在 OSGi 包中使用 JavaCompiler
我正在重构 Java 应用程序以使用 OSGi。该应用程序的一项功能是使用 javax.tools.JavaCompiler 进行即时 Java 编译。在最初的应用程序中,这个过程是通过向编译器提供现有的类路径来工作的,就像这样。
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();
但是,这在 OSGi 包中不起作用,因为类路径不再包含所需的路径。在应用程序的重构 OSGi 版本中,编译器需要访问与上述代码位于同一包中的类,以及来自其他包的类。如何让编译器识别这些类?
我想到了两种可能的解决方案:
- 为编译器提供包含上述代码的包所使用的类加载器,因为它知道所有必需的类。然而,从我读过的内容来看,这似乎不是一个可行的解决方案 这里和此处。
- 使用已安装包的物理位置构建类路径。我看过 org.osgi.framework.Bundle.getLocation() ,但我不确定这是否是一个可靠的解决方案。我返回的路径(至少在 Eclipse 中部署时)是相对的,我不确定它们是否可以在所有平台和情况下安全使用。
上述选项二似乎可行吗?有更好的解决方案吗?
I'm in the process of refactoring a Java application to use OSGi. One feature of the application is on-the-fly Java compilation using javax.tools.JavaCompiler
. In the original application this process worked by feeding the compiler the existing classpath, like so.
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();
However, this won't work in an OSGi bundle since the classpath no longer contains the needed paths. In the refactored OSGi version of the application, the compiler needs access to classes that are within the same bundle as the above code, as well as classes from other bundles. How do I make the compiler aware of these classes?
I've thought of two possible solutions:
- Give the compiler the classloader used by the bundle containing the above code since it is aware of all the necessary classes. However, this doesn't seem like a viable solution from what I've read here and here.
- Build the classpath using the physical locations of the installed bundles. I've looked at
org.osgi.framework.Bundle.getLocation()
but I'm not sure if this would be a reliable solution. The paths I get back (at least when deploying within Eclipse) are relative and I'm not sure if they'd be safe to use across all platforms and situations.
Does option two above seem possible? Is there a better solution?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我在 GitHub 上创建了一个工作示例。
它不是选项 1 或 2,它创建一个自定义 JavaFileManager,它会查看所有包并检索它们的资源。
需要考虑的事项:
我应该提到 技术折磨,他的例子帮助了我非常地。
I've created a working example on GitHub.
It is not option 1 or 2, it creates a custom JavaFileManager which looks through all bundles and retrieves their resources.
Things to take into consideration:
I should mention Technology Excruciation, his example helped me along tremendously.