How do I automatically run a custom task before gradle build in build.gradle
Gradle multi-module project build fails with an unclear error. I run this command:
gradle :module:processor:integrationTest
(module:processor depends on module:processor-core, integrationTest is a custom Gradle task for running tests. I'm using kapt plugin as an annotation processor for Spring Boot configuration properties)
And I get this result:
> Task :module:processor-core:kaptGenerateStubsKotlin UP-TO-DATE
> Task :module:processor-core:kaptKotlin UP-TO-DATE
...
> Task :module:processor-core:jar SKIPPED
> Task :module:processor:kaptGenerateStubsKotlin
> Task :module:processor:kaptKotlin FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':module:processor:kaptKotlin'.
> Could not resolve all files for configuration ':module:processor:_classStructurekaptKotlin'.
> Failed to transform processor-core-SNAPSHOT.jar to match attributes {artifactType=class-structure, org.gradle.libraryelements=jar, org.gradle.usage=java-runtime}.
> Execution failed for StructureTransformAction: D:\dev\backend-project\module\processor-core\build\libs\processor-core-SNAPSHOT.jar.
> D:\dev\backend-project\module\processor-core\build\libs\processor-core-SNAPSHOT.jar (The system cannot find the path specified)
I don't understand why.
it was fixed by adding the following code to the build.gradle of processor-core module:
jar {
archiveBaseName = 'processor-core'
}
without these lines, I guess this step is disabled by Spring Boot, so the JAR file was not produced, and this led to the error.
I just upgraded my Grails web-app from version 3.2 to 4.0.
I have a provided dependency in build.gradle (fairly common configuration):
dependencies {
...
compile "org.springframework.boot:spring-boot-starter-logging"
compile "org.springframework.boot:spring-boot-autoconfigure"
compile "org.springframework.boot:spring-boot-starter-actuator"
provided "org.springframework.boot:spring-boot-starter-tomcat"
...
}
I’ve just noticed that by executing Gradle assemble task I don’t get the myApp.war.original archive anymore (which used to be build without all provided libs), but only the one including provided dependencies.
Am I missing something here? I'd really like to spare those ~4MB of jars in lib-provided folder.
Thanks in advance!
Update 1
Following #ck1's advice i changed provided dependency to providedCompile, but the result is the same.
Though I already use the war plugin, I noticed that the sequence of tasks initiated by assemble task is:
> Task :assetCompile
Finished Precompiling Assets
> Task :compileJava
> Task :compileGroovy
> Task :buildProperties
> Task :processResources
> Task :classes
> Task :compileWebappGroovyPages NO-SOURCE
> Task :compileGroovyPages
> Task :compileGsonViews
> Task :findMainClass
> Task :bootWar
> Task :war SKIPPED
> Task :assemble
So the war task is skipped in favor of the new bootWar task (not available in Gradle 3, used by Grails 3).
Any way to force it? Or is it something the plugin should already support?
Update 2
After some research, I added to build.gradle
war {
enabled = true
}
and was able to get the war task to execute:
> Task :assetCompile
Finished Precompiling Assets
> Task :compileJava
> Task :compileGroovy
> Task :buildProperties
> Task :processResources
> Task :classes
> Task :compileWebappGroovyPages NO-SOURCE
> Task :compileGroovyPages
> Task :compileGsonViews
> Task :findMainClass
> Task :bootWar
> Task :war // not skipped
> Task :assemble
I basically got to where I wanted to, i.e. get a .war archive without all the provided dependencies; differently from before though, not a pair of .war archives (myApp.war and myApp.war.original) but a single one named myApp.war not including the unneeded stuff.
But I'm still pretty much confused, as
Spring Boot's Gradle plugin documentation states bootWar is an extension of war.
The bootRepackage task has been replaced with bootJar and bootWar tasks for building executable jars and wars respectively. Both tasks extend their equivalent standard Gradle jar or war task, giving you access to all of the usual configuration options and behaviour.
But then Spring Boot 2.0 Migration Guide states war task is expected to be skipped:
The bootRepackage task has been replaced with bootJar and bootWar tasks for building executable jars and wars respectively. The jar and war tasks are no longer involved.
So again, what am I missing out?
You should replace provided with either the providedCompile or providedRuntime dependency configuration from the war plugin.
These two configurations have the same scope as the respective compile
and runtime configurations, except that they are not added to the WAR
archive.
Reference:
https://docs.gradle.org/4.10.2/userguide/war_plugin.html
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.
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.
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
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.
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.
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) 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/
Without Gradle War Plugin, bootRepackage task depends on jar task but with Gradle War Plugin, it depends on war task.
How can I change it to depend on jar task even though I'm using Gradle War Plugin?
UPDATE:
I'm using war task to create a war file including documents to be deployed to a documentation server and I want to use bootRepackaged jar file to provide a service. My war task depends on asciidoctor task which depends on test task (I'm using Spring REST Docs.) but I don't want to run asciidoctor task or test task when using bootRepackage task.
I solved my problem with the following setup:
ext {
mainClassName = 'com.izeye.throwaway.Application'
}
task myBootRepackage(type: BootRepackage, dependsOn: jar) {
}
but I'm not sure this is a good practice.
This is a sample project having the above configuration:
https://github.com/izeye/spring-boot-throwaway-branches/tree/war
You should have been able to do this:
bootRepackage {
withJarTask jar
}
While this correctly causes the jar task's jar to be repackaged, it doesn't remove the dependency on the war task. This is another symptom of this Spring Boot issue.
Until this issue has been resolved, the approach that you've taken – declaring your own BootRepackage task and manually configuring the tasks that it depends upon – is your best option.