相关疑难解决方法(0)

如何在动态编译源文件时为JavaCompiler提供接口?

我正在尝试在运行时编译和加载一个类,而不知道该类的包.我知道该类应该遵守一个接口,以及源的位置(以及类名).我正在尝试以下方法:

/* 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接口.

java runtime compilation dynamic classloader

8
推荐指数
1
解决办法
5570
查看次数

使用自定义类加载器中的javax.tools.ToolProvider?

似乎无法使用javax.tools.ToolProviderAnt或Webstart所需的自定义类加载器:http://bugs.sun.com/view_bug.do?video_id = 6548428

javax.tools.ToolProvider.getSystemJavaCompiler()加载javax.tools.JavaCompiler到URLClassLoader中,其父级是系统类加载器.API似乎不允许用户指定父类加载器.

如何使用javax.tools.JavaCompiler自定义类加载器?

例如:

  • Ant加载 MyParserTask
  • MyParserTask 解析Java源代码
  • MyParserTaskAntClassLoader该委托加载到系统类加载器
  • javax.tools.JavaCompilerURLClassLoader代理加载到系统类加载器

稍后,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)
  • 看到这两个类如何驻留在不同的类加载器上,似乎没有一种方法可以MyParserTaskJavacTaskClassCastException出错的情况下进行交互.

有任何想法吗?

java compiler-construction casting classloader

6
推荐指数
1
解决办法
2681
查看次数

在OSGi Bundle中使用JavaCompiler

我正在重构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版本的应用程序中,编译器需要访问与上述代码在同一个包中的类,以及其他包中的类.如何让编译器知道这些类?

我想到了两种可能的解决方案:

  1. 为编译器提供包含上述代码的bundle使用的类加载器,因为它知道所有必需的类.然而,这似乎不是我在这里这里读到的可行解决方案.
  2. 使用已安装的软件包的物理位置构建类路径.我看过了,org.osgi.framework.Bundle.getLocation()但我不确定这是否是一个可靠的解决方案.我得到的路径(至少在Eclipse中部署时)是相对的,我不确定它们是否可以安全地在所有平台和情况下使用.

上面的选项2似乎可能吗?有更好的解决方案吗?

java osgi classpath classloader

6
推荐指数
1
解决办法
874
查看次数