How do I tell Spring Boot to ignore Jetty and always use Tomcat?
Asked Answered
F

2

5

I have the following setup:

spring-boot application (using embedded tomcat)
spring-date-neo4j (embedded mode)
spring-websockets

and neo4j-browser included using (the goal is to be able to use REST and web browser to debug embedded database):

    <dependency>
        <groupId>org.neo4j.app</groupId>
        <artifactId>neo4j-server</artifactId>
        <version>${neo4j.version}</version>
        <exclusions>
            <exclusion>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
            </exclusion>
            <exclusion>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-access</artifactId>
            </exclusion>
            <exclusion>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
            </exclusion>
            <exclusion>
                <artifactId>javax.servlet</artifactId>
                <groupId>org.eclipse.jetty.orbit</groupId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.neo4j.app</groupId>
        <artifactId>neo4j-server</artifactId>
        <version>${neo4j.version}</version>
        <classifier>static-web</classifier>
        <exclusions>
            <exclusion>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
            </exclusion>
            <exclusion>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-access</artifactId>
            </exclusion>
            <exclusion>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
            </exclusion>
            <exclusion>
                <artifactId>javax.servlet</artifactId>
                <groupId>org.eclipse.jetty.orbit</groupId>
            </exclusion>
        </exclusions>
    </dependency>

And started using:

@Autowired
@Bean(destroyMethod = "shutdown")
public GraphDatabaseService graphDatabaseService(DatabaseConfiguration dbConf) {
    // removed with every maven clear
    return new GraphDatabaseFactory().newEmbeddedDatabase(dbConf.getDbPath());

    // stays after clear
    //return new EmbeddedGraphDatabase("./data/neo4j.db");
}

@Bean(destroyMethod = "stop")
public WrappingNeoServerBootstrapper serverWrapper(GraphDatabaseService db) {
    WrappingNeoServerBootstrapper wrapper = new WrappingNeoServerBootstrapper((GraphDatabaseAPI)db);
    wrapper.start();
    return wrapper;
}

And spring boot is insisting on trying Jetty as the servlet container even with the following config annotations for the main app class:

