Jetty.project: SpringMVC Annotation Config fails due to multiple executions of Servlet Listeners

Created on 13 Nov 2018  路  8Comments  路  Source: eclipse/jetty.project

When i upgrade jetty to 9.4.13 9.4.13.v20181111, My SpringMVC application failed to start with this error:
...check whether you have multiple ContextLoader* definitions...

Before 9.4.13 everything works fine.
Environment:
Windows 10 1809 x64
Java 11 x64
Jetty 9.4.13 9.4.13.v20181111
IDEA 2018.3 EAP

I used Annotation Config:

@Configuration
public class SystemWebApplicationInitializer implements WebApplicationInitializer {
    private AnnotationConfigWebApplicationContext getContext() {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.setConfigLocation("qi.ruibu.system");

        return context;
    }

    @Override
    public void onStartup(ServletContext servletContext) {
        WebApplicationContext context = getContext();
        servletContext.addListener(new ContextLoaderListener(context));
        ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
        dispatcher.setLoadOnStartup(1);
        dispatcher.setAsyncSupported(true);
        dispatcher.addMapping("/");

        FilterRegistration.Dynamic encodingFilter = servletContext.addFilter("encoding-filter", new CharacterEncodingFilter());
        encodingFilter.setInitParameter("encoding", "UTF-8");
        encodingFilter.setInitParameter("forceEncoding", "true");
        encodingFilter.setAsyncSupported(true);
        encodingFilter.addMappingForUrlPatterns(null, false, "/*");
    }
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"qi.ruibu.controller"})
public class SystemWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
        registry.addResourceHandler("/*.txt").addResourceLocations("/");
    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedOrigins("*").allowedMethods("*");
    }

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.jsp().prefix("/WEB-INF/views/").suffix(".jsp");
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
        converters.add(stringHttpMessageConverter);
    }
}

and build.gradle:

apply plugin: 'java'
apply plugin: 'idea'

compileJava.dependsOn(processResources)

version = '1.0'

repositories {
    jcenter()
    mavenCentral()
}

String springCoreVersion = '5.1.2.RELEASE'
String log4j2Version = '2.11.1'
String springSecurityVersion = '5.1.1.RELEASE'
String hibernateVersion = '5.3.7.Final'
String jacksonVersion = '2.9.7'
String nettyVersion = '4.1.31.Final'
String junitVersion = '5.3.0'
String jettyVersion = '9.4.13.v20181111'
String kotlinVersion = '1.3.0'

configurations {
    all {
        exclude group: 'asm', module: 'asm'
        exclude group: 'dom4j', module: 'dom4j'
        exclude group: 'commons-logging', module: 'commons-logging'
        exclude group: 'com.sun.mail', module: 'javax.mail'
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    //Spring
    implementation 'org.springframework:spring-core:' + springCoreVersion
    implementation 'org.springframework:spring-context:' + springCoreVersion
    implementation 'org.springframework:spring-aop:' + springCoreVersion
    implementation 'org.springframework:spring-beans:' + springCoreVersion
    implementation 'org.springframework:spring-expression:' + springCoreVersion
    implementation 'org.springframework:spring-jcl:' + springCoreVersion
    implementation 'org.springframework:spring-jdbc:' + springCoreVersion
    implementation 'org.springframework:spring-web:' + springCoreVersion
    implementation 'org.springframework:spring-webmvc:' + springCoreVersion
    implementation 'org.springframework:spring-orm:' + springCoreVersion
    implementation 'org.springframework:spring-tx:' + springCoreVersion
    implementation 'org.springframework:spring-messaging:' + springCoreVersion
    implementation 'org.springframework:spring-websocket:' + springCoreVersion
    implementation 'org.springframework.security:spring-security-core:' + springSecurityVersion
    implementation 'org.springframework.security:spring-security-web:' + springSecurityVersion
    implementation 'org.springframework.security:spring-security-oauth2-core:' + springSecurityVersion
    implementation('org.springframework.security:spring-security-oauth2-client:' + springSecurityVersion) {
        exclude group: 'javax.mail'
    }
    testImplementation 'org.springframework:spring-test:' + springCoreVersion

    //Kotlin
    implementation 'org.jetbrains.kotlin:kotlin-stdlib:' + kotlinVersion
    implementation 'org.jetbrains.kotlin:kotlin-stdlib-common:' + kotlinVersion
    implementation 'org.jetbrains.kotlin:kotlin-reflect:' + kotlinVersion

    implementation 'cglib:cglib:3.2.8'
    implementation 'net.bytebuddy:byte-buddy:1.9.2'
    implementation 'org.ow2.asm:asm:7.0'
    implementation 'javax.servlet:javax.servlet-api:3.1.0'
    implementation 'javax.servlet.jsp:javax.servlet.jsp-api:2.3.2-b01'
    implementation 'javax.servlet.jsp.jstl:jstl:1.2'
    implementation 'javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:1.2.1'
    implementation 'org.apache.logging.log4j:log4j:' + log4j2Version
    implementation 'org.apache.logging.log4j:log4j-core:' + log4j2Version
    implementation 'org.apache.logging.log4j:log4j-web:' + log4j2Version
    implementation 'org.glassfish:javax.el:3.0.1-b09'
    implementation 'com.mchange:c3p0:0.9.5.2'
    implementation 'org.hibernate:hibernate-core:' + hibernateVersion
    implementation 'org.hibernate:hibernate-c3p0:' + hibernateVersion
    implementation 'commons-codec:commons-codec:1.11'
    implementation 'org.apache.commons:commons-compress:1.18'
    implementation 'commons-io:commons-io:2.6'
    implementation 'org.apache.commons:commons-lang3:3.8.1'
    implementation 'org.apache.commons:commons-text:1.6'
    implementation 'commons-fileupload:commons-fileupload:1.3.3'
    implementation 'org.apache.commons:commons-collections4:4.2'
    implementation 'org.apache.commons:commons-configuration2:2.3'
    implementation 'commons-beanutils:commons-beanutils:1.9.3'
    implementation 'org.apache.commons:commons-digester3:3.2'
    implementation 'commons-jxpath:commons-jxpath:1.3'
    implementation 'com.fasterxml.jackson.core:jackson-databind:' + jacksonVersion
    implementation 'com.fasterxml.jackson.core:jackson-core:' + jacksonVersion
    implementation 'com.fasterxml.jackson.core:jackson-annotations:' + jacksonVersion
    implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:' + jacksonVersion
    implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:' + jacksonVersion
    implementation 'com.fasterxml.jackson.module:jackson-module-parameter-names:' + jacksonVersion
    implementation 'com.fasterxml.jackson.module:jackson-module-kotlin:' + jacksonVersion
    implementation 'com.squareup.okio:okio:2.1.0'
    implementation 'com.squareup.okhttp3:okhttp:3.11.0'
    implementation 'org.postgresql:postgresql:42.2.5'
    implementation 'com.thoughtworks.xstream:xstream:1.4.11.1'
    implementation 'org.dom4j:dom4j:2.1.1'
    implementation 'jaxen:jaxen:1.1.6'
    implementation 'org.apache.poi:poi:4.0.0'
    implementation 'org.apache.poi:poi-ooxml:4.0.0'
    implementation 'com.google.zxing:core:3.3.3'
    implementation 'com.google.zxing:javase:3.3.3'
    implementation 'com.belerweb:pinyin4j:2.5.1'
    implementation 'org.bouncycastle:bcpkix-jdk15on:1.60'
    implementation 'org.bouncycastle:bcprov-jdk15on:1.60'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:' + junitVersion
    testImplementation 'org.junit.jupiter:junit-jupiter-engine:' + junitVersion
    testImplementation 'org.junit.jupiter:junit-jupiter-params:' + junitVersion
    implementation 'io.netty:netty-buffer:' + nettyVersion
    implementation 'io.netty:netty-codec:' + nettyVersion
    implementation 'io.netty:netty-codec-http:' + nettyVersion
    implementation 'io.netty:netty-codec-socks:' + nettyVersion
    implementation 'io.netty:netty-common:' + nettyVersion
    implementation 'io.netty:netty-handler:' + nettyVersion
    implementation 'io.netty:netty-handler-proxy:' + nettyVersion
    implementation 'io.netty:netty-resolver:' + nettyVersion
    implementation 'io.netty:netty-transport:' + nettyVersion
    implementation 'io.netty:netty-transport-native-epoll:' + nettyVersion
    implementation 'io.netty:netty-transport-native-unix-common:' + nettyVersion
    implementation 'javax.xml.bind:jaxb-api:2.3.0'
    implementation 'org.glassfish.jaxb:jaxb-runtime:2.3.0.1'
    implementation 'org.eclipse.jetty.websocket:websocket-api:' + jettyVersion
    implementation 'org.eclipse.jetty.websocket:websocket-server:' + jettyVersion
    implementation 'io.jsonwebtoken:jjwt-api:0.10.5'
    implementation 'io.jsonwebtoken:jjwt-impl:0.10.5'
    implementation 'io.jsonwebtoken:jjwt-jackson:0.10.5'
}

Most helpful comment

@mymbrooks @KingBuzzer thanks for the bug report and the reproduction webapp.

Found and fixed the bug.

Standby for release 9.4.14 (I knew 13 was an unlucky number!).

All 8 comments

Hi
can you share this as a github project?
Thanks

This happens to our Spring based applications also with just the only change going from 9.4.12 to 9.4.13. We are using the jetty-maven-plugin to launch our applications.

Here's a minimal example with this regression: https://github.com/KingBuzzer/jetty-regression/
1) clone and do: mvn jetty:run - that works
2) git checkout no-worky and do: mvn jetty:run - see the error above.

Needs JDK10 to compile.

Here's a minimal example with this regression: https://github.com/KingBuzzer/jetty-regression/

  1. clone and do: mvn jetty:run - that works
  2. git checkout no-worky and do: mvn jetty:run - see the error above.

Needs JDK10 to compile.

Thanks KingBuzzer for sample project.

Yes, looks like there is a problem in the initialization sequence - we did make a change there for this release, but all regression tests were passing. I will look into it.

Also, although its not the cause of the problem, you know you're using javax.servlet 4 and jetty-9.x series is designed for the javax.servlet 3, right?

Thanks! Yes I just copied some code from our real app which is using tomcat-9 & servlet 4, but the dependency is in provided scope so should not do any harm here.

Found the problem, see PR #3101

@mymbrooks @KingBuzzer thanks for the bug report and the reproduction webapp.

Found and fixed the bug.

Standby for release 9.4.14 (I knew 13 was an unlucky number!).

Was this page helpful?
0 / 5 - 0 ratings