java - 如何将 JDK6 ToolProvider 和 JavaCompiler 与上下文类加载器一起使用?

标签 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););

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();
   }

}

堆栈跟踪表明它在注释处理期间只被调用一次。我验证了要编译的源文件中引用的类不在系统类路径中,但可以从上下文类加载器中获得。

最佳答案

如果您知道上下文类加载器已知的文件的类路径,您可以将它们传递给编译器:

    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();

此示例假设您使用的是 URLClassloader(它允许您检索类路径),但如果您愿意,也可以插入自己的类路径。

关于java - 如何将 JDK6 ToolProvider 和 JavaCompiler 与上下文类加载器一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/274474/

相关文章:

java - 在 Java 中打开/关闭单个像素或更改颜色

java - 如何使用 Intellij 解决 Java 中的 fileNotFoundException

java - JUnit 错误 : Class names, 'org.junit.runner.JUnitCore' ,只有在显式请求注释处理时才被接受

java - 为什么Java编译器允许通过空对象访问静态变量?

java - Java 中的类加载与对象创建

java - 垃圾收集如何识别孤立对象?

java - 将自定义 ObjectFactory 与 JAXB 一起使用 : is there an established "go to" pattern?

Java在命令行中编译代码时出现问题: Package does not exist. ..但确实如此

android - 包裹/序列化类加载器

java - 在运行时加载 jar