'How to build a WAR file with gradle?

I want to build a WAR file (and then deploy it to Tomcat). So, as an exercise, I've started a new Spring Boot Project using Gradle in IDEA IntelliJ. Afterwards, I've apply the plugin in the build.gradle file, like this apply plugin: 'war' .

The problem is that when I try to run gradle war in the terminal, I get no war file! The only thing that happens is that it will generate a \build with 3 subsolders classes, resources and tmp, but there's no WAR in these.

What should I do to get a WAR file? I've watched this video, but this guy uses Maven and doesn't do advanced stuff and gets the war. I think there's got to be a way to keep it simple.

When I run gradle war --info

Initialized native services in: C:\Users\...\.gradle\native The client 

...

Task :compileJava UP-TO-DATE Resolving global dependency management for project 'deleteme' Excluding [org.apache.tomcat:tomcat-annotations-api] Excluding [] Skipping task ':compileJava' as it is up-to-date. :compileJava (Thread[Task worker for ':',5,main]) completed. Took 0.753 secs. :processResources (Thread[Task worker for ':',5,main]) started.

Task :processResources UP-TO-DATE Skipping task ':processResources' as it is up-to-date. :processResources (Thread[Task worker for ':',5,main]) completed. Took 0.003 secs. :classes (Thread[Task worker for ':',5,main]) started.

Task :classes UP-TO-DATE Skipping task ':classes' as it has no actions. :classes (Thread[Task worker for ':',5,main]) completed. Took 0.0 secs. :war (Thread[Task worker for ':',5,main]) started.

Task :war SKIPPED Skipping task ':war' as task onlyIf is false. :war (Thread[Task worker for ':',5,main]) completed. Took 0.0 secs.



Solution 1:[1]

I guess that you have applied the spring boot gradle plugin to your project, in addition to the war plugin ? then this behaviour is normal, since the Spring Boot plugin will disable jar and war tasks and replace these with bootWar and bootJar tasks .

With both spring boot and war plugin applied:

./gradlew war
15:35:09: Executing task 'war'...

> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE
> Task :war SKIPPED

BUILD SUCCESSFUL in 0s
2 actionable tasks: 2 up-to-date
15:35:10: Task execution finished 'war'.

Note the SKIPPED message

$ ./gradlew bootWar
15:36:35: Executing task 'bootWar'...

> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE
> Task :bootWar

BUILD SUCCESSFUL in 1s
3 actionable tasks: 1 executed, 2 up-to-date
15:36:37: Task execution finished 'bootWar'.

Then you will get the expected war file under build/libs.

You can still re-enable the standard jar/war tasks as explained here : https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/#packaging-executable-wars-deployable (if you need to produce normal archives and not executable archives)

Regarding the Tomcat issue: install Tomcat 8.5.

Solution 2:[2]

As rightly said by @M.Ricciuti, the spring boot gradle plugin will disable the jar/war tasks and would only work with bootJar/bootWar tasks. But if you still want your project to be packaged with jar/war tasks just add the below to your build.gradle file

war {
    enabled=true
}

This would enable the gradle war command to generate the war for your project.

Solution 3:[3]

Please read: https://docs.gradle.org/current/userguide/war_plugin.html

If using Gradle with IntelliJ, goto build.gradle (or build.gradle.kts for Kotlin) and add

id 'war'

(or just

war

for Kotlin ) under Plugins

Reload Gradle Project and then use gradlew bootWar on the Intellij Terminal.

Add --info or --stackTrace for debugging

Solution 4:[4]

I was also facing the same issue.

After a lot of struggle, I figured out that I needed to extend SpringBootServletInitializer in my application. So my effective code looks like

    public class SyncApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(SyncApplication.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(SyncApplication.class, args);
    }

}

Looks like this SpringBootServletInitializer directs war plugins generate bootstrapping code while building the war, and thus spring context is initialized while deploying the app.

Solution 5:[5]

If you are using spring boot with gradle, you should follow the steps below:

  1. Edit your build.gradle file adding apply plugin:'war' and then rebuild gradle.

  2. With gradle built two (2) files will be created on your root directory: gradlew (for Linux) and gradlew.bat (for windows)

Open your terminal on your current project and run ./gradlew war

Your project will build and generate a .war file in build/libs/

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 MTZ
Solution 2 Madhu Bhat
Solution 3 Nishant
Solution 4 Anand Vaidya
Solution 5 Stephen Ostermiller