Spring boot war doesn´t work on Jboss 7.1

后端 未结 2 1567
孤街浪徒
孤街浪徒 2021-01-16 05:42

I´m trying to deploy a Spring boot application on Jboss. I follow this tutorial for convert my jar in to a war file. But when i try to run the application on Jboss it´s give

相关标签:
2条回答
  • 2021-01-16 05:56

    spring-boot on compile generate two files(.war).

    myapp-0.0.1-SNAPSHOT
    myapp-0.0.1-SNAPSHOT.war.original
    

    If you wan to deploy to JBoss 7.1 you need to rename myapp-0.0.1-SNAPSHOT.war.original to e.g myapp-0.0.1.war(remove .original extension) and deploy to server.

    0 讨论(0)
  • 2021-01-16 06:09

    The main issue with deploying spring-boot is explained here

    The post is a bit old by now and does not apply to the current spring-boot (1.3.3 as of this writing).

    What is happening in your case is that some filter in spring-boot actuator do not have default constructors which JBoss will try to call so to get around this you need to do the following (This is for current spring-boot 1.3.3):

    Create an ApplicationContext which will wrap all bean filters in a delegating class which has a default constructor. We can use spring's DelegatingFilterProxy for that

    public class JBossWebApplicationContext extends AnnotationConfigEmbeddedWebApplicationContext {
    
    private final Logger log = LoggerFactory.getLogger(getClass());
    
    @Override
    protected Collection<ServletContextInitializer> getServletContextInitializerBeans() {
        Collection<ServletContextInitializer> servletContextInitializerBeans = super.getServletContextInitializerBeans();
        for (ServletContextInitializer servletContextInitializerBean : servletContextInitializerBeans) {
            if (servletContextInitializerBean instanceof FilterRegistrationBean) {
                FilterRegistrationBean frb = (FilterRegistrationBean) servletContextInitializerBean;
                try {
                    Field field = FilterRegistrationBean.class.getDeclaredField("filter");
                    field.setAccessible(true);
                    Filter origFilter = (Filter) field.get(frb);
                    frb.setFilter(new DelegatingFilterProxy(origFilter));
                } catch (NoSuchFieldException | IllegalAccessException e) {
                    throw new BeanCreationException("Error setting up bean. It does not have a filter field", e);
                }
    
            }
        }
    
        return servletContextInitializerBeans;
    }
    }
    

    Then in your springboot main class make sure to use the context we created above:

    @SpringBootApplication
    public class MyApplication extends SpringBootServletInitializer {
    
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        application.sources(MyApplication.class);
        application.contextClass(JBossWebApplicationContext.class);
        return super.configure(application);
    }
    
    public static void main(String[] args) throws Exception {
        SpringApplication app = new SpringApplication(MyApplication.class);
        app.setApplicationContextClass(JBossWebApplicationContext.class);
        app.run(args);
    }
    }
    

    Lastly you need to make sure your servlet path is configured to be "/*" since JBoss 7.1 does not seem to work with only the default (/). This can be configured in your application.yml (or application.properties)

    server:
      servletPath: /*
    

    This should allow you to deploy a springBoot application in JBoss 7.1 (Tested myself on 7.1.3)

    Some extra points:

    • I have NOT tested this extensively and therefore you should make sure things are behaving as they should be before relying on this solution
    • I really don't like having to call reflection to get the FRB underlying filter but unfortunately the getFilter method is protected
    • This solution can probably be improved upon by someone who is more versed into spring than I am
    0 讨论(0)
提交回复
热议问题