Use Jersey to provide REST APIs from karaf applications

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:

  1. 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 {
        ...
    }
  2. 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);
        }
        ...
    }
  3. Override the ServletContainer.init(WebConfig) method, and:
    1. 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);
    2. 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());
    3. 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);
                      }
                  });
    4. 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.

  4. 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:

  1. Clone this project and build it:
    git clone https://github.com/steinarb/jersey-demo.git
    cd jersey-demo
    mvn clean install
    
  2. Install apache karaf and start it  according to the karaf quick start guide (alternatively, see Develop OSGi applications using karaf)
  3. 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
  4. 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:

  1. 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
  2. jerseyinkaraf.servicedef which is an OSGi bundle containing the interfaces and bean defining the OSGi service for doing the counting
  3. jerseinkaraf.services which is an OSGi bundle containing a DS component implementing the services
  4. 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
  5. 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

2 thoughts on “Use Jersey to provide REST APIs from karaf applications”

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

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.