Put jar output from one module into another - java

I have Gradle 7 project, there are two sub modules
- Root
- sub project A
- sub project B
My goal is following:
When project A is build it creates a A.jar file.
When project B is build it creates a B.jar file that contains unexploded A.jar output from build of project A
To be more clear B.jar should look something like this
\META-INF
\my
\package
\tree
SomeClassInsideBJar
\A.jar
URI aJarUri = someClassInsideBjar.getClassLaoder().getResource("A.jar");
Subproject A build just fine, but i cannot figure out how to embed its jar into B.jar
According to another questions I should be able to get a reference to .jar output of a task by .archiveFile property
I tried this in B`s build file
jar {
sourceSets.main.resources.includes = project(":A").getByName("build").archiveFile
}
But that ends with error
No signature of method: build_62kfcng7dpn0plap6jwx8ojvt.jar() is
applicable for argument types:
(build_62kfcng7dpn0plap6jwx8ojvt$_run_closure2) values:
[build_62kfcng7dpn0plap6jwx8ojvt$_run_closure2#be2d508]

Let's say you want to include classes and resources project A to B
The module B should contain:
dependencies {
// it must be compile only to prevent it to be exposed as a transitive dependency in the pom file
compileOnly project(":A")
}
jar {
from project(':A').sourceSets.main.output
}
Then you shall expect when you generate a jar with jar task inside the B.jar classes from module A right next to the classes from B, e.g. modules are merged.
Gradle 7.6.0

If what you need to do is to reference the project A inside project B, then you can compile project A at the time of project B build time and add it as a dependency to the project B jar file.
include both projects in settings.gradle file in the root project.
include 'project A'
include 'project B'
then in the build.gradle file of project B add
dependencies{
compile (':project A')
}

Related

How can you add dependency source code to sourceJar task output?

If you got a multi-project gradle build. And one module depends on another.
How could you add the dependency module source code to the output jar
Now i am using this:
java {
withSourcesJar()
}
I am new to gradle builds and i don't know any kotlin.
And if you have the source code of a dependency as a .jar file. Could you also add that
to the output?
So I have a project module:
dependencies:
project module
local .jar
What i want:
One .jar of the project (including other modules and dependencies) compiled code:
project-0.5.0.jar
..and one .jar of the source code (including other modules and dependencies)
project-0.5.0-sources.jar
I have all source code of dependencies stored locally as .jar files
Edit
My project conventions (global for all modules):
plugins {
`java-library`
}
java {
withSourcesJar()
}
How I am currently creating the project "fat".jar with compiled code:
(inside the build script)
tasks.jar {
//manifest.attributes["Main-Class"] = "com.example.MyMainClass"
val dependencies = configurations
.runtimeClasspath
.get()
.map(::zipTree) // OR .map { zipTree(it) }
from(dependencies)
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
I have figured out how to add a project moduleA to another moduleB output sources .jar like so (inside moduleB's build-script):
tasks.sourcesJar {
from(project(":moduleA").sourceSets.main.get().allSource)
}
Now I need to figure out how to include source code from a dependency .jar
from(file("../path/dependency-1.0.0-sources.jar"))
This packs the .jar as it is. I need it's files.
I figured it out. And it was easier than i thought. Keep in mind i am using Kotlin.
(All code snippets are inside the build.gradle.kts file of the project / module you are creating the sources .jar for)
First off you need to include either the java or java-library plugin:
plugins {
`java-library`
}
And as far as i know, also this plugin extension:
java {
withSourcesJar()
}
This makes the sourcesJar task available (task used to create the sources jar), and you can modify it like so:
tasks.sourcesJar {
from(project(":common").sourceSets.main.get().allSource)
from(zipTree("../libs/tinylog-2.5.0/tinylog-api-2.5.0-sources.jar"))
}
The first line inside the brackets includes my "common" module source code to the output .jar.
The second line adds the .java files inside the tinylog sources .jar to the output .jar.

How is the classpath setup in a multimodule gradle project during runtime?

I'm quite new to gradle and especially multimodule gradle projects, so I have a small example project created with the following project structure
Main
*src
*tests
*build.gradle
*settings.gradle
*Subproject1
+src
+tests
+build.gradle
So when I tried to load the classes in Subproject1 from a class in the main (root) project, it can not find the class, I would have thought the root project classpath contains the subprojects classes as well.
What am I doing wrong here or any material I should go through to understand this?
current settings.gradle file,
rootProject.name = 'main'
include 'Subproject1'
You should take some time to read documentation HERE which explains the concept of multiproject builds and provides some examples on how to create dependencies between sub-projects.
The root project will not inherit classpath from the subprojects, you will have to declare explicitelly these dependencies as follows
build.gradle (root project)
dependencies {
implementation project(':Subproject1')
}

IntelliJ / Gradle - composite build project - how to import from different module?

I'm new to Java and am currently trying to build a cucumber / selenium project in IntelliJ that contains two modules: A library project containing page definitions, and a test project that contains the cucumber features and step definitions that talk to those page definitions. The idea is that the page definitions are a shared resource, and the tests are specific to different projects / groups. Both modules are at the same level underneath the parent project. The build is using Gradle, and the settings.gradle file for the parent looks as follows:
rootProject.name = 'composite-builds'
includeBuild 'libraryproject'
includeBuild 'testproject'
Using Gradle includeBuild on the parent project works fine and the whole project imports. However I am having no luck using the library project in my import statements in the test project. It consistently returns me these kinds of error: java: package libraryproject.pageFactory.examplePages does not exist and is clearly not seeing the library module.
What do I need to do / add in order for the test project to recognise the library project? I did try to also add the includeBuild statement in the settings.gradle for the test project but this made no difference.
The library can be found here
Update: the real reason that I cannot see the modules from the library project is that they were held in the test folder, not main.
Go to your build.gradle file
Instead of includeBuild use dependencies{compile{project(':libraryproject')}}
Inside the Root Project of libraryproject which is in your case the composite-builds. Change includeBuild to include in the settings.gradle
rootProject.name = 'composite-builds'
include ':libraryproject'
include ':testproject'
If it is in the same root:
dependencies {
compile(
project(':libraryproject')
)
}
Subfolder:
dependencies {
compile(
project(':myFolder1:myFolder2:libraryproject')
)
}

Gradle composite builds - can you have a dependency to a java sub-project from an included multi-project build?

Let's say you have 2 gradle projects. The first is a multi project with 2 java sub-projects:
rootProject
:my:subProject1
:myother:subProject2
The second gradle project is a single project that includeBuild's the root project:
secondProject
includeBuild '../rootProject'
I want to make a compile dependency of :my:subProject1 into secondProject.
So basically I want to add the following to secondProject's build.gradle file:
dependency {
compile(project(':my:subProject1'))
}
When I try to do that, it returns error: Project with path ':my:subProject1' could not be found in root project 'secondProject'
I seems like I can only resolve the dependency when I do the dependency as group:artifact:version. For example: my.root.project:subProject1:1.0.0. But why would it make me do that? Why not let me access the composite build's project hierarchy?
Only one settings.gradle should exist on the root, remove all setting.gradle files in any subfolders
Define the projects on the settings.gradle file of the root folder
include ':sub1', ':sub2', ':sub3'
Add compile project(":sub1") to your build.gradle under dependencies block:
dependencies{
compile project(":sub1")
}
This is just how these composite builds work. They basically act as if you published the other project to maven local prior to including it. so this means you need to depend on the version number of the split project.

Configure parent/root project for child project in gradle

Is it possible to set parent project of a child gradle project.
In my case, all parent and child project lies on same level in the file hierarchy. For example
code
/parent project
build.gradle
/child project1
build.gradle
/child project2
build.gradle
Here porject 1 depends on project2, so i am referring them as
compile project(':../project2')
also in my settings.gradle file , i have
include '../child_project1'
include '../child_project1'
with this i am able to run tasks from parent project folder but individual tasks are not running from child projects.
I know this is an old question but you can do this by specifying the child project like this in your settings.gradle:
include ':A'
project(':A').projectDir = new File('../A')
Check out section 20.3.2.2. of the Gradle doc on Multi-project builds. One can use includeFlat in the settings.gradle file.

Categories

Resources