我正在尝试在运行时编译和加载一个类,而不知道该类的包.我知道该类应该遵守一个接口,以及源的位置(以及类名).我正在尝试以下方法:
/* Compiling source */
File root = new File("scripts");
File sourceFile = new File(root, "Test.java");
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null, null, null, sourceFile.getPath());
Run Code Online (Sandbox Code Playgroud)
Test.java文件看起来像什么
import foo.Itest;
public class Test implements Itest{
...
}
Run Code Online (Sandbox Code Playgroud)
我cannot find symbol symbol : class Itest
从编译器得到一个错误.如何为编译器提供接口(已经加载)以避免此错误?
[EDIT - RESOLVED]:错误来自接口的事实ITest
,而源是指Itest
接口.
似乎无法使用javax.tools.ToolProvider
Ant或Webstart所需的自定义类加载器:http://bugs.sun.com/view_bug.do?video_id = 6548428
javax.tools.ToolProvider.getSystemJavaCompiler()
加载javax.tools.JavaCompiler
到URLClassLoader中,其父级是系统类加载器.API似乎不允许用户指定父类加载器.
如何使用javax.tools.JavaCompiler
自定义类加载器?
例如:
MyParserTask
MyParserTask
解析Java源代码MyParserTask
由AntClassLoader
该委托加载到系统类加载器javax.tools.JavaCompiler
由URLClassLoader
代理加载到系统类加载器稍后,MyParserTask
调用:
javax.tools.CompilationTask task = compiler.getTask(...);
com.sun.source.util.JavacTask javacTask = (com.sun.source.util.JavacTask) task;
javacTask.parse().next().accept(visitor, unused); // parsing happens here
Run Code Online (Sandbox Code Playgroud)
MyParserTask
在JavacTask
不ClassCastException
出错的情况下进行交互.有任何想法吗?
我正在重构Java应用程序以使用OSGi.该应用程序的一个功能是使用即时Java编译javax.tools.JavaCompiler
.在原始应用程序中,此过程通过向编译器提供现有类路径来完成,就像这样.
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
String[] options = {"-classpath", System.getProperty("java.class.path")};
DiagnosticListener<JavaFileObject> listener = new DiagnosticListener<JavaFileObject>() {...};
StandardJavaFileManager fileManager = compiler.getStandardFileManager(listener, null, null);
Iterable<? extends JavaFileObject> fileObjects = fileManager.getFileObjects(sourceFile);
CompilationTask task = compiler.getTask(null, fileManager, listener, Arrays.asList(options), null, fileObjects);
task.call();
Run Code Online (Sandbox Code Playgroud)
但是,这在OSGi包中不起作用,因为类路径不再包含所需的路径.在重构的OSGi版本的应用程序中,编译器需要访问与上述代码在同一个包中的类,以及其他包中的类.如何让编译器知道这些类?
我想到了两种可能的解决方案:
org.osgi.framework.Bundle.getLocation()
但我不确定这是否是一个可靠的解决方案.我得到的路径(至少在Eclipse中部署时)是相对的,我不确定它们是否可以安全地在所有平台和情况下使用.上面的选项2似乎可能吗?有更好的解决方案吗?