1

I am moving to spring boot and converting web.xml to a programmatic equivalent. I am able to register the following successfully but cant find the equivalent of setting init params. Here is the snippet of web.xml that I am translating to code.

    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>javax.ws.rs.Application</param-name>
      <param-value>com.mmp.rest.support.JerseyConfig</param-value>
    </init-param>
    <init-param>
      <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
      <param-value>true</param-value>
    </init-param>

Here is the code that register the servlet progrmatically

    // working but cant get my custom configurations because of null pointer
        @Bean
        public ServletRegistrationBean servletRegistrationBean(){
            ServletContainer jerseyContainer = new ServletContainer();
            // commenting since this is throwing null pointer for getServletContext()
            //jerseyContainer.getServletContext().setInitParameter("javax.ws.rs.Application","com.mmp.rest.support.JerseyConfig");
            //jerseyContainer.getServletContext().setInitParameter("com.sun.jersey.api.json.POJOMappingFeature","true");
            return new ServletRegistrationBean(jerseyContainer,"/openenv/api/*");
        }

This is the error I am getting if I do not comment the code lines in the above snippet as I did

       .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::       (v1.5.10.RELEASE)

2018-04-04 10:28:45.138  INFO 8404 --- [           main] ump.env.EnvApplication                   : Starting EnvApplication on ENVPHIL149 with PID 8404 (C:\Users\Abdul.Hafeez\Downloads\ump\target\classes started by Abdul.Hafeez in C:\Users\Abdul.Hafeez\Downloads\ump)
2018-04-04 10:28:45.141  INFO 8404 --- [           main] ump.env.EnvApplication                   : No active profile set, falling back to default profiles: default
2018-04-04 10:28:45.248  INFO 8404 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@2ed0fbae: startup date [Wed Apr 04 10:28:45 EDT 2018]; root of context hierarchy
2018-04-04 10:28:46.640  INFO 8404 --- [           main] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2018-04-04 10:28:47.604  INFO 8404 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2018-04-04 10:28:47.617  INFO 8404 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2018-04-04 10:28:47.617  INFO 8404 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.27
2018-04-04 10:28:49.557  INFO 8404 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2018-04-04 10:28:49.557  INFO 8404 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 4309 ms
2018-04-04 10:28:49.573 ERROR 8404 --- [ost-startStop-1] o.s.b.c.embedded.tomcat.TomcatStarter    : Error starting Tomcat context. Exception: org.springframework.beans.factory.BeanCreationException. Message: Error creating bean with name 'servletRegistrationBean' defined in ump.env.EnvApplication: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.web.servlet.ServletRegistrationBean]: Factory method 'servletRegistrationBean' threw exception; nested exception is java.lang.NullPointerException
2018-04-04 10:28:49.635  WARN 8404 --- [           main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
2018-04-04 10:28:49.651  INFO 8404 --- [           main] utoConfigurationReportLoggingInitializer : 

Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2018-04-04 10:28:49.651 ERROR 8404 --- [           main] o.s.boot.SpringApplication               : Application startup failed

org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:137) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537) ~[spring-context-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at ump.env.EnvApplication.main(EnvApplication.java:37) [classes/:na]
Caused by: org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.initialize(TomcatEmbeddedServletContainer.java:123) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.<init>(TomcatEmbeddedServletContainer.java:84) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getTomcatEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:554) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:179) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:164) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:134) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    ... 8 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'servletRegistrationBean' defined in ump.env.EnvApplication: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.web.servlet.ServletRegistrationBean]: Factory method 'servletRegistrationBean' threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:234) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:215) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addServletContextInitializerBeans(ServletContextInitializerBeans.java:91) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:79) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getServletContextInitializerBeans(EmbeddedWebApplicationContext.java:241) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.selfInitialize(EmbeddedWebApplicationContext.java:228) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.access$000(EmbeddedWebApplicationContext.java:89) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext$1.onStartup(EmbeddedWebApplicationContext.java:213) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.context.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:55) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5196) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1419) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_162]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_162]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_162]
    at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_162]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.web.servlet.ServletRegistrationBean]: Factory method 'servletRegistrationBean' threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    ... 25 common frames omitted
