Cannot deploy Spring App to Websphere

♀尐吖头ヾ 提交于 2020-01-10 13:39:39

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!