javaspringspring-bootresin

Spring Boot war fails to deploy properly on Resin server


My projects relies on Spring Boot to build standalone executable jar files. It works great for internal testing. However, once we are ready to deployment it to our development environment, applications need to be in a war file so it can be deployed to our Resin server.

So I followed the guide (http://spring.io/guides/gs/convert-jar-to-war/) and did the conversion. Then I deployed the war application to a local Resin server and a long series of exceptions occurred.

Long story short, I ended up creating a simple hello world REST service using Spring Boot that builds as war and deployed it to Resin. The test application is at (https://github.com/ChrisZhong/spring-boot-war-sample). Similar problems occurred with the test application. But, the same test war deployed to Tomcat 7 without any problems and worked as intended. The following log is from Resin.

[14-03-12 17:06:25.414] {resin-34} WebApp[production/webapp/default/spring-boot-war-sample-1.1.1,STARTING] Spring WebApplicationInitializers detected on classpath: [hello.WebXml@62da57c9]

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

2014-03-12 17:06:26.765  INFO 4024 --- [       resin-34] o.s.boot.SpringApplication               : Starting application on CHRIS-DESKTOP with PID 4024 (C:\resin-4.0.38\webapps\spring-boot-war-sample-
1.1.1\WEB-INF\lib\spring-boot-1.0.0.RC4.jar started by czhong)
2014-03-12 17:06:26.919  INFO 4024 --- [       resin-34] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@3
93d3e1d: startup date [Wed Mar 12 17:06:26 CDT 2014]; root of context hierarchy
2014-03-12 17:06:29.034  INFO 4024 --- [       resin-34] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
[14-03-12 17:06:29.135] {resin-34} HV000001: Hibernate Validator 4.3.0.Final
2014-03-12 17:06:29.414  INFO 4024 --- [       resin-34] com.caucho.server.webapp.WebApp          : WebApp[production/webapp/default/spring-boot-war-sample-1.1.1,STARTING] Initializing Spring embedded
 WebApplicationContext
[14-03-12 17:06:29.415] {resin-34} WebApp[production/webapp/default/spring-boot-war-sample-1.1.1,STARTING] Initializing Spring embedded WebApplicationContext
2014-03-12 17:06:29.416  INFO 4024 --- [       resin-34] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 2497 ms
2014-03-12 17:06:31.500  INFO 4024 --- [       resin-34] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
com.caucho.config.ConfigException: Custom bean class 'org.springframework.boot.context.web.ErrorPageFilter' is not public.  Bean classes must be public, concrete, and have a zero-argument constructor.

        at com.caucho.config.Config.checkCanInstantiate(Config.java:532)
        at com.caucho.config.Config.validate(Config.java:561)
        at com.caucho.server.dispatch.FilterConfigImpl.setFilterClass(FilterConfigImpl.java:105)
        at com.caucho.server.webapp.WebApp.addFilter(WebApp.java:1457)
        at com.caucho.server.webapp.WebApp.addFilter(WebApp.java:1439)
        at org.springframework.boot.context.embedded.FilterRegistrationBean.onStartup(FilterRegistrationBean.java:233)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext$1.onStartup(EmbeddedWebApplicationContext.java:214)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:164)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:132)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:476)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:120)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:619)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:306)
        at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:130)
        at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:89)
        at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:51)
        at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
        at com.caucho.server.webapp.WebApp.callInitializer(WebApp.java:3494)
        at com.caucho.server.webapp.WebApp.callInitializers(WebApp.java:3462)
        at com.caucho.server.webapp.WebApp.startImpl(WebApp.java:3687)
        at com.caucho.server.webapp.WebApp.access$400(WebApp.java:207)
        at com.caucho.server.webapp.WebApp$StartupTask.run(WebApp.java:5231)
        at com.caucho.env.thread2.ResinThread2.runTasks(ResinThread2.java:173)
        at com.caucho.env.thread2.ResinThread2.run(ResinThread2.java:118)
2014-03-12 17:06:31.518  INFO 4024 --- [       resin-34] .b.l.ClasspathLoggingApplicationListener : Application failed to start with classpath: [file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.
1.1/WEB-INF/classes/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-INF/lib/aopalliance-1.0.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-INF/lib/commo
ns-logging-1.1.3.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-INF/lib/jackson-annotations-2.3.0.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-I
NF/lib/jackson-core-2.3.1.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-INF/lib/jackson-databind-2.3.1.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1
/WEB-INF/lib/jcl-over-slf4j-1.7.6.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-INF/lib/jul-to-slf4j-1.7.6.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1
.1.1/WEB-INF/lib/log4j-over-slf4j-1.7.6.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-INF/lib/logback-classic-1.1.1.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war
-sample-1.1.1/WEB-INF/lib/logback-core-1.1.1.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-INF/lib/slf4j-api-1.7.6.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-
sample-1.1.1/WEB-INF/lib/snakeyaml-1.13.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-INF/lib/spring-aop-4.0.2.RELEASE.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-
war-sample-1.1.1/WEB-INF/lib/spring-beans-4.0.2.RELEASE.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-INF/lib/spring-boot-1.0.0.RC4.jar!/, jar:file:/C:/resin-4.0.38/webapps
/spring-boot-war-sample-1.1.1/WEB-INF/lib/spring-boot-autoconfigure-1.0.0.RC4.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-INF/lib/spring-boot-starter-1.0.0.RC4.jar!/, jar
:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-INF/lib/spring-boot-starter-logging-1.0.0.RC4.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-INF/lib/spring-b
oot-starter-tomcat-1.0.0.RC4.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-INF/lib/spring-boot-starter-web-1.0.0.RC4.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-wa
r-sample-1.1.1/WEB-INF/lib/spring-context-4.0.2.RELEASE.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-INF/lib/spring-core-4.0.2.RELEASE.jar!/, jar:file:/C:/resin-4.0.38/web
apps/spring-boot-war-sample-1.1.1/WEB-INF/lib/spring-expression-4.0.2.RELEASE.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-INF/lib/spring-web-4.0.2.RELEASE.jar!/, jar:file
:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-INF/lib/spring-webmvc-4.0.2.RELEASE.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-INF/lib/tomcat-embed-core-7.0.5
2.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-INF/lib/tomcat-embed-el-7.0.52.jar!/, jar:file:/C:/resin-4.0.38/webapps/spring-boot-war-sample-1.1.1/WEB-INF/lib/tomcat-embe
d-logging-juli-7.0.52.jar!/]
2014-03-12 17:06:31.523  INFO 4024 --- [       resin-34] com.caucho.server.webapp.WebApp          : WebApp[production/webapp/default/spring-boot-war-sample-1.1.1] fail
[14-03-12 17:06:31.523] {resin-34} WebApp[production/webapp/default/spring-boot-war-sample-1.1.1] fail
2014-03-12 17:06:31.535  WARN 4024 --- [           main] com.caucho.server.webapp.WebApp          : java.lang.IllegalStateException: Registration is null. Was something already registered for name=[er
rorPageFilter]?