@EnableAutoConfiguration(exclude = EmbeddedServletContainerAutoConfiguration.EmbeddedJetty.class)
@ComponentScan
@EnableWebMvc
@Configuration
public class WebApplication extends WebMvcConfigurerAdapter {

But the jetty version Spring uses (8) does not support web sockets so I am getting

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean
with name 'jettyEmbeddedServletContainerFactory' defined in class path resource 
[org/springframework/boot/autoconfigure/web/EmbeddedServletContainerAutoConfiguration$EmbeddedJetty.class]:
Initialization of bean failed; nested exception is java.lang.IllegalStateException:
Websockets are currently only supported in Tomcat (found class org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory).

How do I tell Spring Boot to ignore Jetty and always use Tomcat?

The dependency tree:

[INFO] Building webapp 1.0
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ webapp ---
[INFO] webapp:war:1.0
[INFO] +- common:jar:1.0:compile
[INFO] |  +- javax.validation:validation-api:jar:1.1.0.Final:compile
[INFO] |  +- org.springframework.data:spring-data-neo4j:jar:3.1.0.RELEASE:compile
[INFO] |  |  +- org.aspectj:aspectjrt:jar:1.7.4:compile
[INFO] |  |  +- org.springframework.data:spring-data-commons:jar:1.8.0.RELEASE:compile
[INFO] |  |  +- org.neo4j:neo4j-cypher-dsl:jar:2.0.1:compile
[INFO] |  |  +- org.neo4j:neo4j:jar:2.0.3:compile
[INFO] |  |  +- org.slf4j:slf4j-api:jar:1.7.7:compile
[INFO] |  |  \- org.slf4j:jcl-over-slf4j:jar:1.7.7:compile
[INFO] |  +- commons-codec:commons-codec:jar:1.9:compile
[INFO] |  +- org.apache.poi:poi:jar:3.10-FINAL:compile
[INFO] |  +- org.apache.poi:poi-scratchpad:jar:3.10-FINAL:compile
[INFO] |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.3.3:compile
[INFO] |  \- com.fasterxml.jackson.core:jackson-databind:jar:2.3.3:compile
[INFO] |     \- com.fasterxml.jackson.core:jackson-core:jar:2.3.3:compile
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:1.0.2.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:1.0.2.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot:jar:1.0.2.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:1.0.2.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:1.0.2.RELEASE:compile
[INFO] |  |  |  +- org.slf4j:jul-to-slf4j:jar:1.7.7:compile
[INFO] |  |  |  +- org.slf4j:log4j-over-slf4j:jar:1.7.7:compile
[INFO] |  |  |  \- ch.qos.logback:logback-classic:jar:1.1.2:compile
[INFO] |  |  |     \- ch.qos.logback:logback-core:jar:1.1.2:compile
[INFO] |  |  \- org.yaml:snakeyaml:jar:1.13:runtime
[INFO] |  \- org.springframework.boot:spring-boot-starter-tomcat:jar:1.0.2.RELEASE:compile
[INFO] |     +- org.apache.tomcat.embed:tomcat-embed-el:jar:7.0.52:compile
[INFO] |     \- org.apache.tomcat.embed:tomcat-embed-logging-juli:jar:7.0.52:compile
[INFO] +- org.springframework:spring-core:jar:4.0.3.RELEASE:compile
[INFO] +- org.springframework:spring-context:jar:4.0.3.RELEASE:compile
[INFO] |  \- org.springframework:spring-expression:jar:4.0.3.RELEASE:compile
[INFO] +- org.springframework:spring-beans:jar:4.0.3.RELEASE:compile
[INFO] +- org.springframework.security:spring-security-web:jar:3.2.4.RELEASE:compile
[INFO] |  +- aopalliance:aopalliance:jar:1.0:compile
[INFO] |  \- org.springframework.security:spring-security-core:jar:3.2.3.RELEASE:compile
[INFO] +- org.springframework.security:spring-security-config:jar:3.2.4.RELEASE:compile
[INFO] +- org.springframework.security:spring-security-taglibs:jar:3.2.4.RELEASE:compile
[INFO] |  \- org.springframework.security:spring-security-acl:jar:3.2.3.RELEASE:compile
[INFO] |     \- org.springframework:spring-jdbc:jar:4.0.3.RELEASE:compile
[INFO] +- org.springframework:spring-webmvc:jar:4.0.3.RELEASE:compile
[INFO] +- org.springframework:spring-web:jar:4.0.3.RELEASE:compile
[INFO] +- org.springframework:spring-websocket:jar:4.0.3.RELEASE:compile
[INFO] +- org.springframework:spring-messaging:jar:4.0.3.RELEASE:compile
[INFO] +- org.apache.tomcat.embed:tomcat-embed-websocket:jar:7.0.52:compile
[INFO] |  \- org.apache.tomcat.embed:tomcat-embed-core:jar:7.0.52:compile
[INFO] +- org.freemarker:freemarker:jar:2.3.20:compile
[INFO] +- org.springframework:spring-context-support:jar:4.0.3.RELEASE:compile
[INFO] +- net.glxn:qrgen:jar:1.4:compile
[INFO] |  \- com.google.zxing:javase:jar:3.0.0:compile
[INFO] |     \- com.google.zxing:core:jar:3.0.0:compile
[INFO] +- org.springframework:spring-tx:jar:4.0.3.RELEASE:compile
[INFO] +- org.springframework:spring-aop:jar:4.0.3.RELEASE:compile
[INFO] +- org.springframework:spring-aspects:jar:4.0.3.RELEASE:compile
[INFO] |  \- org.aspectj:aspectjweaver:jar:1.7.4:compile
[INFO] +- org.hibernate:hibernate-validator:jar:5.1.1.Final:compile
[INFO] |  +- org.jboss.logging:jboss-logging:jar:3.1.3.GA:compile
[INFO] |  \- com.fasterxml:classmate:jar:1.0.0:compile
[INFO] +- javax.el:javax.el-api:jar:2.2.4:compile
[INFO] +- org.glassfish.web:javax.el:jar:2.2.4:compile
[INFO] +- org.apache.commons:commons-lang3:jar:3.3.2:compile
[INFO] +- commons-io:commons-io:jar:2.4:compile
[INFO] +- commons-fileupload:commons-fileupload:jar:1.3.1:compile
[INFO] +- org.jsoup:jsoup:jar:1.7.3:compile
[INFO] +- com.sun.jersey:jersey-server:jar:1.18:compile
[INFO] |  +- asm:asm:jar:3.1:compile
[INFO] |  \- com.sun.jersey:jersey-core:jar:1.18:compile
[INFO] +- com.sun.jersey:jersey-servlet:jar:1.18:compile
[INFO] +- org.neo4j.app:neo4j-server:jar:2.0.3:compile
[INFO] |  +- org.neo4j:neo4j:pom:2.0.3:compile
[INFO] |  |  +- org.neo4j:neo4j-lucene-index:jar:2.0.3:compile
[INFO] |  |  |  \- org.apache.lucene:lucene-core:jar:3.6.2:compile
[INFO] |  |  +- org.neo4j:neo4j-graph-algo:jar:2.0.3:compile
[INFO] |  |  +- org.neo4j:neo4j-udc:jar:2.0.3:compile
[INFO] |  |  +- org.neo4j:neo4j-graph-matching:jar:2.0.3:compile
[INFO] |  |  \- org.neo4j:neo4j-jmx:jar:2.0.3:compile
[INFO] |  +- org.neo4j:neo4j-kernel:jar:2.0.3:compile
[INFO] |  |  \- org.apache.geronimo.specs:geronimo-jta_1.1_spec:jar:1.1.1:compile
[INFO] |  +- org.neo4j:server-api:jar:2.0.3:compile
[INFO] |  |  \- org.neo4j.3rdparty.javax.ws.rs:jsr311-api:jar:1.1.2.r612:compile
[INFO] |  +- org.neo4j:neo4j-cypher:jar:2.0.3:compile
[INFO] |  |  +- org.neo4j:neo4j-cypher-commons:jar:2.0.3:compile
[INFO] |  |  +- org.neo4j:neo4j-cypher-compiler-1.9:jar:2.0.3:compile
[INFO] |  |  +- org.neo4j:neo4j-cypher-compiler-2.0:jar:2.0.3:compile
[INFO] |  |  |  +- org.parboiled:parboiled-scala_2.10:jar:1.1.6:compile
[INFO] |  |  |  |  \- org.parboiled:parboiled-core:jar:1.1.6:compile
[INFO] |  |  |  \- net.sf.opencsv:opencsv:jar:2.0:compile
[INFO] |  |  +- com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:jar:1.3.1:compile
[INFO] |  |  \- org.scala-lang:scala-library:jar:2.10.3:compile
[INFO] |  +- org.neo4j.app:neo4j-browser:jar:2.0.3:compile
[INFO] |  +- org.codehaus.janino:janino:jar:2.6.1:compile
[INFO] |  |  \- org.codehaus.janino:commons-compiler:jar:2.6.1:compile
[INFO] |  +- org.eclipse.jetty:jetty-server:jar:9.0.5.v20130815:compile
[INFO] |  |  +- org.eclipse.jetty:jetty-http:jar:9.0.5.v20130815:compile
[INFO] |  |  \- org.eclipse.jetty:jetty-io:jar:9.0.5.v20130815:compile
[INFO] |  +- org.eclipse.jetty:jetty-webapp:jar:8.1.14.v20131031:compile
[INFO] |  |  +- org.eclipse.jetty:jetty-xml:jar:8.1.14.v20131031:compile
[INFO] |  |  \- org.eclipse.jetty:jetty-servlet:jar:8.1.14.v20131031:compile
[INFO] |  |     \- org.eclipse.jetty:jetty-security:jar:8.1.14.v20131031:compile
[INFO] |  +- commons-configuration:commons-configuration:jar:1.6:compile
[INFO] |  |  +- commons-collections:commons-collections:jar:3.2.1:compile
[INFO] |  |  +- commons-lang:commons-lang:jar:2.4:compile
[INFO] |  |  +- commons-logging:commons-logging:jar:1.1.1:compile
[INFO] |  |  \- commons-beanutils:commons-beanutils-core:jar:1.8.0:compile
[INFO] |  +- commons-digester:commons-digester:jar:1.8.1:compile
[INFO] |  |  \- commons-beanutils:commons-beanutils:jar:1.8.0:compile
[INFO] |  +- org.codehaus.jackson:jackson-jaxrs:jar:1.9.7:compile
[INFO] |  |  +- org.codehaus.jackson:jackson-core-asl:jar:1.9.7:compile
[INFO] |  |  \- org.codehaus.jackson:jackson-mapper-asl:jar:1.9.7:compile
[INFO] |  +- org.rrd4j:rrd4j:jar:2.0.7:compile
[INFO] |  +- org.mozilla:rhino:jar:1.7R4:compile
[INFO] |  +- bouncycastle:bcprov-jdk16:jar:140:compile
[INFO] |  +- com.sun.jersey.contribs:jersey-multipart:jar:1.9:compile
[INFO] |  |  \- org.jvnet:mimepull:jar:1.6:compile
[INFO] |  \- org.neo4j:neo4j-shell:jar:2.0.3:compile
[INFO] |     \- org.apache.servicemix.bundles:org.apache.servicemix.bundles.jline:jar:0.9.94_1:compile
[INFO] +- org.neo4j.app:neo4j-server:jar:static-web:2.0.3:compile
[INFO] +- org.eclipse.jetty:jetty-util:jar:9.0.7.v20131107:compile
[INFO] +- com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:jar:r239:compile
[INFO] |  +- com.google.guava:guava:jar:17.0:compile (version selected from constraint [11.0,))
[INFO] |  \- com.google.code.findbugs:jsr305:jar:3.0.0:compile (version selected from constraint [1.3.9,))
[INFO] +- junit:junit:jar:4.11:test
[INFO] |  \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] +- org.mockito:mockito-all:jar:1.9.5:test
[INFO] +- org.springframework:spring-test:jar:4.0.3.RELEASE:test
[INFO] +- org.mockito:mockito-core:jar:1.9.5:test
[INFO] |  \- org.objenesis:objenesis:jar:1.0:test
[INFO] \- org.hamcrest:hamcrest-library:jar:1.3:test
Flume answered 21/7, 2014 at 13:57 Comment(0)
J
14

