在OSGi捆绑包中使用JavaCompiler [英] Using JavaCompiler in an OSGi Bundle

查看:101
本文介绍了在OSGi捆绑包中使用JavaCompiler的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在重构Java应用程序以使用OSGi.该应用程序的一项功能是使用javax.tools.JavaCompiler即时进行Java编译.在原始应用程序中,此过程通过向编译器提供现有的类路径来完成,就像这样.

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

但是,由于类路径不再包含所需的路径,因此这在OSGi捆绑软件中将不起作用.在应用程序的重构OSGi版本中,编译器需要访问与上述代码位于同一包中的类以及其他包中的类.如何使编译器知道这些类?

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:

  1. 为编译器提供包含以上代码的捆绑软件所使用的类加载器,因为它知道所有必需的类.但是,从我阅读的此处此处.
  2. 使用已安装捆绑软件的物理位置构建类路径.我已经看过org.osgi.framework.Bundle.getLocation()了,但是我不确定这是否是一个可靠的解决方案.我获得的路径(至少在Eclipse中进行部署时)是相对的,我不确定它们是否可以在所有平台和情况下安全使用.
  1. 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.
  2. 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?

推荐答案

我在它不是选项1或2,它创建了一个自定义JavaFileManager,它可以查看所有包并检索其资源.

It is not option 1 or 2, it creates a custom JavaFileManager which looks through all bundles and retrieves their resources.

注意事项:

  • 它使用JSR 199编译器API,但仅在OpenJDK/Sun编译器上工作,Eclipse JDT编译器在这方面似乎已损坏.
  • 我仅在Equinox上进行过测试,我没有使用任何特定于Equinox的代码,因此它应该可以在其他实现上使用.
  • 它没有经过优化,因此可能很慢和/或内存不足.
  • 它确实注册了包侦听器,因此当提供某些包的包解析或未解析时,它将刷新其类缓存
  • 我认为拆分包的确定性不是很好.
  • 它使用OSGi 4.3中引入的BundleWiring API,因此不适用于OSGi的旧版OSGi实现(例如,Karaf 2.x)

我应该提到技术发明,他的榜样极大地帮助了我.

I should mention Technology Excruciation, his example helped me along tremendously.

这篇关于在OSGi捆绑包中使用JavaCompiler的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