Edit: creating a REST API using jersey has been made simpler, see Simplified REST APIs from karaf using Jersey for details.
The sample application https://github.com/steinarb/jersey-demo demonstrates how to use Jersey to provide a REST API from a Declarative Services (DS) component registering with the Pax Web Whiteboard Extender in apache karaf.
The way Jersey works is that it initially scans a package in the classpath for classes with JAX-RS annotations (e.g. @Path, @GET, @POST), and matches @Path annotations to possible endpoints in the REST API. When Jersey receives a REST call to a endpoint that matches a resource, Jersey will instanciate the appropriate resource class, call a method on the instanciated resource and then release the resource to Java garbage collection.
To be able to do something useful in these resource objects we use HK2 to dependency inject OSGi services.
To be able to dependency inject OSGi services into Jersey resources the following is done:
- Create a whiteboard DS component exposing a Servlet service from Jersey ServletContainer, configuring the package to scan for API resources:
@Component( service=Servlet.class, property={"alias=/jerseyinkaraf/api", HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX+ServerProperties.PROVIDER_PACKAGES+"=no.priv.bang.demos.jerseyinkaraf.webapi.resources" } ) public class CounterServiceServlet extends ServletContainer { ... }
- Make the DS component of ServletContainer depend on OSGi services Counter and LogService
public class CounterServiceServlet extends ServletContainer { ... @Reference public void setCounter(Counter counter) { this.counter = counter; } @Reference public void setLogservice(LogService logservice) { this.logservice.setLogService(logservice); } ... }
- Override the ServletContainer.init(WebConfig) method, and:
- Call super.init(WebConfig) to make sure that a ServletConfig containing the information set up by the http whiteboard is created (contains the servletcontext, the servlet name and the package to scan for Jersey resources)
super.init(webConfig);
- Copy the ResourceConfig of the ServletContainer (because that ServletConfig is immutable after the setup, and calling ServletConfig.register() will cause an IllegalOperationException)
ResourceConfig copyOfExistingConfig = new ResourceConfig(getConfiguration());
- On the ServletConfig copy, register an anonymous inner inheriting AbstractBinder that in its configure() method registers the OSGi services injected into the ServletContainer as JSR330 injections in the Jersey resources
copyOfExistingConfig.register(new AbstractBinder() { @Override protected void configure() { bind(logservice).to(LogService.class); bind(counter).to(Counter.class); } });
- Call ServletContainer.reload(ResourceConfig) with the ResourceConfig copy as the argument
reload(copyOfExistingConfig);
Note: The copyOfExistingConfig object at this point contains both the initial configuration created by the ServletContainer itself, and the two added OSGi services for dependency injection.
- Call super.init(WebConfig) to make sure that a ServletConfig containing the information set up by the http whiteboard is created (contains the servletcontext, the servlet name and the package to scan for Jersey resources)
- In the resources use JSR330 injections of the registered services
@Path("/counter") @Produces(MediaType.APPLICATION_JSON) public class CounterResource { @Inject Counter counter; @GET public Count currentValue() { return counter.currentValue(); } @POST public Count increment() { return counter.increment(); } }
To try out the application:
- Clone this project and build it:
git clone https://github.com/steinarb/jersey-demo.git cd jersey-demo mvn clean install
- Install apache karaf and start it according to the karaf quick start guide (alternatively, see Develop OSGi applications using karaf)
- At the karaf command line give the following commands
feature:repo-add mvn:no.priv.bang.demos.jerseyinkaraf/jerseyinkaraf/LATEST/xml/features feature:install jerseyinkaraf.webapi feature:install jerseyinkaraf.webgui
- Open http://localhost:8181/jerseyinkaraf in a web browser and click on the button to increment the counter value
The demo consists of the following maven project and modules:
- jerseyinkaraf The top project which in addition to containing common configuration, and the list of modules, also creates a karaf feature repository containing the features of all bundles created in the modules, and attaches the karaf feature repository to the maven artifact
- jerseyinkaraf.servicedef which is an OSGi bundle containing the interfaces and bean defining the OSGi service for doing the counting
- jerseinkaraf.services which is an OSGi bundle containing a DS component implementing the services
- jerseyinkaraf.webapi which is an OSGi bundle containing a DS component that defines a REST API that plugs into the Web Whiteboard Extender and exposes the OSGi services
- jerseyinkaraf.webgui which is an OSGi bundle containing a DS component that exposes an HTML and JavaScript application that plugs into the Web Whiteboard Extender
If your plugin gets startup problems and you finds messages like this in karaf.log, then the problem is receiving javax.inject from multiple bundles:
2019-03-09T12:33:14,425 | WARN | features-1-thread-1 | authservice | 1127 - org.eclipse.jetty.util - 9.3.24.v20180605 | unavailable
java.lang.IllegalStateException: InjectionManagerFactory not found.
at org.glassfish.jersey.internal.inject.Injections.lambda$lookupInjectionManagerFactory$0(Injections.java:98) ~[1147:org.glassfish.jersey.core.jersey-common:2.27.0]
at java.util.Optional.orElseThrow(Optional.java:290) ~[?:?]
at org.glassfish.jersey.internal.inject.Injections.lookupInjectionManagerFactory(Injections.java:98) ~[1147:org.glassfish.jersey.core.jersey-common:2.27.0]
at org.glassfish.jersey.internal.inject.Injections.createInjectionManager(Injections.java:93) ~[1147:org.glassfish.jersey.core.jersey-common:2.27.0]
at org.glassfish.jersey.server.ApplicationHandler.(ApplicationHandler.java:282) ~[1148:org.glassfish.jersey.core.jersey-server:2.27.0]
at org.glassfish.jersey.servlet.WebComponent.(WebComponent.java:335) ~[1145:org.glassfish.jersey.containers.jersey-container-servlet-core:2.27.0]
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:178) ~[1145:org.glassfish.jersey.containers.jersey-container-servlet-core:2.27.0]
at no.priv.bang.authservice.web.security.AuthserviceServlet.init(AuthserviceServlet.java:69) ~[1093:no.priv.bang.authservice.web.security:1.0.0.SNAPSHOT]
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:370) ~[1145:org.glassfish.jersey.containers.jersey-container-servlet-core:2.27.0]
at javax.servlet.GenericServlet.init(GenericServlet.java:244) ~[1086:javax.servlet-api:3.1.0]
at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:643) ~[1125:org.eclipse.jetty.servlet:9.3.24.v20180605]
at org.eclipse.jetty.servlet.ServletHolder.initialize(ServletHolder.java:422) ~[1125:org.eclipse.jetty.servlet:9.3.24.v20180605]
at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:892) ~[1125:org.eclipse.jetty.servlet:9.3.24.v20180605]
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:349) ~[1125:org.eclipse.jetty.servlet:9.3.24.v20180605]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.startContext(HttpServiceContext.java:444) ~[1159:org.ops4j.pax.web.pax-web-jetty:6.0.11]
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:778) ~[1124:org.eclipse.jetty.server:9.3.24.v20180605]
at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:262) ~[1125:org.eclipse.jetty.servlet:9.3.24.v20180605]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doStart(HttpServiceContext.java:270) ~[1159:org.ops4j.pax.web.pax-web-jetty:6.0.11]
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) ~[1127:org.eclipse.jetty.util:9.3.24.v20180605]
at org.ops4j.pax.web.service.jetty.internal.JettyServerImpl$1.start(JettyServerImpl.java:328) ~[1159:org.ops4j.pax.web.pax-web-jetty:6.0.11]
at org.ops4j.pax.web.service.internal.HttpServiceStarted.registerFilter(HttpServiceStarted.java:626) ~[?:?]
at org.ops4j.pax.web.service.internal.HttpServiceStarted.registerFilter(HttpServiceStarted.java:598) ~[?:?]
at org.ops4j.pax.web.service.internal.HttpServiceProxy.registerFilter(HttpServiceProxy.java:212) ~[?:?]
at org.ops4j.pax.web.extender.whiteboard.internal.element.FilterWebElement.register(FilterWebElement.java:61) ~[?:?]
at org.ops4j.pax.web.extender.whiteboard.internal.WebApplication.registerWebElement(WebApplication.java:392) ~[?:?]
at org.ops4j.pax.web.extender.whiteboard.internal.WebApplication.addWebElement(WebApplication.java:199) ~[?:?]
at org.ops4j.pax.web.extender.whiteboard.internal.tracker.AbstractTracker.addingService(AbstractTracker.java:193) ~[?:?]
at org.ops4j.pax.web.extender.whiteboard.internal.tracker.AbstractTracker.addingService(AbstractTracker.java:46) ~[?:?]
at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:941) ~[?:?]
at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:870) ~[?:?]
at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256) ~[?:?]
at org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:229) ~[?:?]
at org.osgi.util.tracker.ServiceTracker$Tracked.serviceChanged(ServiceTracker.java:901) ~[?:?]
at org.apache.felix.framework.EventDispatcher.invokeServiceListenerCallback(EventDispatcher.java:990) ~[?:?]
at org.apache.felix.framework.EventDispatcher.fireEventImmediately(EventDispatcher.java:838) ~[?:?]
at org.apache.felix.framework.EventDispatcher.fireServiceEvent(EventDispatcher.java:545) ~[?:?]
at org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:4595) ~[?:?]
at org.apache.felix.framework.Felix.registerService(Felix.java:3587) ~[?:?]
at org.apache.felix.framework.BundleContextImpl.registerService(BundleContextImpl.java:348) ~[?:?]
at org.apache.felix.scr.impl.manager.AbstractComponentManager$3.register(AbstractComponentManager.java:903) ~[?:?]
at org.apache.felix.scr.impl.manager.AbstractComponentManager$3.register(AbstractComponentManager.java:890) ~[?:?]
at org.apache.felix.scr.impl.manager.RegistrationManager.changeRegistration(RegistrationManager.java:132) ~[?:?]
at org.apache.felix.scr.impl.manager.AbstractComponentManager.registerService(AbstractComponentManager.java:957) ~[?:?]
at org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:741) ~[?:?]
at org.apache.felix.scr.impl.manager.AbstractComponentManager.enableInternal(AbstractComponentManager.java:675) ~[?:?]
at org.apache.felix.scr.impl.manager.AbstractComponentManager.enable(AbstractComponentManager.java:430) ~[?:?]
at org.apache.felix.scr.impl.manager.ConfigurableComponentHolder.enableComponents(ConfigurableComponentHolder.java:657) ~[?:?]
at org.apache.felix.scr.impl.BundleComponentActivator.initialEnable(BundleComponentActivator.java:341) ~[?:?]
at org.apache.felix.scr.impl.Activator.loadComponents(Activator.java:387) ~[?:?]
at org.apache.felix.scr.impl.Activator.access$200(Activator.java:52) ~[?:?]
at org.apache.felix.scr.impl.Activator$ScrExtension.start(Activator.java:262) ~[?:?]
at org.apache.felix.scr.impl.AbstractExtender.createExtension(AbstractExtender.java:196) ~[?:?]
at org.apache.felix.scr.impl.AbstractExtender.modifiedBundle(AbstractExtender.java:169) ~[?:?]
at org.apache.felix.scr.impl.AbstractExtender.modifiedBundle(AbstractExtender.java:49) ~[?:?]
at org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:482) ~[?:?]
at org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:415) ~[?:?]
at org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:232) ~[?:?]
at org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:444) ~[?:?]
at org.apache.felix.framework.EventDispatcher.invokeBundleListenerCallback(EventDispatcher.java:915) ~[?:?]
at org.apache.felix.framework.EventDispatcher.fireEventImmediately(EventDispatcher.java:834) ~[?:?]
at org.apache.felix.framework.EventDispatcher.fireBundleEvent(EventDispatcher.java:516) ~[?:?]
at org.apache.felix.framework.Felix.fireBundleEvent(Felix.java:4579) ~[?:?]
at org.apache.felix.framework.Felix.startBundle(Felix.java:2174) ~[?:?]
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:998) ~[?:?]
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:984) ~[?:?]
at org.apache.karaf.features.internal.service.FeaturesServiceImpl.startBundle(FeaturesServiceImpl.java:1361) ~[?:?]
at org.apache.karaf.features.internal.service.Deployer.deploy(Deployer.java:894) ~[?:?]
at org.apache.karaf.features.internal.service.FeaturesServiceImpl.doProvision(FeaturesServiceImpl.java:1248) ~[?:?]
at org.apache.karaf.features.internal.service.FeaturesServiceImpl.lambda$doProvisionInThread$1(FeaturesServiceImpl.java:1147) ~[?:?]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:?]
at java.lang.Thread.run(Thread.java:748) [?:?]
2019-03-09T12:33:14,441 | ERROR | features-1-thread-1 | HttpServiceStarted | - - | Could not start the servlet context for context path [authservice]
javax.servlet.ServletException: authservice@e8f8bc0d==no.priv.bang.authservice.web.security.AuthserviceServlet,jsp=null,order=-1,inst=false
at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:664) ~[?:?]
at org.eclipse.jetty.servlet.ServletHolder.initialize(ServletHolder.java:422) ~[?:?]
at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:892) ~[?:?]
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:349) ~[?:?]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.startContext(HttpServiceContext.java:444) ~[?:?]
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:778) ~[?:?]
at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:262) ~[?:?]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doStart(HttpServiceContext.java:270) ~[?:?]
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) ~[?:?]
at org.ops4j.pax.web.service.jetty.internal.JettyServerImpl$1.start(JettyServerImpl.java:328) ~[?:?]
at org.ops4j.pax.web.service.internal.HttpServiceStarted.registerFilter(HttpServiceStarted.java:626) ~[?:?]
at org.ops4j.pax.web.service.internal.HttpServiceStarted.registerFilter(HttpServiceStarted.java:598) ~[?:?]
at org.ops4j.pax.web.service.internal.HttpServiceProxy.registerFilter(HttpServiceProxy.java:212) ~[?:?]
at org.ops4j.pax.web.extender.whiteboard.internal.element.FilterWebElement.register(FilterWebElement.java:61) ~[?:?]
at org.ops4j.pax.web.extender.whiteboard.internal.WebApplication.registerWebElement(WebApplication.java:392) ~[?:?]
at org.ops4j.pax.web.extender.whiteboard.internal.WebApplication.addWebElement(WebApplication.java:199) ~[?:?]
at org.ops4j.pax.web.extender.whiteboard.internal.tracker.AbstractTracker.addingService(AbstractTracker.java:193) ~[?:?]
at org.ops4j.pax.web.extender.whiteboard.internal.tracker.AbstractTracker.addingService(AbstractTracker.java:46) ~[?:?]
at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:941) ~[?:?]
at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:870) ~[?:?]
at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256) ~[?:?]
at org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:229) ~[?:?]
at org.osgi.util.tracker.ServiceTracker$Tracked.serviceChanged(ServiceTracker.java:901) ~[?:?]
at org.apache.felix.framework.EventDispatcher.invokeServiceListenerCallback(EventDispatcher.java:990) ~[?:?]
at org.apache.felix.framework.EventDispatcher.fireEventImmediately(EventDispatcher.java:838) ~[?:?]
at org.apache.felix.framework.EventDispatcher.fireServiceEvent(EventDispatcher.java:545) ~[?:?]
at org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:4595) ~[?:?]
at org.apache.felix.framework.Felix.registerService(Felix.java:3587) ~[?:?]
at org.apache.felix.framework.BundleContextImpl.registerService(BundleContextImpl.java:348) ~[?:?]
at org.apache.felix.scr.impl.manager.AbstractComponentManager$3.register(AbstractComponentManager.java:903) ~[?:?]
at org.apache.felix.scr.impl.manager.AbstractComponentManager$3.register(AbstractComponentManager.java:890) ~[?:?]
at org.apache.felix.scr.impl.manager.RegistrationManager.changeRegistration(RegistrationManager.java:132) ~[?:?]
at org.apache.felix.scr.impl.manager.AbstractComponentManager.registerService(AbstractComponentManager.java:957) ~[?:?]
at org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:741) ~[?:?]
at org.apache.felix.scr.impl.manager.AbstractComponentManager.enableInternal(AbstractComponentManager.java:675) ~[?:?]
at org.apache.felix.scr.impl.manager.AbstractComponentManager.enable(AbstractComponentManager.java:430) ~[?:?]
at org.apache.felix.scr.impl.manager.ConfigurableComponentHolder.enableComponents(ConfigurableComponentHolder.java:657) ~[?:?]
at org.apache.felix.scr.impl.BundleComponentActivator.initialEnable(BundleComponentActivator.java:341) ~[?:?]
at org.apache.felix.scr.impl.Activator.loadComponents(Activator.java:387) ~[?:?]
at org.apache.felix.scr.impl.Activator.access$200(Activator.java:52) ~[?:?]
at org.apache.felix.scr.impl.Activator$ScrExtension.start(Activator.java:262) ~[?:?]
at org.apache.felix.scr.impl.AbstractExtender.createExtension(AbstractExtender.java:196) ~[?:?]
at org.apache.felix.scr.impl.AbstractExtender.modifiedBundle(AbstractExtender.java:169) ~[?:?]
at org.apache.felix.scr.impl.AbstractExtender.modifiedBundle(AbstractExtender.java:49) ~[?:?]
at org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:482) ~[?:?]
at org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:415) ~[?:?]
at org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:232) ~[?:?]
at org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:444) ~[?:?]
at org.apache.felix.framework.EventDispatcher.invokeBundleListenerCallback(EventDispatcher.java:915) ~[?:?]
at org.apache.felix.framework.EventDispatcher.fireEventImmediately(EventDispatcher.java:834) ~[?:?]
at org.apache.felix.framework.EventDispatcher.fireBundleEvent(EventDispatcher.java:516) ~[?:?]
at org.apache.felix.framework.Felix.fireBundleEvent(Felix.java:4579) ~[?:?]
at org.apache.felix.framework.Felix.startBundle(Felix.java:2174) ~[?:?]
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:998) ~[?:?]
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:984) ~[?:?]
at org.apache.karaf.features.internal.service.FeaturesServiceImpl.startBundle(FeaturesServiceImpl.java:1361) ~[?:?]
at org.apache.karaf.features.internal.service.Deployer.deploy(Deployer.java:894) ~[?:?]
at org.apache.karaf.features.internal.service.FeaturesServiceImpl.doProvision(FeaturesServiceImpl.java:1248) ~[?:?]
at org.apache.karaf.features.internal.service.FeaturesServiceImpl.lambda$doProvisionInThread$1(FeaturesServiceImpl.java:1147) ~[?:?]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:?]
at java.lang.Thread.run(Thread.java:748) [?:?]
Caused by: java.lang.IllegalStateException: InjectionManagerFactory not found.
at org.glassfish.jersey.internal.inject.Injections.lambda$lookupInjectionManagerFactory$0(Injections.java:98) ~[?:?]
at java.util.Optional.orElseThrow(Optional.java:290) ~[?:?]
at org.glassfish.jersey.internal.inject.Injections.lookupInjectionManagerFactory(Injections.java:98) ~[?:?]
at org.glassfish.jersey.internal.inject.Injections.createInjectionManager(Injections.java:93) ~[?:?]
at org.glassfish.jersey.server.ApplicationHandler.(ApplicationHandler.java:282) ~[?:?]
at org.glassfish.jersey.servlet.WebComponent.(WebComponent.java:335) ~[?:?]
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:178) ~[?:?]
at no.priv.bang.authservice.web.security.AuthserviceServlet.init(AuthserviceServlet.java:69) ~[?:?]
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:370) ~[?:?]
at javax.servlet.GenericServlet.init(GenericServlet.java:244) ~[?:?]
at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:643) ~[?:?]
... 62 more
2019-03-09T12:33:14,460 | INFO | features-1-thread-1 | FeaturesServiceImpl | 10 - org.apache.karaf.features.core - 4.1.7 | org.glassfish.hk2.locator/2.5.0.b42
2019-03-09T12:33:14,460 | INFO | features-1-thread-1 | FeaturesServiceImpl | 10 - org.apache.karaf.features.core - 4.1.7 | org.glassfish.jersey.inject.jersey-hk2/2.27.0
2019-03-09T12:33:14,461 | INFO | features-1-thread-1 | FeaturesServiceImpl | 10 - org.apache.karaf.features.core - 4.1.7 | org.glassfish.hk2.utils/2.5.0.b42
2019-03-09T12:33:14,461 | INFO | features-1-thread-1 | FeaturesServiceImpl | 10 - org.apache.karaf.features.core - 4.1.7 | org.glassfish.hk2.api/2.5.0.b42
2019-03-09T12:33:14,462 | INFO | features-1-thread-1 | FeaturesServiceImpl | 10 - org.apache.karaf.features.core - 4.1.7 | javax.ws.rs-api/2.1.0
2019-03-09T12:33:14,462 | INFO | features-1-thread-1 | FeaturesServiceImpl | 10 - org.apache.karaf.features.core - 4.1.7 | org.glassfish.jersey.core.jersey-common/2.27.0
2019-03-09T12:33:14,462 | INFO | features-1-thread-1 | FeaturesServiceImpl | 10 - org.apache.karaf.features.core - 4.1.7 | Done.
Run the command
bundle:list
and look for bundles with inject in their name.
The only bundle that should be there, is jersey-inject-hk2:
125 │ Active │ 80 │ 2.28.0 │ jersey-inject-hk2
The way to eliminate undesirable javax.inject runtime dependencies is to look at the transitive maven dependencies with “mvn dependency:tree” and then exclude the transitive dependencies from the depdencies that pull them in.