Caused by: java.lang.NullPointerException: null
    at javax.servlet.GenericServlet.getServletContext(GenericServlet.java:123) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
    at org.glassfish.jersey.servlet.ServletContainer.getServletContext(ServletContainer.java:479) ~[ump-rest-deps-1.0-SNAPSHOT.jar:na]
    at ump.env.EnvApplication.servletRegistrationBean(EnvApplication.java:93) [classes/:na]
    at ump.env.EnvApplication$$EnhancerBySpringCGLIB$$4a25e205.CGLIB$servletRegistrationBean$2(<generated>) ~[classes/:na]
    at ump.env.EnvApplication$$EnhancerBySpringCGLIB$$4a25e205$$FastClassBySpringCGLIB$$fad8fa21.invoke(<generated>) ~[classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358) ~[spring-context-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at ump.env.EnvApplication$$EnhancerBySpringCGLIB$$4a25e205.servletRegistrationBean(<generated>) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_162]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_162]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_162]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_162]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    ... 26 common frames omitted
hhafeez
  • 73
  • 9
  • Why do you need to use init params in the previous project? – CInvt Apr 04 '18 at 14:38
  • it is a legacy project and through this param its customizing the ResourceConfig – hhafeez Apr 04 '18 at 14:40
  • I see. If you want to customize the API root path, Spring Boot does it [a little differently](https://stackoverflow.com/questions/32927937/how-to-set-base-url-for-rest-in-spring-boot). – CInvt Apr 04 '18 at 15:08
  • its not complaining about root path. root path is fine. – hhafeez Apr 04 '18 at 16:03

2 Answers2

1

After looking into the API I am able to figure this out and as @PaulSamsotha mentioned I do not need POJO mapping. Just have to pass the config instance while instantiating jersey container and it works like charm

@Bean
        public ServletRegistrationBean servletRegistrationBean(){
            // passing the JerseyConfig instance to ServletContainer
            ServletContainer jerseyContainer = new ServletContainer(new com.mmp.rest.support.JerseyConfig());
            return new ServletRegistrationBean(jerseyContainer,"/openenv/api/*");
        }
hhafeez
  • 73
  • 9
0

You don't need to do this. Just use the recommended way of using a ResourceConfig. You can set init-params by using the property method of the ResourceConfig. You can set the url mapping with the @ApplicationPath annotation.

@Component
@ApplicationPath("/openenv/api")
public class JerseyConfig extends ResourceConfig {
    public JerseyConfig() {
        packages("package.to.scan");
        property("<param-name>", "<param-value>");
    }
}

Also, POJOMappingFeature is something that is only for Jersey 1.x. It is not even needed in Jersey 2.x.

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • I don't want to touch this legacy class but I still tried what you suggested. I did not get any error but the rest service is not running then. – hhafeez Apr 04 '18 at 21:05
  • bye the way I am able to get it running by passing the jerseyConfig instance in ServletContainer – hhafeez Apr 04 '18 at 21:07
  • You need to register the services? Using your `JerseyConfig` class, just add a call to `property` in the constructor. If you use my code above it will not register any of your resources. The point was to use the ResourceConfig you're currently using. – Paul Samsotha Apr 04 '18 at 21:17
  • what property I am going to set with property call? will it register the service? – hhafeez Apr 04 '18 at 21:23
  • The POJOMappingFeature property doesn't exist in Jersey 2.x because it's not needed. – Paul Samsotha Apr 04 '18 at 21:27
  • yes like you said I don't need this and it works fine without it. – hhafeez Apr 04 '18 at 21:28
  • Then there is no need to create your own ServletRegistrationBean. Just add the `@ApplicationPath` annotation. – Paul Samsotha Apr 04 '18 at 21:29
  • I did but it does not work. I don't get any errors but rest service does not start up. – hhafeez Apr 04 '18 at 21:31
  • Does your JerseyConfig extend Application or ResourceConfig? If it extends Application, make it extend ResourceConfig. See https://stackoverflow.com/questions/45625925/what-exactly-is-the-resourceconfig-class-in-jersey-2/45627178#45627178. – Paul Samsotha Apr 04 '18 at 21:35
  • it extends ResourceConfig – hhafeez Apr 04 '18 at 21:36
  • Yeah, I don't know why it's not working then. It should work – Paul Samsotha Apr 04 '18 at 21:36
  • hmm it could be because I am not using any spring manage jersey and I have to provide org.glassfish.jersey.servlet.ServletContainer explicityly – hhafeez Apr 04 '18 at 21:41
  • Oh lol. I forgot you need to make the ResourceConfig class a Spring component. Add `@Component` on it. – Paul Samsotha Apr 04 '18 at 21:43
  • And make sure your ResourceConfig class is a class that is being scanned by the component scan. Wherever the main class is (that has the @SpringBootApplication), the ResourceConfig should be in the same package or a subpackage – Paul Samsotha Apr 04 '18 at 21:52