How do I tell Spring Boot to ignore Jetty and always use Tomcat?
Solution 1
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.
Solution 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
MarSik
Updated on June 08, 2022Comments
-
MarSik about 2 years
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
-
MarSik almost 10 yearsExcept that is exactly what I can't do, because neo4j-server starts an embedded Jetty server.
-
Andy Wilkinson almost 10 yearsThat wasn't clear to me from your question. I've updated my answer with an alternative approach.
-
mrlem over 9 yearsThanks Andy, that's a life saver: I had that same problem with a conflict between activemq-http's jetty and spring-boot-starter-web :)