26
votes

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.

5
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.M. Deinum
@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?Abdull
@Abdull good idea. It makes it more clear.niels

5 Answers

33
votes

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)

11
votes

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

5
votes

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.

5
votes

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>
1
votes

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.