Search code examples
jax-rsjersey-2.0grizzlyservletcontextlistener

Jersey Grizzly Containers w/ @WebListener ServletContextListeners


I've got my JAX-RS web services running with grizzly-server, but I cannot configure my @WebListener to work. I am building a framework so I cannot switch to Grizzly listeners.

I've got the latest libraries.

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-grizzly2-http</artifactId>
</dependency>
<dependency>
    <groupId>org.glassfish.grizzly</groupId>
    <artifactId>grizzly-http-servlet</artifactId>
    <version>2.3.30</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
</dependency>

Here is some code:

@ApplicationPath("/SampleAdmin")
public class SampleAdminApplication extends ResourceConfig {
    public SampleAdminApplication() {
        packages("com.companyname.sample.sampleadmin.server.services");
    }
}

    @WebListener
    public class SampleAdminListener implements ServletContextListener {
        private static final Logger log = Logger.getLogger(SampleAdminListener.class);

        @Override
        public void contextInitialized(ServletContextEvent servletContextEvent) {
            log.info("SampleAdminListener Initializing context.");
        }

        @Override
        public void contextDestroyed(ServletContextEvent servletContextEvent) {
            log.info("SampleAdminListener Destroying context.");
        }
    }
    /**
     * Starts Grizzly HTTP server exposing JAX-RS resources defined in this application.
     * @return Grizzly HTTP server.
     */
    public static HttpServer startServer() {
        // create a resource config that scans for JAX-RS resources and providers
        // in com.example.rest package
        final ResourceConfig rc = new SampleAdminApplication();

        // create and start a new instance of grizzly http server
        // exposing the Jersey application at BASE_URI
        HttpServer httpServer = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);

        WebappContext context = new WebappContext("WebappContext", "/" + webapp);
        context.addListener("com.vilabs.sample.sampleadmin.server.servlet.SampleAdminListener");
        context.addFilter("SampleAdminFilter", SampleAdminFilter.class);
        context.addFilter("SampleAdminCsrfFilter", SampleAdminCsrfFilter.class);
//        ServletRegistration registration = context.addServlet("ServletContainer", new ServletContainer(rc));
        ServletRegistration registration = context.addServlet("ServletContainer", new ServletContainer(rc));
        registration.addMapping("/*");

        context.deploy(httpServer);
        return httpServer;
    }

The call to context.deploy(httpServer) throws IllegalStateException.

Jun 06, 2017 7:14:14 PM org.glassfish.grizzly.servlet.WebappContext deploy
SEVERE: [WebappContext] Exception deploying application.  See stack trace for details.
java.lang.RuntimeException: java.lang.IllegalStateException: The resource configuration is not modifiable in this context.
    at org.glassfish.grizzly.servlet.WebappContext.initServlets(WebappContext.java:1833)
    at org.glassfish.grizzly.servlet.WebappContext.deploy(WebappContext.java:318)
    at com.vilabs.sample.sampleadmin.server.SampleServer.startServer(SampleServer.java:60)
    at com.vilabs.sample.sampleadmin.server.SampleServer.main(SampleServer.java:70)
Caused by: java.lang.IllegalStateException: The resource configuration is not modifiable in this context.
    at org.glassfish.jersey.server.ResourceConfig$ImmutableState.register(ResourceConfig.java:274)
    at org.glassfish.jersey.server.ResourceConfig$ImmutableState.register(ResourceConfig.java:221)
    at org.glassfish.jersey.server.ResourceConfig.register(ResourceConfig.java:453)
    at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:387)
    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:244)
    at org.glassfish.grizzly.servlet.WebappContext.initServlets(WebappContext.java:1831)

Solution

  • IllegalStateException: The resource configuration is not modifiable in this context

    It's because createHttpServer(uri, resourceConfig) automatically starts the server unless the boolean flag is passed to the overloaded method, telling it not to auto-start.

    Another thing is that you are are trying to create two applications. Once when you call createHttpServer passing the ResourceConfig, and another time when you create the ServletContainer with the same ResourceConfig.

    What you should do is just the overloaded createHttpServer(uri). This won't create an application, and won't start the server. And you create the Jersey application when you create the ServletContainer with the ResourceConfig, and pass it to the WebAppContext.