如何将JDK6 ToolProvider和JavaCompiler与上下文类加载器一起使
发布时间:2020-12-14 06:01:52 所属栏目:Java 来源:网络整理
导读:我的用例是使用JDK 6中提供的ToolProvider和 JavaCompiler类从java程序编译生成的源文件.源文件包含对上下文类加载器中的类的引用(它在J2EE容器中运行),但不包含在系统类加载器中.我的理解是,默认情况下,ToolProvider将使用系统类加载器创建JavaCompiler实例
我的用例是使用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(); } } 堆栈跟踪表明它仅在注释处理期间调用一次.我验证了要编译的源文件中引用的类不在系统类路径中,但可以从上下文类加载器中获得. 解决方法
如果您知道contextclassloader已知的文件的类路径,则可以将它们传递给编译器:
StandardJavaFileManager fileManager = compiler.getStandardFileManager(this /* diagnosticlistener */,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,compilationUnits); task.call(); 此示例假设您正在使用URLClassloader(允许您检索类路径),但如果您愿意,可以插入自己的类路径. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |