Gradle project dependency problems - gradle

I have a multi-project Gradle build that is configured as this:
keycloak
|-- keycloak-spi-1
|-- keycloak-spi-2
|-- keycloak-theme
the subprojects build jars that i want to include inside docker that is build in the parent with Jib but, an error message appears:
Obtaining project build output files failed
Gradle is version 7.4.1
Thanks
After some investigation, Jib use the output of jar task during the image build and, in this case, jar task must not compile sources but copy the shadowJars from all the subprojects. I take this approach but not work:
task jar(type: Jar, overwrite: true) {
subprojects {
from(tasks.shadowJar)
}
into "${buildDir}/libs"
doLast {
delete jar.archiveFile
}
}

Related

Jib Main class error with spring boot multi module (gradle)

root-projec
ㄴ sub1-project
build.gradle
ㄴ sub2-project
build.gradle
build.gradle
I'm trying to build all subprojects as jibs in the root project.
The following script is the build.gradle file of the root and sub modules.
...
jib {
from {
image = "eclipse-temurin:17"
}
to {
image = "abc/${project.name}:${project.version}"
tags = ["latest"]
}
}
cd root-project
./gradlew jib
Execution failed for task ':jib'.
> com.google.cloud.tools.jib.plugins.common.MainClassInferenceException: Main class was not found, perhaps you should add a `mainClass` configuration to jib
Of course there are no classes in the root project. Why do you want to include the main class in the root project when building the jib? I'd like to find a way to exclude this.
Additionally, is there any way to build with jib when building with a specific profile as follows?
There is a way to write a script in maven, but gradle has grammatical difficulties.
./gradlew clean build -P build-docker-image

Why won't gradle jar build a jar that gradle build does?

In my Gradle project, I define an additional sourceSet.
sourceSets {
sample {
java {
srcDir 'sample/java'
}
compileClasspath += sourceSets.main.output + sourceSets.main.compileClasspath
}
}
I then add a task:
task sampleJar(type: Jar) {
classifier 'sample'
from sourceSets.sample.output
}
artifacts {
archives sampleJar
}
If I do > gradle build the additional jar file builds from the additional source set. However, if I do > gradle jar, it doesn't. any reason why?
When I go through the output messages, I see:
gradle build has sampleJar in the Tasks to be executed:
but
gradle jar doesn't.
But unsure as to why?
Because jar is just the task that assembles the main jar file.
build, on the other hand, is the top-level life-cycle task, which depends on assemble. And assemble is documented as
Depends on: jar, and all other tasks that create artifacts attached to the archives configuration.
Since your sampleJar pecisely creates an artifact attached to the archives configuration, assemble, and thus build depends on it.

Gradle tasks shown in intellij but can not be run

I have a multi module project with the following structure:
root_project
module1
module2
module3
I try to apply the java plug-in to all projects using the following code:
allprojects {
apply plugin: 'java'
group = 'com.mysoftware'
sourceCompatibility = 1.8
version = '1.3'
repositories {
mavenCentral()
}
}
Additionally I add the javafx plugin to module3. The java and javafx tasks are now shown in the intellij gradle view, but when trying to execute them, I get this error:
Task 'jfxJar' not found in root project 'module3'.
Furthermore, running the tasks task show me that neither the java tasks nor the javafx tasks are available, despite being shown in the gradle view in intellij.
I tried rebuilding and refreshing the whole project without success. I use the Use default gradle wrapper configuration.
The error message you got Task 'jfxJar' not found in root project 'module3' indicates that Gradle considers the subproject module3 as a Root project: this can happen if you created a settings.gradle file in the sub-project directory, which is not a valid setup (only one settings.gradle file can exist in a multiproject build, located in the root directory)

Collect build artifacts from subprojects into RPM with Gradle

I have the following project structure:
Root
+---Sub1
|
+---Sub2
Sub1 project produces JAR, Sub2 creates WAR.
Root project goal is to produce RPM that contains both the Sub1 and Sub2 output.
I'm trying to use ospackage Gradle plugin to build RPM. Here is part of root build.gradle:
ospackage {
from subprojects.collect { it.tasks.withType(Zip) } into 'lib'
}
It works but for Sub2 both JAR and WAR are created, which is undesirable.
What configuration should be applied in order to collect appropriate jars and wars into RPM?
UPDATE
I'm searching for some generic solution, i.e. iteration over subprojects is preferable to specifying behaviour for each subproject.
The solution is to add WAR plugin in Sub2 project's build.gradle:
apply plugin: 'war'
make buildRpm task dependent on all subprojects build tasks in the root build file:
buildRpm.dependsOn getTasksByName('build', true)
and finally configure ospackage plugin to collect the artifacts into the target RPM:
ospackage {
from(subprojects.collect { "${it.buildDir}/libs" }) {
into 'bin'
}
}

How to add a war build to a distribution

We have a gradle project that does a distTar to create a tar distribution file.
Each dependency project builds good placing all the dependencies and project jar files into the distribution libs folder.
We need to add a project that builds a war file. By adding the project as a dependency it adds all the war dependencies ... we need just the war file from the project war task.
Also the war project war task is not being executed.
Instead the jar task is being executed from distTar of the distribution project.
How do we execute the project war task and add just the war file to a "gui" folder in the tar distribution?
To get the built war file into the distribution add a task which the distTar depends. Have the depends on task depend on the other project war task. Take the output files and put them in the distribution. The key is to do the into/from in a doLast so the depends on other project war completes before the into/from for the distribution.
// create a task depends on other project war
// put into the distribution gui folder the war.output.files
// the doLast gives visibility to the war.outputs.files
// after the depends on is complete
task otherProjectWar(dependsOn: ':OtherProject:war') {
doLast {
applicationDistribution.into("gui") {
from( project(':OtherProject').war.outputs.files )
}
}
}
// add depends on for distTar
distTar {
dependsOn otherProjectWar
...
}
I believe the proper approach is to include desired task outputs to the distribution. Here is sample script that adds jar built by the project to the main distribution (for war use war outputs instead of jar outputs).
apply plugin: 'java'
apply plugin: 'distribution'
distributions {
main {
contents {
from jar.outputs
}
}
}
Running the distribution task then correctly resolves dependencies for both zip and tar.
> gradlew distTar
:clean
:compileJava
:processResources NO-SOURCE
:classes
:jar
:distTar
You'll need to add a dependency to the output of the war task. By default, ProjectDependency simply adds a dependency to the default configuration of that project.
dependencies {
compile project(':myproject').war.outputs.files
}
Edit: To clarify, compile probably isn't the best configuration to add this dependency to, this is just an example. If indeed all this project is doing is aggregating dependencies into a single distribution archive then the configuration is likely irrelevant.

Resources