30

I want to create a war file without embedded tomcat with maven. Here the relevant part of my pom

... <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.1.6.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- Add tomcat only if I want to run directly --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> ... 

How ever if I run mvn package I get a war, where the tomcat*.jar are in a provided-lib folder but still in the lib-folder. I read build-tool-plugins-maven-packaging, but can't find what's wrong.

I know a main idea is to run it as an application, how ever our customer want's to deploy it on his application-server.

3
  • 1
    The fact that the jars are still there doesn't mean you cannot deploy it as a war. You can perfectly deploy it as is. Make sure that you exclude tomcat from the spring-boot-starter-web dependency. Commented Sep 23, 2014 at 9:45
  • 1
    @niels, you edited this question, and since revision 2 it includes the answer to your question. What about reverting to your initial answer and providing a separate answer? Commented Oct 26, 2014 at 23:48
  • @Abdull good idea. It makes it more clear. Commented Oct 27, 2014 at 13:32

5 Answers 5

35

Following the Hint from M. Deinum I excluded the tomcat-depedency.

With the following pom.xml (relevant snippet) a maven clean package has the result I want to get.

... <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.1.6.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- Add tomcat only if I want to run directly --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> ... 

Warning for idea-user: You must activate "Include dependencies with the provided scope" in the run-configuration (see Unable to start spring-boot application in IntelliJ Idea for more information)

Sign up to request clarification or add additional context in comments.

5 Comments

But if the spring-boot-starter-tomcat is commented out, how do you run the app? I tried it this way, and deployed it to a tomcat container, but got error messages then. All similar to: org.apache.catalina.startup.ContextConfig checkHandlesTypes WARNING: Unable to load class [org.apache.tomcat.util.descriptor.web.NameRule] to check against the @HandlesTypes annotation of one or more ServletContentInitializers. java.lang.ClassNotFoundException: org.apache.tomcat.util.descriptor.web.NameRule etc.
You can deploy the war in an arbitrary servlet-container. If your application doesn't need tomcat classes it works fine this way. Is it possible that you need at compile-time the tomcat-classes? How do you compile? mvn from commandline? Make sure you make a mvn clean at the beginning.
I use gradle, I already figured it out though. The build process (bootRepackage) produces two artifacts, one with and one without the embedded Tomcat container. Turned out I took the wrong artifact for the external Tomcat deployment - should take the war without the embedded Tomcat then.
When i run my application with above suggestion, it gives me error "Unregistering JMX-exposed beans on shutdown"
@Tatkal I Think it's difficult, to give you help with so less information. I can only guess that you have configured JMX at the logback config. I would recommend to open a new question with detailed information. Have you checked twice that the error only happens if you make the adjustments in pom.xml?
13

I'm not sure if that's the spring-boot way of doing it, but you can exclude the tomcat jars using the maven-war-plugin configuration. That is, add the following to your pom.xml:

<build> <plugins> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.4</version> <configuration> <packagingExcludes>WEB-INF/lib/tomcat-*.jar</packagingExcludes> </configuration> </plugin> </plugins> </build> 

Using this approach, the war generated is not executable (cannot be run on command line using java -jar ) but can only be deployed to any servlet container

Comments

5

I had this same need but removing the mentioned dependency didn't worked. I was able to get the WAR file by adding this <packaging>war</packaging> dependency to my pom file.

I used this Spring article as a guide... sharing so this may help other people as well.

Comments

5

Changing spring-boot-starter dependency from

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

To this one will exclude the embedded tomcat server.

 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> 

Comments

2

I think that the easiest way to build a final WAR from your existing Spring Boot project without embedded Tomcat is the following:

1) Set WARpackaging for your artifact: <packaging>war</packaging>

2) Set the Tomcat Server dependency to provide:

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

If some of your existing Spring Boot dependencies contain it by default, just exclude it. Example:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> 

That is it.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.