问题
I've been developing an application to tomcat during development phase. As we're moving forward, my client wants to be deployed to websphere. I'm attempting to do so on websphere 8.5, but for some reason I seem to be running into problems. Tomcat is easy, I'm just dropping in the war and everything works like it should. Websphere is a different story. I keep getting the following error when I try to hit my application:
Error 404: SRVE0190E: File not found: {0}
I've been doing some research and aside from the one line below, I don't notice anything strange in the logs. The admin console says the application is running with no problems.
SRVE0292I: Servlet Message - [app#app.war]:.No Spring WebApplicationInitializer types detected on classpath
My application is configured using Java Config files instead of the traditional XML and I'm half guessing this is part of the problem?
I found a blog post saying that there were some server settings that needed to be applied. I've tried those with no success:
com.ibm.ws.webcontainer.mapFiltersToAsterisk=true
com.ibm.ws.webcontainer.removetrailingservletpathslash=true
com.ibm.ws.webcontainer.invokeFiltersCompatibility=true
I'm at a loss, does anyone have any ideas?
Due to some followup, I'll post my web.xml and WebappInitializer:
@Order(2)
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] {ApplicationConfig.class, DataSourceConfig.class, JpaConfig.class, SecurityConfig.class, MailConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] {WebMvcConfig.class};
}
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
return new Filter[] {characterEncodingFilter};
}
@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
registration.setInitParameter("defaultHtmlEscape", "true");
registration.setInitParameter("spring.profiles.active", "default");
}
}
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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_3_0.xsd"
version="3.0" metadata-complete="false">
<!-- Map all errors to Spring MVC handler method. See CustomErrorController.generalError() -->
<error-page>
<location>/generalError</location>
</error-page>
<session-config>
<session-timeout>15</session-timeout>
</session-config>
<display-name>eua</display-name>
</web-app>
回答1:
I'm not terribly happy about my solution, but it works for the time being. Websphere's support of web.xml-less initialization is a bit sub-standard. Even replies from their techs were unhelpful. In the end I had to move a bit of the spring initialization to the web.xml. I was still able to configure most of my JPA, security, and Web features via config files, but I had to give Spring a bit of kickstart. Below is my altered web.xml for anyone that is interested. Thanks everyone for the help and guidance.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<!-- Map all errors to Spring MVC handler method. See CustomErrorController.generalError() -->
<error-page>
<location>/generalError</location>
</error-page>
<session-config>
<session-timeout>15</session-timeout>
</session-config>
<display-name>app</display-name>
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>org.proj.config.ApplicationConfig
org.proj.config.DefaultDataSourceConfig
org.proj.config.JpaConfig
org.proj.config.SecurityConfig
org.proj.config.MailConfig
org.proj.config.WebMvcConfig
</param-value>
</context-param>
<!-- Bootstrap the root application context as usual using ContextLoaderListener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<!-- Again, config locations must consist of one or more comma- or space-delimited
and fully-qualified @Configuration classes -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>org.proj.config.ApplicationConfig
org.proj.config.DefaultDataSourceConfig
org.proj.config.JpaConfig
org.proj.config.SecurityConfig
org.proj.config.MailConfig
org.proj.config.WebMvcConfig
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>ERROR</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
</web-app>
回答2:
use @Configuration annotation on the WebAppInitializer class
@Configuration
public class WebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(HibernateConfiguration.class);
// Manage the lifecycle of the root application context
container.addListener(new ContextLoaderListener(rootContext));
// Create the dispatcher servlet's Spring application context
AnnotationConfigWebApplicationContext dispatcherServlet = new AnnotationConfigWebApplicationContext();
dispatcherServlet.register(SpringWebConfig.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherServlet));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
回答3:
I had similar issue. The Websphere has some default limit on the number of classes that can be scanned. And this SpringBoot main class was probably not within that range. In my case, the issue was resolved when I set this JVM property -Dclassinfocachesize=10000 (Application servers > server1 > Process definition > Java Virtual Machine> Generic JVM arguments >) and restart WAS
回答4:
For me working solution for IBM WAS ND 8.5.0 was to implement directly interface WebApplicationInitializer:
To deploy a Spring Boot application to Weblogic you must ensure that your servlet initializer directly implements WebApplicationInitializer (even if you extend from a base class that already implements it).
SpringBoot 74.4
回答5:
Both adding @Configuration annotation and directly implementing WebApplicationInitializer can resolve this issue. (Tested for Websphere 8.5.0.2)
回答6:
I faced the same issue too. My Spring MVC (Spring 4.3) Rest application was working on Jboss, but when I tried deploying on Websphere 8.5.5 I got the same error: SRVE0292I: Servlet Message - [app#app.war]:.No Spring WebApplicationInitializer types detected on classpath. I tried all the options suggested in this post and other posts, but nothing worked out. Finally I found the issue. When I created the Spring MVC Rest application I used maven archetype to create the project and it created the Spring MVC application with blank web.xml. As I planned to use Spring4, java based initialization, I left arechetype created web.xml like that and didn't configure my dispatcherServlet in web.xml. Jboss was intelligent enough to ignore blank web.xml and finding java initializer class and bringing the application up. Where as the same application deployed on WebSphere 8.5.5, WebSphere found the blank web.xml and looking for the DispatcherServlet info in the web.xml and not looking for the java initializer class. After removing the web.xml and redeploying the application is up on WebSphere.
回答7:
this issue is fixed by APAR PM85177 for WebSphere ND. The fix is integrated in WAS8.0.0.8 and following version.
来源:https://stackoverflow.com/questions/21714642/cannot-deploy-spring-app-to-websphere