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:
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?
In OSGi, a single component is called a bundle. Logically, a bundle is a piece of functionality that has an independent lifecycle – which means it can be started, stopped and removed independently. Technically, a bundle is just a jar file with a MANIFEST. MF file containing some OSGi-specific headers.
To run your bundles, right click and choose Run as ->OSGi Framework (or debug as). You can tweak which bundles are included in the runtime configuration, and what arguments are used. You may for example want to add -console . You can also create an application for export, which will give you a config.
OSGi facilitates creating and managing modular Java components (called bundles) that can be deployed in a container. As a developer, you use the OSGi specification and tools to create one or more bundles. OSGi defines the lifecycle for these bundles. It also hosts them and supports their interactions in a container.
How does OSGi work? OSGi is a set of specifications that define a dynamic component system for Java. These specifications allow for a development model in which an application is composed of several components, and then packed into bundles. These components communicate locally and through the network via services.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With