title: Jersey web application registering resources dynamically
body: <p>I have a web application, which shall load its resources dynamically from jar files.</p>
  
  <p>I started to use <code>org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory.createHttpServer</code> to setup my own server and loaded all resources via <code>ServiceLoader</code> and registered them via <code>ResourceConfig#register</code>. This worked nicely, but I had always a second server running.</p>
  
  <p>Now I want to create a simple war of the application and deploy it on e.g. tomcat. The idea is, when the war is loaded, that the resources are also loaded via <code>ServiceLoader</code> and then available (so same as with the standalone server).</p>
  
  <p>How must I re-write the main class that loaded and registered the resources and fired up the server, so that it is working inside a web application ?</p>
  
  <p>I currently have a <code>javax.ws.rs.core.Application</code> defined, that in a method marked with <code>@PostConstruct</code> loads the resources. Though this is working, it gets initialised with every request.</p>
  
  <p>I tried to add <code>javax.inject.Singleton</code> to the Application, but this resulted in the error:</p>
  
  <pre><code>java.lang.IllegalStateException: Unable to perform operation: post construct on com.test.server.IntegrationServer
  at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:392)
  at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
  at org.jvnet.hk2.internal.SingletonContext$1.compute(SingletonContext.java:83)
  at org.jvnet.hk2.internal.SingletonContext$1.compute(SingletonContext.java:71)
  at org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture$1.call(Cache.java:97)
  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  at org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture.run(Cache.java:154)
  at org.glassfish.hk2.utilities.cache.Cache.compute(Cache.java:199)
  at org.jvnet.hk2.internal.SingletonContext.findOrCreate(SingletonContext.java:122)
  at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2020)
  at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:766)
  at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:705)
  at org.glassfish.jersey.server.ApplicationHandler.createApplication(ApplicationHandler.java:385)
  at org.glassfish.jersey.server.ApplicationHandler.&lt;init&gt;(ApplicationHandler.java:342)
  at org.glassfish.jersey.servlet.WebComponent.&lt;init&gt;(WebComponent.java:392)
  at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:177)
  at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:369)
  at javax.servlet.GenericServlet.init(GenericServlet.java:158)
  </code></pre>
  
  <p>Is my approach completely wrong ? Or how can I create such a system, to be run as deployable war ? </p>
  
  <p><strong>* EDIT *</strong></p>
  
  <p>With using a ServletContextListener, I could solve the multiple init calls, but my resources are not loaded.</p>
  
  <p>So, I have a resource like that</p>
  
  <pre><code>@Path("test")
  </code></pre>
  
  <p>public class TestResource implements MarkerInterface {
      @GET
      @Produces(MediaType.TEXT_PLAIN)
      @Path("get")
      public String get() {
          return "HELLO";
      }
  }
  This resource is packed in a jar file and is located in the file system.</p>
  
  <p>The application now loads this file location and loads via <code>ServiceLoader</code> all <code>MarkerInterface</code> classes and shall register them.</p>
  
  <p>I have</p>
  
  <pre><code>@WebListener
  public class IntegrationServer extends ResourceConfig implements ServletContextListener {
  
  @Override
  public void contextInitialized(ServletContextEvent sce) {
      LOGGER.info(() -&gt; "CONTEXT INIT");
      try {
          register(JacksonFeature.class);
          // wrapper for the ServiceLoader implementation
          this.serviceLoader = new IntegrationServiceLoader();
         this.serviceLoader.loadIntegrations(MarkerInterface.class, gce -&gt; {
              LOGGER.info(() -&gt; "Adding " + gce.getClass() + " to Server");
              register(gce.getClass());
          });
      }
      catch (IOException e) {
          LOGGER.log(Level.SEVERE, e, () -&gt; "Failed to init integration server");
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p>I see the registration output in the log, when deploying it as <code>server.war</code> on tomcat, but when I call  <code>http://localhost:8080/server/test/get</code> I get a HTTP Status 404 - Not Found.</p>
  
  <p>My web.xml looks like</p>
  
  <pre><code>&lt;web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://java.sun.com/xml/ns/javaee"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  version="2.5"&gt;
  &lt;servlet&gt;
      &lt;servlet-name&gt;Jersey Web Application&lt;/servlet-name&gt;
      &lt;servlet-class&gt;org.glassfish.jersey.servlet.ServletContainer&lt;/servlet-class&gt;
      &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
  &lt;/servlet&gt;
  &lt;servlet-mapping&gt;
      &lt;servlet-name&gt;Jersey Web Application&lt;/servlet-name&gt;
      &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;
  </code></pre>
  
  <p></p>
  
  <p>** EDIT 2***</p>
  
  <p>See Cássio Mazzochi Molin answer for this discussion.</p>
  
  <p>I used the builder to register my resources and printed it out</p>
  
  <pre><code>Builder{names=[com.test.server.TestResource], path='backend', methodBuilders=[], childResourceBuilders=[Builder{names=[[unnamed]], path='info', methodBuilders=[org.glassfish.jersey.server.model.ResourceMethod$Builder@819f71f], childResourceBuilders=[], childResources=[], resourceMethods=[], subResourceLocator=null, handlerClasses=[], handlerInstances=[], parentResource=Builder{names=[com.cetrea.qa.server.TestResource], path='backend'}, extended=false}], childResources=[Resource{"achievements", 3 child resources, 0 resource methods, 0 sub-resource locator, 1 method handler classes, 0 method handler instances},
  </code></pre>
  
  <p>this is part of it. The TestResource has a method <code>info</code>, so I can call <code>http://localhost:8080/server/backend/info</code> and get the right result.
  The resource <code>achievements</code> come from a plugin and has e.g. a <code>all</code> method, so I tried <code>http://localhost:8080/server/backend/achievements/all</code> (and also without the <code>backend</code> part), but this gives again 404</p>