'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:
Edit your build.gradle file adding
apply plugin:'war'
and then rebuild gradle.With gradle built two (2) files will be created on your root directory:
gradlew
(for Linux) andgradlew.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 |