Handle gradle tasks dependencies - gradle

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.

Related

Could not resolve all files for configuration `_classStructurekaptKotlin` caused by Execution failed for `StructureTransformAction`

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.

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

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

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/

Disable check for using 'kotlin' package in Gradle

When I try to gradlew build my project, I receive an error message from the compileKotlin task:
F:\IdeaProjects\walp.tinykotlintest>gradlew build
:compileKotlin
...
Only the Kotlin standard library is allowed to use the 'kotlin' package
...
BUILD FAILED
Total time: 6.214 secs
This happens because I've declared a class in a package that starts with: kotlin...
Is there a way to dissable this check by configuring my build.gradle script?
EDIT: I know for sure this is possible if I compile with the bare kotlin compiler...here is an example of using the kotlin compiler to compile a class in the kotlin package...So I think there should to be a way to do it in gradle too!....I hope...
What I've tried so far:
I tried to configure the gradle.build by configuring the KotlinCompile task:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
tasks.withType(KotlinCompile) {
it.kotlinOptions.allowKotlinPackage = true
}
The gradle script runs fine with these changes...but it seems like this is getting ignored...and I still encounter the error.
I tried to subclass the KotlinCompile class and override its beforeCompileHook() and replace the existing compileKotlin task with my version:
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
class MyKotlinCompile extends KotlinCompile {
#Override
public void beforeCompileHook(K2JVMCompilerArguments args) {
args.allowKotlinPackage = true
throw new RuntimeException("HELLO") // added to see if hook is run
}
}
tasks.create(name: "compileKotlin", type: MyKotlinCompile, overwrite: true)
Studying the source code...I was fairly certain this would work but evidently it didn't. I tried with and without throwing the RuntimeException but I always get the following error when I tried to gradle build again:
F:\IdeaProjects\walp.tinykotlintest>gradlew build --stacktrace
:compileKotlin UP-TO-DATE
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar UP-TO-DATE
:sourcesJar UP-TO-DATE
:assemble UP-TO-DATE
:compileTestKotlin FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':compileTestKotlin'.
> java.lang.NullPointerException (no error message)
* Try:
Run with --info or --debug option to get more log output.
* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':compileTestKotlin'.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
.
.
.
at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:129)
at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:61)
Caused by: java.lang.NullPointerException
at org.jetbrains.kotlin.gradle.tasks.KotlinCompile$populateTargetSpecificArgs$2.invoke(Tasks.kt:215)
at org.jetbrains.kotlin.gradle.tasks.KotlinCompile.populateTargetSpecificArgs(Tasks.kt:222)
at org.jetbrains.kotlin.gradle.tasks.KotlinCompile.populateTargetSpecificArgs(Tasks.kt:148)
at org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile.execute(Tasks.kt:105)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:75)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.doExecute(AnnotationProcessingTaskFactory.java:243)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:219)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.execute(AnnotationProcessingTaskFactory.java:230)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:208)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
... 60 more
I probably shouldn't be doing this anyways...but I really want to try it out.
thank you!
If the Kotlin standard library is incompatible with the JVM that you're using, it sounds like what you should actually do is fork Kotlin, make the changes required for compatibility with your JVM, and then use the standard Maven build script to build your fork. The script already provides the option to allow compiling files in the kotlin package.
The error has nothing to do with Gradle. The Kotlin compiler won't compile code in a kotlin package unless you are developing the Kotlin itself.
This was done for the same reason you can't write code in a java package.

Run my task before a plugin's task?

We're using a gradle file to build a Java WAR file. I know very little about gradle. At the top of build.gradle:
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'war'
We run the gradle with gradle clean install. I'm not sure where these tasks are defined but I assume they're in one of the plugins (I'd guess war).
When I run gradle clean install it seems to print the tasks that it are run:
:clean
:compileJava
:processResources
:classes
:war
:install
Correct me if I'm wrong, but it seems that the task install dependsOn compileJava, processResources, classes, and war.
I need a task I've written to run sometime after clean but sometime before war. Preferably without modifying the plugin.
I've tried indicating that my task mustRunAfter processResources but it doesn't work that way.
How can I inject my task as a dependency on install before the dependency war?
You can declare task dependencies explicitly.
Add following code to your build.gradle file
tasks.war.dependsOn("yourTaskNameHere")
tasks["yourTaskNameHere"].dependsOn("clean")

Resources