13

So I am building a spring boot web application, packaging as a war, and deploying to a tomcat application server.

I have the following dependency in my pom.xml for tomcat:

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

The scope of this dependency needs to be provided in order to be able to deploy it to a tomcat instance. However, when I want to run the war via the spring boot CLI or via IntelliJ's default spring boot run configuration, I need to remove the <scope>provided</scope> in order for it to run the embedded tomcat.

My question is, is there some way to make the dependency conditionally provided based on an active spring profile, or some other method?

Andrew Mairose
  • 10,615
  • 12
  • 60
  • 102
  • The last time I tried (about 3 months ago) I could deploy my war to a tomcat, even with an embedded-tomcat contained within it. It worked fine. The war was just a little bigger than it should have been! Unsure if that approach still works in latest versions of spring-boot though. – David Lavender Feb 17 '17 at 13:41
  • 2
    Don't... No Really don't... Leave it as provided and use the maven spring boot task to run your application from within Intellij. Also when running the war there should be no issue as spring packages the provided dependencies in a separate directory which are still scanned by Spring Boot. – M. Deinum Feb 17 '17 at 13:46
  • @M.Deinum you should post that as an answer - that works for me – Andrew Mairose Feb 17 '17 at 18:23

3 Answers3

9

In your specific case, you can just do : In the dependencies to run spring-boot with embedded tomcat :

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

And in a profile to deploy under tomcat

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

After, to build for a specific profile

mvn clean install -Ptomcat
6

You can't control dependencies via spring profiles. However you can control spring profiles by maven profiles and it can solve your problem.

You can declare several maven profiles in your application and provide different set of dependencies for each of them. Then you can configure maven profiles to use particular spring profile. Take a look on maven profiles and an example of such configuration in this thread

Community
  • 1
  • 1
Sasha Shpota
  • 9,436
  • 14
  • 75
  • 148
3

This is a solution that will work with both, jar and war packaging:

pom.xml

    ...
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.4.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <artifactId>...</artifactId>
    <groupId>...</groupId>
    <version>0-SNAPSHOT</version>
    <packaging>${packaging.type}</packaging>
    ...
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <start-class>...</start-class>
        <packaging.type>jar</packaging.type>
    ...
    </properties>
    <dependencies>
        <dependency>
            <!-- Brings in Embedded Tomcat dependencies -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
...
    </dependencies>

    <profiles>
        <profile>
            <id>tomcat-war</id>
            <properties>
                <packaging.type>war</packaging.type>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                    <scope>provided</scope>
                </dependency>
            </dependencies>
    ...
    </profiles>

    <build>
            <finalName>${project.artifactId}</finalName>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
    ...

Build artifact as jar:

mvn clean package

Build artifact as war:

mvn clean package -Ptomcat-war

Main class, that goes in <start-class> in pom.xml:

package ...

public class Application extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(Application.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
ootero
  • 3,235
  • 2
  • 16
  • 22