java.lang.IllegalStateException: Registration is null. Was something already registered for name=[errorPageFilter]?
        at org.springframework.util.Assert.state(Assert.java:385)
        at org.springframework.boot.context.embedded.RegistrationBean.configure(RegistrationBean.java:107)
        at org.springframework.boot.context.embedded.FilterRegistrationBean.configure(FilterRegistrationBean.java:241)
        at org.springframework.boot.context.embedded.FilterRegistrationBean.onStartup(FilterRegistrationBean.java:233)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext$1.onStartup(EmbeddedWebApplicationContext.java:214)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:164)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:132)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:476)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:120)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:619)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:306)
        at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:130)
        at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:89)
        at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:51)
        at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
        at com.caucho.server.webapp.WebApp.callInitializer(WebApp.java:3494)
        at com.caucho.server.webapp.WebApp.callInitializers(WebApp.java:3462)
        at com.caucho.server.webapp.WebApp.startImpl(WebApp.java:3687)
        at com.caucho.server.webapp.WebApp.access$400(WebApp.java:207)
        at com.caucho.server.webapp.WebApp$StartupTask.run(WebApp.java:5231)
        at com.caucho.env.thread2.ResinThread2.runTasks(ResinThread2.java:173)
        at com.caucho.env.thread2.ResinThread2.run(ResinThread2.java:118)

[14-03-12 17:06:31.541] {main} java.lang.IllegalStateException: Registration is null. Was something already registered for name=[errorPageFilter]?
                        at org.springframework.util.Assert.state(Assert.java:385)
                        at org.springframework.boot.context.embedded.RegistrationBean.configure(RegistrationBean.java:107)
                        at org.springframework.boot.context.embedded.FilterRegistrationBean.configure(FilterRegistrationBean.java:241)
                        at org.springframework.boot.context.embedded.FilterRegistrationBean.onStartup(FilterRegistrationBean.java:233)
                        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext$1.onStartup(EmbeddedWebApplicationContext.java:214)
                        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:164)
                        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:132)
                        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:476)
                        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:120)
                        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:619)
                        at org.springframework.boot.SpringApplication.run(SpringApplication.java:306)
                        at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:130)
                        at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:89)
                        at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:51)
                        at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
                        at com.caucho.server.webapp.WebApp.callInitializer(WebApp.java:3494)
                        at com.caucho.server.webapp.WebApp.callInitializers(WebApp.java:3462)
                        at com.caucho.server.webapp.WebApp.startImpl(WebApp.java:3687)
                        at com.caucho.server.webapp.WebApp.access$400(WebApp.java:207)
                        at com.caucho.server.webapp.WebApp$StartupTask.run(WebApp.java:5231)
                        at com.caucho.env.thread2.ResinThread2.runTasks(ResinThread2.java:173)
                        at com.caucho.env.thread2.ResinThread2.run(ResinThread2.java:118)

[14-03-12 17:06:31.543] {main} Host[production/host/default] active
[14-03-12 17:06:31.543] {main} ServletService[id=app-0,cluster=app] active
[14-03-12 17:06:31.543] {main}
[14-03-12 17:06:31.544] {main} http listening to *:8080
[14-03-12 17:06:32.294] {main} https listening to *:8443
[14-03-12 17:06:32.313] {main}
[14-03-12 17:06:32.327] {main} Resin[id=app-0] started in 17193ms
2014-03-12 17:08:31.542  INFO 4024 --- [       resin-29] com.caucho.server.webapp.WebApp          : WebApp[production/webapp/default/spring-boot-war-sample-1.1.1] stopping

I am told by a colleague who has some experience with Resin that there is a problem with loading the jar files as indicated by the ! at the end of each jar file.


Solution

  • For some reason Resin enforces that filters (programmatically?) added to the context must have a public modifier. The ErrorPageFilter in Spring Boot is package protected and as such fails that check (check the sources for both Resin and Spring Boot).

    I can imagine this check for Filters that are added through the ServletContext.addFilter(String, Class) method. Not for the method ServletContext.addFilter(String, Filter). The latter is used by Spring Boot to register the filters.

    I would consider this a bug in Resin.