11
votes

I`m trying to run a simple application with spring java based configuration on jboss, but no success. This application works fine both on jetty and tomcat. The jboss log looks good, since it shows me some successful mappings etc, but I got 404 trying to access the url.

Here are my code:

Initializer

@Order(1)
public class Initializer extends AbstractAnnotationConfigDispatcherServletInitializer  {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] {RootConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] {WebAppConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] {"/"};
    }

    @Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration) {
        registration.setInitParameter("dispatchOptionsRequest", "true");
    }
}

RootConfig

@Configuration
@ComponentScan(value = "com.test.config", excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, value = RootConfig.class))
public class RootConfig {

}

WebAppConfig

@Configuration
@ComponentScan("com.test")
@EnableWebMvc
@EnableSpringDataWebSupport
public class WebAppConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    }

    @Bean
    public InternalResourceViewResolver setupViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/pages/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}

And now the jboss log...

17:08:53,645 INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/test]] (MSC service thread 1-8) Spring WebApplicationInitializers detected on classpath: [br.com.cleartech.config.Initializer@2f7e4dd2]
17:08:53,767 INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/test]] (MSC service thread 1-8) Initializing Spring root WebApplicationContext
17:08:53,768 INFO  [org.springframework.web.context.ContextLoader] (MSC service thread 1-8) Root WebApplicationContext: initialization started
17:08:53,770 INFO  [org.springframework.web.context.support.AnnotationConfigWebApplicationContext] (MSC service thread 1-8) Refreshing Root WebApplicationContext: startup date [Wed Dec 18 17:08:53 BRST 2013]; root of context hierarchy
17:08:53,843 INFO  [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] (MSC service thread 1-8) JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning
17:08:53,846 INFO  [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] (MSC service thread 1-8) JSR-330 'javax.inject.Named' annotation found and supported for component scanning
17:08:53,847 INFO  [org.springframework.web.context.support.AnnotationConfigWebApplicationContext] (MSC service thread 1-8) Registering annotated classes: [class br.com.cleartech.config.RootConfig]
17:08:53,915 INFO  [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] (MSC service thread 1-8) JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning
17:08:53,916 INFO  [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] (MSC service thread 1-8) JSR-330 'javax.inject.Named' annotation found and supported for component scanning
17:08:53,977 INFO  [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] (MSC service thread 1-8) JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning
17:08:53,978 INFO  [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] (MSC service thread 1-8) JSR-330 'javax.inject.Named' annotation found and supported for component scanning
17:08:54,130 INFO  [org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor] (MSC service thread 1-8) JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
17:08:54,153 INFO  [org.springframework.beans.factory.support.DefaultListableBeanFactory] (MSC service thread 1-8) Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@52477602: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,rootConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,log4j,webAppConfig,homeController,consoleAppender,fileAppender,registerSpringLogger,org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration,mvcValidator,simpleControllerHandlerAdapter,beanNameHandlerMapping,httpRequestHandlerAdapter,mvcContentNegotiationManager,requestMappingHandlerMapping,resourceHandlerMapping,requestMappingHandlerAdapter,mvcConversionService,viewControllerHandlerMapping,defaultServletHandlerMapping,handlerExceptionResolver,org.springframework.data.web.config.SpringDataWebConfiguration,pageableResolver,sortResolver,setupViewResolver]; root of factory hierarchy
17:08:54,269 INFO  [org.hibernate.validator.util.Version] (MSC service thread 1-8) Hibernate Validator 4.2.0.Final
17:08:54,388 INFO  [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping] (MSC service thread 1-8) Mapped "{[/teste],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String br.com.cleartech.controller.HomeController.teste()
17:08:54,404 INFO  [org.springframework.web.servlet.handler.SimpleUrlHandlerMapping] (MSC service thread 1-8) Mapped URL path [/resources/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
17:08:54,631 INFO  [org.springframework.web.servlet.handler.SimpleUrlHandlerMapping] (MSC service thread 1-8) Root mapping to handler of type [class org.springframework.web.servlet.mvc.ParameterizableViewController]
17:08:54,634 INFO  [org.springframework.web.servlet.handler.SimpleUrlHandlerMapping] (MSC service thread 1-8) Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler]
17:08:54,668 INFO  [org.springframework.web.context.ContextLoader] (MSC service thread 1-8) Root WebApplicationContext: initialization completed in 899 ms
17:08:54,675 INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/test]] (MSC service thread 1-8) Initializing Spring FrameworkServlet 'dispatcher'
17:08:54,676 INFO  [org.springframework.web.servlet.DispatcherServlet] (MSC service thread 1-8) FrameworkServlet 'dispatcher': initialization started
17:08:54,679 INFO  [org.springframework.web.context.support.AnnotationConfigWebApplicationContext] (MSC service thread 1-8) Refreshing WebApplicationContext for namespace 'dispatcher-servlet': startup date [Wed Dec 18 17:08:54 BRST 2013]; parent: Root WebApplicationContext
17:08:54,681 INFO  [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] (MSC service thread 1-8) JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning
17:08:54,682 INFO  [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] (MSC service thread 1-8) JSR-330 'javax.inject.Named' annotation found and supported for component scanning
17:08:54,683 INFO  [org.springframework.web.context.support.AnnotationConfigWebApplicationContext] (MSC service thread 1-8) Registering annotated classes: [class br.com.cleartech.config.WebAppConfig]
17:08:54,685 INFO  [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] (MSC service thread 1-8) JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning
17:08:54,686 INFO  [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] (MSC service thread 1-8) JSR-330 'javax.inject.Named' annotation found and supported for component scanning
17:08:54,698 INFO  [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] (MSC service thread 1-8) JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning
17:08:54,699 INFO  [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] (MSC service thread 1-8) JSR-330 'javax.inject.Named' annotation found and supported for component scanning
17:08:54,759 INFO  [org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor] (MSC service thread 1-8) JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
17:08:54,786 INFO  [org.springframework.beans.factory.support.DefaultListableBeanFactory] (MSC service thread 1-8) Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@12f882f3: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,webAppConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,log4j,rootConfig,homeController,consoleAppender,fileAppender,registerSpringLogger,org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration,mvcValidator,simpleControllerHandlerAdapter,beanNameHandlerMapping,httpRequestHandlerAdapter,mvcContentNegotiationManager,requestMappingHandlerMapping,resourceHandlerMapping,requestMappingHandlerAdapter,mvcConversionService,viewControllerHandlerMapping,defaultServletHandlerMapping,handlerExceptionResolver,org.springframework.data.web.config.SpringDataWebConfiguration,pageableResolver,sortResolver,setupViewResolver]; parent: org.springframework.beans.factory.support.DefaultListableBeanFactory@52477602
17:08:54,885 INFO  [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping] (MSC service thread 1-8) Mapped "{[/teste],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String br.com.cleartech.controller.HomeController.teste()
17:08:54,891 INFO  [org.springframework.web.servlet.handler.SimpleUrlHandlerMapping] (MSC service thread 1-8) Mapped URL path [/resources/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
17:08:54,927 INFO  [org.springframework.web.servlet.handler.SimpleUrlHandlerMapping] (MSC service thread 1-8) Root mapping to handler of type [class org.springframework.web.servlet.mvc.ParameterizableViewController]
17:08:54,931 INFO  [org.springframework.web.servlet.handler.SimpleUrlHandlerMapping] (MSC service thread 1-8) Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler]
17:08:54,962 INFO  [org.springframework.web.servlet.DispatcherServlet] (MSC service thread 1-8) FrameworkServlet 'dispatcher': initialization completed in 285 ms
17:08:54,977 INFO  [org.jboss.web] (MSC service thread 1-8) JBAS018210: Registering web context: /test
17:08:54,985 INFO  [org.jboss.as] (MSC service thread 1-5) JBAS015951: Admin console listening on http://127.0.0.1:9990
17:08:54,986 INFO  [org.jboss.as] (MSC service thread 1-5) JBAS015874: JBoss AS 7.1.1.Final "Brontes" started in 8333ms - Started 377 of 455 services (77 services are passive or on-demand)
17:08:55,175 INFO  [org.jboss.as.server] (DeploymentScanner-threads - 2) JBAS018559: Deployed "test.war"

As you can see, it seems to be ok, since I got some:

Spring WebApplicationInitializers detected on classpath
Initializing Spring root WebApplicationContext
Root WebApplicationContext: initialization started
Mapped URL path [/resources/**]
Mapped URL path [/**]
Registering web context: /test
JBAS018559: Deployed "test.war"

But when trying to access localhost:8080/test or even a simple rest declared into a controller I got 404.

EDIT Just to explain that at the time this post was written, I was not using spring boot. Most of the answers refers to it as a solution.

8
What happens when you try to access admin console athttp://127.0.0.1:9990 ?kosa
Do you have any handlers for /?Sotirios Delimanolis
@Nambari, works fine, appears the jboss admin console...Thiago Pereira
@Sotirios, I have this one: public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("index"); }Thiago Pereira
@SotiriosDelimanolis: I was suspecting, other services (jetty/tomcat) running on 8080, but app not there, anyway it seems from logs it clear that Jboss listening on 8080. If no web server running 8080, you will get that browser screen with no response.kosa

8 Answers

10
votes

I was using @SpringBootApplication

As I read in this thread I needed to:

Change the mapping of the DispatcherServlet to "/*" instead of "/" (by adding a @Bean of type ServletRegistrationBean with a servlet named "dispatcherServlet")

In this url I found the code solution: Add Servlet Mapping to dispatch servlet

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

    @Bean
    public DispatcherServlet dispatcherServlet() {
        return new DispatcherServlet();
    }

    /**
     * Register dispatcherServlet programmatically 
     * 
     * @return ServletRegistrationBean
     */
    @Bean
    public ServletRegistrationBean dispatcherServletRegistration() {
        ServletRegistrationBean registration = new ServletRegistrationBean(
                dispatcherServlet(), "/*");
        registration
                .setName(DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME);
        return registration;
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}
9
votes

I had a similar problem with a Spring MVC project deployed to JBoss 7.1 with no web.xml.

According to Spring javadocs for WebApplicationInitializer, older versions of Tomcat (<=7.0.14) could not be mapped to "/" programmatically. Older versions of JBoss AS 7 have this same defect.

This was the source of my problem. I was registering the servlet via "/", but JBoss EAP 6.4 doesn't support this mapping programmatically. It only works via web.xml. I still wanted to use programmatic config, so I changed the mapping to "/*" instead of "/", and it fixed my issue.

public class WebApplicationInitializerImpl implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) throws ServletException {
        WebApplicationContext context = getContext();

        Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet(context));
        registration.setLoadOnStartup(1);
        registration.addMapping("/*");
    }

    private WebApplicationContext getContext() {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.setConfigLocation(AppConfig.class.getName());
        return context;
    }

}

Note: This configuration is incompatible with JSP views. "/*" will supersede the servlet container's JSP Servlet. If you still rely on JSP views, I would recommend using web.xml to configure the DispatcherServlet instead of doing it programmatically; the web.xml configuration works with "/" correctly.

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value></param-value>
    </init-param>
</servlet>

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
9
votes

We have a spring-boot (1.1.4) project on JBoss EAP 6.2 (my customer's requirement...)

I found a solution to run it on JBoss EAP 6.2.0 GA and keep capability to run on Apache Tomcat 7 container.

Initially my project run in embedded mode, so I need to create and change some files to run on containers.

To run on Tomcat as root application I created context.xml: /src/main/webapp/META-INF/context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path=""/>

To run on JBOSS EAP 6.2.0 GA as root application I created jboss-web.xml: /src/main/webapp/WEB-INF/jboss-web.xml

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
    <context-root>/</context-root>
</jboss-web>

I created a class, because JBoss servlet mapping works as /* but not with / :

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

/**
 * Working without web.xml with container (not em,bedded mode).
 * JBOSS EAP 6.2 specific: you need to map dispatcherServlet to /* .
 */
public class ContainerWebXml extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(TomcatStart.class);
    }

    /**
     * JBOSS EAP 6.2 mapping.
     *
     * @param container
     * @throws ServletException
     */
    @Override
    public void onStartup(ServletContext container) throws ServletException {
        WebApplicationContext context = getContext();

        Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet(context));
        registration.setLoadOnStartup(1);
        registration.addMapping("/*"); // required JBOSS EAP 6.2.0 GA
        super.onStartup(container);
    }

    private WebApplicationContext getContext() {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.setConfigLocation(TomcatStart.class.getName());
        return context;
    }

}

Do not forget call super.onStartup(container);

Changes in pom.xml:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>

If you use spring.profile, than you need to set as env. variable.

I run JBoss EAP 6.2.0 GA as standalone mode:

export JAVA_OPTS="-Dspring.profiles.active=local"
.../jboss-eap-6.2/bin/standalone.sh

If you run on Tomcat, then do not forget to set -Dspring.profiles.active=local

As I see the server.port setting will be ignored when you run on container.

7
votes

I'm using Spring Boot 1.3.1 and JBoss EAP 6.4. And I found with that in your project you can add to src/main/resources/application.properties this line:

server.servlet-path=/*

Also, if you're launching this out of Eclipse, be sure to clean your project... I blew a lot of time because of that alone.

2
votes

As per the answers provided by Michael R and István Pató, the servlet mapping in JBoss must be "/*", not "/". However, the other solutions cause @Component annotated objects to be instantiated twice. The following solves the double initialization by first calling super.onStartup and then adding another mapping for the dispatcher servlet:

public class WebApplicationInitializerImpl implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext container) throws ServletException {
        super.onStartup(container);

        Dynamic registration = (Dynamic) container.getServletRegistration(EmbeddedWebApplicationContext.DISPATCHER_SERVLET_NAME);
        registration.setLoadOnStartup(1);
        registration.addMapping("/*");
    }
}
2
votes

I am using JBoss EAP 6.4. I was going through the thread.

I would like to add that after changing mapping for dispatchServlet from "/" to "/* ". The JSP in your project might not process correctly. I suspect that since "/* " have more precedence over "/*.jsp ", therefore, JSPServlet might not be getting request to process the JSP and JSP will not be processed correctly. In my case, source of JSP is coming on browser as text.

I have resolved this issue by defining JSP as servlet in web.xml as mentioned below. After that things worked fine for me :)

<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

<servlet>
    <servlet-name>LoginServlet</servlet-name>
    <jsp-file>/login.jsp</jsp-file>
</servlet>

<servlet>
    <servlet-name>IndexServlet</servlet-name>
    <jsp-file>/index.jsp</jsp-file>
</servlet>
<!--mapping -->
<servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/login.jsp</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>IndexServlet</servlet-name>
    <url-pattern>/index.jsp</url-pattern>
</servlet-mapping>

I spent lot of time on this, might help someone :))

1
votes

Well, for someone else who is facing this problem, it just works fine on the new Wildfly. If you don't have any specific container to run your application, you can choose between jboss 7 and wildfly AND wants to run spring java config, try it out on wildfly!

1
votes

I had similar problems with JBoss 6.4.0. and Spring Boot 1.3 in combination with Tiles 3. After installing the Jboss patch jboss-eap-6.4.6-patch.zip the problems were solved.

After patching I did not need to use the setting server.servlet-path=/*