Jdk6中的源代码编译功能

JDK6中的源代码编译功能,网上给的示例一般都无法运行,会抛出ClassNotFoundException。
经过改良,主要原因是字节码输出的文件不对。现修改为输出到内存中。

/**
* 字符串变为Class
*
* @author wuyuhou
*
*/
public class StringToClass {

public static void main(String[] args) throws Exception {
Class clazz = loadClass("com.test.CalculatorTest",
"package com.test;"
+ "public class CalculatorTest {"
+ " public int multiply(int multiplicand, int multiplier) {"
+ " System.out.print(multiplicand + \" * \");"
+ " System.out.print(multiplier + \" = \");"
+ " return multiplicand * multiplier;"
+ " }"
+ "}", StringToClass.class.getClassLoader());
Object instance = clazz.newInstance();
Method m = clazz.getMethod("multiply", new Class[] {
int.class, int.class
});
Object[] o = new Object[] {
3, 2
};
System.out.println(m.invoke(instance, o));
}

public static Class loadClass(String className, String javaSource, ClassLoader loader) throws ClassNotFoundException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
//源码Java对象
JavaFileObject sourceFileObject = new SimpleJavaFileObjectWrapper(className, Kind.SOURCE, javaSource, null);

//输出到内存中
ByteArrayOutputStream byteArrayOutput = new ByteArrayOutputStream();
//Class输出Java对象
JavaFileObject outputFileObject = new SimpleJavaFileObjectWrapper(className, Kind.CLASS, null, byteArrayOutput);

Iterable<JavaFileObject> files = Arrays.asList(sourceFileObject);
StandardJavaFileManager fileManager = new StandardJavaFileManagerWrapper(compiler.getStandardFileManager(null, null, null), outputFileObject);
JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, null, null, files);
task.call();
//字节码数组
byte[] classBytes = byteArrayOutput.toByteArray();
return new SimpleClassLoader(loader).loadClass(classBytes);
}

private static class SimpleClassLoader extends ClassLoader {
public SimpleClassLoader(ClassLoader parent) {
super(parent);
}
public Class<?> loadClass(byte[] classBytes) throws ClassNotFoundException {
return defineClass(null, classBytes, 0, classBytes.length);
}
}

private static class SimpleJavaFileObjectWrapper extends SimpleJavaFileObject {

private String javaSource = null;
private ByteArrayOutputStream byteArrayOutput = null;
public SimpleJavaFileObjectWrapper(String className, Kind kind, String javaSource, ByteArrayOutputStream byteArrayOutput) {
super(URI.create("string:///" + className.replace('.', '/') + kind.extension), kind);
this.javaSource = javaSource;
this.byteArrayOutput = byteArrayOutput;
}

@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
return javaSource;
}

@Override
public OutputStream openOutputStream() throws IOException {
return byteArrayOutput;
}
}

private static class StandardJavaFileManagerWrapper implements StandardJavaFileManager {
private StandardJavaFileManager defaultWrapper = null;

private JavaFileObject outputFileObject = null;

public StandardJavaFileManagerWrapper(StandardJavaFileManager defaultWrapper, JavaFileObject outputFileObject) {
this.defaultWrapper = defaultWrapper;
this.outputFileObject = outputFileObject;
}

public ClassLoader getClassLoader(Location location) {
return defaultWrapper.getClassLoader(location);
}

public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse) throws IOException {
return defaultWrapper.list(location, packageName, kinds, recurse);
}

public String inferBinaryName(Location location, JavaFileObject file) {
return defaultWrapper.inferBinaryName(location, file);
}

public boolean handleOption(String current, Iterator<String> remaining) {
return defaultWrapper.handleOption(current, remaining);
}

public boolean hasLocation(Location location) {
return defaultWrapper.hasLocation(location);
}

public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException {
return defaultWrapper.getJavaFileForInput(location, className, kind);
}

// 输出重新定位,否则就会报出ClassNotFoundException
public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException {
if (outputFileObject != null) {
return outputFileObject;
}
return defaultWrapper.getJavaFileForOutput(location, className, kind, sibling);
}

public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException {
return defaultWrapper.getFileForInput(location, packageName, relativeName);
}

public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling) throws IOException {
return defaultWrapper.getFileForOutput(location, packageName, relativeName, sibling);
}

public void flush() throws IOException {
defaultWrapper.flush();
}

public void close() throws IOException {
defaultWrapper.close();
}

public int isSupportedOption(String option) {
return defaultWrapper.isSupportedOption(option);
}

public boolean isSameFile(FileObject a, FileObject b) {
return defaultWrapper.isSameFile(a, b);
}

public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(Iterable<? extends File> files) {
return defaultWrapper.getJavaFileObjectsFromFiles(files);
}

public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) {
return defaultWrapper.getJavaFileObjects(files);
}

public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) {
return defaultWrapper.getJavaFileObjectsFromStrings(names);
}

public Iterable<? extends JavaFileObject> getJavaFileObjects(String... names) {
return defaultWrapper.getJavaFileObjects(names);
}

public void setLocation(Location location, Iterable<? extends File> path) throws IOException {
defaultWrapper.setLocation(location, path);
}

public Iterable<? extends File> getLocation(Location location) {
return defaultWrapper.getLocation(location);
}
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值