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?
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.