Phi*_*hil 6 java javac classloader java-compiler-api
我的用例是使用JDK 6中提供的ToolProvider和JavaCompiler类从java程序编译生成的源文件.源文件包含对上下文类加载器中的类的引用(它在J2EE容器中运行),但不包含在系统类加载器中.我的理解是,默认情况下,ToolProvider将使用系统类加载器创建JavaCompiler实例.
有没有办法为JavaCompiler指定一个类加载器?
我尝试了这种方法,从IBM DeveloperWorks上的某些东西进行了修改:
FileManagerImpl fm =
new FileManagerImpl(compiler.getStandardFileManager(null, null, null););
Run Code Online (Sandbox Code Playgroud)
将FileManagerImpl定义为:
static final class FileManagerImpl
extends ForwardingJavaFileManager<JavaFileManager> {
public FileManagerImpl(JavaFileManager fileManager) {
super(fileManager);
}
@Override
public ClassLoader getClassLoader(JavaFileManager.Location location) {
new Exception().printStackTrace();
return Thread.currentThread().getContextClassLoader();
}
}
Run Code Online (Sandbox Code Playgroud)
堆栈跟踪表明它仅在注释处理期间调用一次.我验证了要编译的源文件中引用的类不在系统类路径中,但可以从上下文类加载器中获得.
小智 8
如果您知道contextclassloader已知的文件的类路径,则可以将它们传递给编译器:
StandardJavaFileManager fileManager = compiler.getStandardFileManager(this /* diagnosticlistener */, null, null);
// get compilationunits from somewhere, for instance via fileManager.getJavaFileObjectsFromFiles(List<file> files)
List<String> options = new ArrayList<String>();
options.add("-classpath");
StringBuilder sb = new StringBuilder();
URLClassLoader urlClassLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
for (URL url : urlClassLoader.getURLs())
sb.append(url.getFile()).append(File.pathSeparator);
options.add(sb.toString());
CompilationTask task = compiler.getTask(null, fileManager, this /* diagnosticlistener */, options, null, compilationUnits);
task.call();
Run Code Online (Sandbox Code Playgroud)
此示例假设您正在使用URLClassloader(允许您检索类路径),但如果您愿意,可以插入自己的类路径.
归档时间: |
|
查看次数: |
6288 次 |
最近记录: |