Can Spring Boot be used with OSGi? If not, any plans to have an OSGi Spring Boot (Apache Felix or Eclipse Equinox)? In my opinion, cloud applications must be highly modular and updatable like OSGi offers.
No . Once you import spring boot dependancies , it has to be a spring project.
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.
Build a service-oriented application using Spring and OSGi OSGi, also known as the Dynamic Module System for Java, specifies a modular approach to Java application development, as well as a set of standardized methods for managing dependencies between modules.
When you have a large number of different web apps, it can make sense to let the knowledge on that part only in the production team. In that case, you would not use Spring boot. On the other end, if the hosting is externalized, Spring boot allows to give a full package.
Yes, it's possible to run Spring Boot
apps in OSGI container.
First of all, you'll have to switch from Spring Boot jar
packaging to OSGI bundle
.
If you're using Maven
you can use org.apache.felix:maven-bundle-plugin
for doing that. As Spring Boot
dependency jars are not valid OSGI
bundles, we should either make them valid bundles with bnd
tool or we can embed them into the bundle itself. That can be done with maven-bundle-plugin
configuration, particularly with <Embed-Dependency>
.
However, we need to start the bundle with Spring Boot
app somehow. The idea is to start Spring Boot in BundleActivator
:
@Import(AppConfig.class) @SpringBootConfiguration @EnableAutoConfiguration public class SpringBootBundleActivator implements BundleActivator { ConfigurableApplicationContext appContext; @Override public void start(BundleContext bundleContext) { Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); appContext = SpringApplication.run(SpringBootBundleActivator.class); } @Override public void stop(BundleContext bundleContext) { SpringApplication.exit(appContext, () -> 0); } }
You should also set context classloader to an OSGI classloader loading the bundle by Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
. That is required because Spring
uses context classloader.
You can see this in action in my demo repo: https://github.com/StasKolodyuk/osgi-spring-boot-demo
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