Boot's using Jetty as it's on the classpath. The attempt to exclude it by excluding EmbeddedServletContainerAutoConfiguration.EmbeddedJetty.class doesn't work as EmdeddedJetty isn't an auto-configuration class. EmbeddedServletContainerAutoConfiguration is an auto-configuration class and you could exclude it, but then you'd also lose embedded Tomcat support which I don't think is what you want. The easiest thing to do is to eliminate Jetty from your application's classpath.

The dependency tree output shows that you've still got transitive dependencies on org.eclipse.jetty:jetty-server and org.eclipse.jetty:jetty-webapp, both of which are being pulled in by your direct dependency on org.neo4j.app:neo4j-server. Update your pom to exclude them:

<dependency>
    <groupId>org.neo4j.app</groupId>
    <artifactId>neo4j-server</artifactId>
    <version>${neo4j.version}</version>
    <classifier>static-web</classifier>
    <exclusions>
        <exclusion>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
        </exclusion>
        <exclusion>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-access</artifactId>
        </exclusion>
        <exclusion>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
        </exclusion>
        <exclusion>
            <artifactId>javax.servlet</artifactId>
            <groupId>org.eclipse.jetty.orbit</groupId>
        </exclusion>
        <exclusion>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-webapp</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Update: if excluding Jetty from the dependencies isn't an option, then you can declare your own TomcatEmbeddedServletContainerFactory bean:

@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
    return new TomcatEmbeddedServletContainerFactory();
}

This will prevent the auto-configuration of the embedded Jetty server as it's conditional on there being no EmbeddedServletContainerFactory bean in the application context.

Jard answered 21/7, 2014 at 16:48 Comment(3)
Except that is exactly what I can't do, because neo4j-server starts an embedded Jetty server.Flume
That wasn't clear to me from your question. I've updated my answer with an alternative approach.Jard
Thanks Andy, that's a life saver: I had that same problem with a conflict between activemq-http's jetty and spring-boot-starter-web :)Peipeiffer
R
2

You could also import the EmbeddedTomcat configuration directly. Has the same effect as declaring TomcatEmbeddedServletContainerFactory directly and should there be any change with it you won't need to update anything.

@SpringBootApplication
@Import(EmbeddedServletContainerAutoConfiguration.EmbeddedTomcat.class)
... your configuration class
Rocket answered 13/11, 2017 at 19:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.