Grails 4 - Gradle 'assemble' task not generating .war.original archive - gradle

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

Related

Gradle features were used in this build, making it incompatible with Gradle 7.0

This is my spring boot project. When I going to run gradle task in spring tool suit I can get error like below. I am new to sprint boot can anyone help me. I used java 11 and gradle version 6.8.3
Gradle Distribution: Specific Gradle version 6.8.3
Gradle Version: 6.8.3
Java Home: /usr/lib/jvm/java-11-openjdk-amd64
JVM Arguments: None
Program Arguments: None
Build Scans Enabled: false
Offline Mode Enabled: false
Gradle Tasks: clean build
> Task :clean
> Task :compileJava
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
> Task :processResources
> Task :classes
> Task :bootJarMainClassName
> Task :bootJar
> Task :jar SKIPPED
> Task :assemble
> Task :compileTestJava NO-SOURCE
> Task :processTestResources NO-SOURCE
> Task :testClasses UP-TO-DATE
> Task :test NO-SOURCE
> Task :check UP-TO-DATE
> Task :build
Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.8.3/userguide/command_line_interface.html#sec:command_line_warnings
You can use ./gradlew build --warning-mode all to find out deprecated features.
For example
This problem can be for several reasons, To avoid going into so much explanation If the application worked at some point
Delete de app in the device and run yarn android or npm android
or
Delete de build folder and delete the app in the device and run yarn android or npm android
That's works for me

gradle: Task :jar SKIPPED while I get my jar with gradlew build

My Question is: Why does the jar-creation work with gradlew build, while I see "Task :jar SKIPPED" when I click on jar in intellij's gradle window ? And how can I fix it in IntelliJ ?
Just created something with spring initializer and loaded the project in intellij as it is.
( it is org.springframework.boot, .. 'org.springframework.boot:spring-boot-starter-web')
I wonder about Task :jar SKIPPED ( nor jar created )
and than I discovered that I get the jar when I start from console.
( and the jar runs fine, it finds the main class - even without jar manifest attribute in build.gradle)
( yesterday I failed in maven with "no main manifest attribute in .... .jar )
This is because Springboot Gradle plugin will create a bootJar task and by default will disable jar and war tasks, as described here: https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/#packaging-executable-and-normal
So you need to execute bootJar task , from the IDE. When executing gradlew build, the tasks bootJar gets automatically executed, due to tasks dependencies created by the plugin.
When running task build (from console or IDE), you can see the tasks executed by Gradle depending on tasks dependencies, e.g.:
> Task :backend:compileJava
> Task :backend:processResources
> Task :backend:classes
> Task :backend:bootJar ## <== this is the task register by Springboot plugin, which produces the "Fat/executable" jar
> Task :backend:jar SKIPPED ## <== task disabled by Springboot plugin
> Task :backend:assemble
> Task :backend:processTestResources
> Task :backend:testClasses
> Task :backend:test
> Task :backend:check
> Task :backend:build
For your remark
the jar runs fine, it finds the main class - even without jar manifest
attribute in build.gradle
The Springboot plugin will automatically configure this for you, see : https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/#packaging-executable-configuring-main-class
EDIT 27-05-2021
Starting from Springboot 2.5, the jaris not disabled by default anymore. see more details in release notes here
You can enble this, with add code below in projectName.gradle
it works for me :
spring-boot : 2.0.8.RELEASE
Gradle : 4.5 or >
jar {
baseName = 'projectName'
enabled=true
manifest {
....
}
}

Gradle build doesn't generate jar

I would like to build my project as a jar file which only contains my code. This project jar is used as a library to other java project.
Here is my build.gradle:
plugins {
id 'java'
}
group 'com.my.lib'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
task sourcesJar(type: Jar) {
archiveClassifier = 'sources'
from sourceSets.main.allJava
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}
After I build the project (I am using IntelliJ, I clicked "Build" ==> "Rebuild project"). IntelliJ told me build successfully But I don't see any jar created. Why?
18:30:18: Executing tasks ':classes :testClasses'...
> Task :compileJava
> Task :processResources NO-SOURCE
> Task :classes
> Task :compileTestJava
> Task :processTestResources NO-SOURCE
> Task :testClasses
BUILD SUCCESSFUL in 0s
2 actionable tasks: 2 executed
18:30:18: Tasks execution finished ':classes :testClasses'.
I figured out that even I have those settings, when I choose Build->Build project, Intellij still not run Gradle build that's why in my original question there is no "sourceJar" showing. I have to open "Gradle tool" window, click on that little elephant icon to run gradle task. Then, type "Gradle build", it then run the source Jar task.
The "Build Project" form IntelliJ IDEA will compile your code for usage in the IDE, it is not directly tied to the build lifecycle task of Gradle.
For Gradle to build the JAR, you need to run ./gradlew assemble, which will have the expected outcome.
Note that this will not run tests or static analysis. If you want that to run as well, you can use ./gradlew build.
Both of these Gradle tasks can be executed from the Gradle tool window in IntelliJ IDEA.
Open the project in your file system and you might find it under the build/libs/.. folder

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.
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/

Handle gradle tasks dependencies

Using gradle with its spring-boot plugin (1.5.1) and a first spirit plugin together raises an error:
D:\Coden\WS\STS\fs-db-import>gradle build
:genJaxb
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar UP-TO-DATE
:fsm UP-TO-DATE
:bootRepackage FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':bootRepackage'.
> Unable to deduce layout for 'D:\Coden\WS\STS\fs-db-import\build\fsm\fs-db-import-0.0.1.fsm'
It seems that bootRepackage from the spring boot plugin can't handle or package the fsm file.
a) how can I exclude it?
Another approach would be to switch the 'fsm' and the 'bootRepackage' task, but adding the following lines to build.gradle
bootRepackage.dependsOn -= fsm
tasks.bootRepackage.dependsOn -= fsm
fsm.dependsOn bootRepackage
results in
Circular dependency between the following tasks:
:bootRepackage
\--- :fsm
\--- :bootRepackage (*)
(*) - details omitted (listed previously)
b) how do I remove 'fsm'`s dependency from 'bootRepackage'?
c) is it possible to show a gradle task dependency graph? (not project dependencies)
By default the Spring Boot plugin attempts to repackage all tasks of type Jar. Sine the FSM task extends from Jar the plugin attempts to repackage them both. You can explicitly tell the plugin which Jar task to use.
bootRepackage {
withJarTask jar
}
More information can be found in the Spring Documentation.

Resources