I would like to create a command-line tool that starts an OSGi framework, in order to reuse code that is relying on OSGi.
In the answer accessing command-line arguments from OSGi bundle, I got how I can read the command line arguments:
@Component
public class Example {
String[] args;
@Activate
void activate() {
System.out.println("Hello World");
System.out.println(args.length + " args:");
for (String s : args) {
System.out.println(" - " + s);
}
}
@Reference(target = "(launcher.arguments=*)")
void args(Object object, Map<String, Object> map) {
if (map.containsKey("launcher.arguments")) {
args = (String[]) map.get("launcher.arguments");
} else {
args = new String[] {};
}
}
}
But now when I run the assembled jar (bnd-export-maven-plugin
) like this:
java -jar <path-to>/application.jar lorem ipsum
I get the expected output, but the application does not terminate.
After having read 4.2.6 Stopping a Framework, I was thinking that I need to call stop()
on the system bundle. I have tried to change my code to:
@Activate
void activate(BundleContext bundleContext) {
System.out.println("Hello World");
System.out.println(args.length + " args:");
for (String s : args) {
System.out.println(" - " + s);
}
try {
bundleContext.getBundle().stop();
} catch (BundleException e) {
e.printStackTrace();
}
}
But it does not seems to work like this.
If you want the system bundle to stop you must do (notice the 0):
bundleContext.getBundle(0).stop();
To do this hyper correctly, you should do this in another thread.
@Component
public class ServiceComponent {
@Activate
void activate(BundleContext c) {
CompletableFuture.runAsync( ()-> {
try {
c.getBundle(0).stop();
} catch (BundleException e) {
e.printStackTrace();
}
} );
}
}
This is, of course, a suicide component ...