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.
Related
I have a multi-project gradle build, using kotlin as build script language.
I can build a "fat" jar containing all project dependencies (.class files)
I am not sure how it works. But it goes through all dependencies and exclude duplicate packages.
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
}
Is there some equivalent way to create a sources jar. Including the source code
of all dependencies?
Side question: Can you declare sources like dependencies?
dependencies {
implementation(project(":common"))
implementation(files("../libs/somejar1.jar"))
implementation(files("../libs/somejar2.jar"))
}
sources {
?
}
Edit
I have written a library. The library has code I have written (multiple modules). The modules have dependencies. (Could be other modules within the project, and/or other libraries) I have the other libraries' as jar files stored locally together with the source code of those libraries.
I am able to pack all the code I have written together with my codes dependencies into a single fat jar.
It would be nice to also be able to pack all source files (including the source files of the dependencies) into a "fat sources jar".
That way, when I want to use my library in other projects. I can have 2 jars. One with all the .class files and one sources jar with all the .java files.
I have a library which is used to build a number of CLI tools using Gradle. Each CLI tool is a separate JAR. At the moment every tool requires a separate Gradle project, with an associated set of directories, like this:
Having all of this structure is resulting in the whole collection of tools becoming very unwieldy and difficult to work with. Is there any way to collect all of the different Mains into a single folder (suitably renamed) and configure Gradle to turn each one into a separate JAR?
FWIW, the JARs are currently created using https://github.com/johnrengelman/shadow . JAR size doesn't matter.
Thanks in advance.
Jars are just zip files with META-INF folder inside. Use Zip tasks to create them and dependsOn to run tasks as part of your build sequence.
I had the code like below for changing jar files:
task changeJar (type: Zip) {
baseName project.name
extension 'jar'
destinationDir new File('build')
entryCompression ZipEntryCompression.STORED
from { zipTree(new File(core.libsDir, core.name + '.jar')) }
from ( <somewhere else> ) {
exclude 'META-INF/'
}
}
I'm not sure if it's a good fit but you might be interested in my gradle-java-flavours plugin.
eg:
apply plugin: 'com.lazan.javaflavours'
javaFlavours {
flavour 'tool1'
flavour 'tool2'
}
dependencies {
compile 'a:a:1.0' // common to all tools
compileTool1 'b:b:2.0' // compile deps for tool1 only
runtimeTool2 'c:c:2.0' // runtime deps for tool2 only
}
Directories
src/main/java, src/test/java, src/main/resources, src/test/resources - common code & tests
src/tool1/java, src/testTool1/java, src/tool1/resources, src/testTool1/resources - tool1 only sources
src/tool2/java, src/testTool2/java, src/tool2/resources, src/testTool2/resources - tool2 only sources
Jars
projectName.jar
projectName-tool1.jar
projectName-tool2.jar
I'm using Dagger 2 to generate some source code in my Gradle project. Right now those sources are being generated and added in the ./build/classes/main folder along with all the class files.
How do I choose a folder to separate all the generated .java files to?
How do I include that folder in my gradle Java project, and have IntelliJ view those as sources so I can use them in my project?
It looks like the application plugin only uses a certain set of directories by default, mixing in flavours of build to decide what files to compile.
However, I did find an example build script that creates a dagger configuration and manipulates gradle into using it for the generated output and adds it to the classpath. It uses dagger-compiler.
The core of it is:
sourceSets {
dagger {
java {
srcDirs = ['src/dagger/java']
}
}
}
configurations {
compileDagger
}
compileJava {
description = "dagger annotation processor is loaded automatically from classpath"
sourceSets.dagger.java.srcDirs*.mkdirs()
classpath += configurations.compileDagger
options.compilerArgs += [
'-s', sourceSets.dagger.java.srcDirs.iterator().next()
]
}
clean {
description = "delete files in generated source directory tree"
delete fileTree(dir: sourceSets.dagger.java.srcDirs.iterator().next())
}
dependencies {
ext.daggerVersion = "2.0.1"
compile(
"com.google.dagger:dagger:${daggerVersion}",
"com.google.guava:guava:18.0")
compileDagger(
"com.google.dagger:dagger-compiler:${daggerVersion}")
}
Regarding IntelliJ, the plugin should automatically add any srcSets via the normal building of the idea project, so there should be no additional configuration needed, just regenerate it.
I am trying to use Sigar in a Gradle project. Sigar distribution is by default provided with 2 types of files:
a JAR that contains classes
some native files (.so, dylib, .dll)
My purpose is to repackage these files so that I can use them as dependencies deployed and downloaded on-demand from a personal Maven repository.
My first try was to define dependencies as files in order to check that my application is working as expected before to repackage. Below is the Gradle code I used for my first test that works:
dependencies {
compile files("${rootDir}/lib/sigar/sigar.jar")
runtime fileTree(dir: "${rootDir}/lib/sigar/", exclude: "*.jar")
}
Then, I have repackaged Sigar native files into a JAR and renamed the other one to match rules for maven artifacts since I want to deploy them in a Maven repository. Below is what I get:
sigar-1.6.4.jar (contains .class files)
sigar-1.6.4-native.jar (contains .dylib, .so, and .dll files at the root)
The next step was to deploy these files in my custom repository. Then, I have updated my build.gradle as follows:
dependencies {
compile 'sigar:sigar:1.6.4'
runtime 'sigar:sigar:1.6.4:native'
}
Unfortunately, when I do a gradle clean build, new dependencies are fetched but native libraries can no longer be found at runtime since now I get the following exception:
Error thrown in postRegister method: rethrowing <java.lang.UnsatisfiedLinkError: org.hyperic.sigar.Sigar.getCpuInfoList()[Lorg/hyperic/sigar/CpuInfo;>
Consequently, I am looking for a solution to fetch and to link native files to my Java app like for other dependencies. Any advice, comment, suggestion, help, solution, etc. are welcome ;)
A solution is to define a new gradle configuration that unzips JAR files at the desired location:
project.ext.set('nativeLibsDir', "$buildDir/libs/natives")
configurations {
nativeBundle
}
dependencies {
nativeBundle 'sigar:sigar:1.6.4:native'
}
task extractNativeBundle(type: Sync) {
from {
configurations.nativeBundle.collect { zipTree(it) }
}
into file(project.nativeLibsDir)
}
dist.dependsOn extractNativeBundle
Then, this location must be put in java.library.path for tasks that depend on native libraries:
systemProperty "java.library.path", project.nativeLibsDir
Can I compile Android JUnit test apk file by using gradle script? Now my test class is:
public class main extends ActivityInstrumentationTestCase2<LoginWindow> {
public main() {
super("com.tecomgroup.handifox", LoginWindow.class);
}
...
}
and gradle says that he cannot find class LoginWindow. Should I add the LoginWindow.java to dependencies {} block? Will such test work? Or may be there is another way to compile test apk file?
When using Gradle Android plugin, you no longer need to have a separate project for testing. Production sources should be put into src/main/java directory, test sources should be in src/instrumentTest/java. The same applies to resources.
From Android Gradle plugin User Guide on project structure.
Project Structure
The basic build files above expect a default folder structure. Gradle follows the concept of convention over configuration, providing sensible default option values when possible.
The basic project starts with two components called “source sets”. The main source code and the test code. These live respectively in:
src/main/
src/instrumentTest/
Inside each of these folders exists folder for each source components.
For both the Java and Android plugin, the location of the Java source code and the Java resources:
java/
resources/
For the Android plugin, extra files and folders specific to Android:
AndroidManifest.xml
res/
assets/
aidl/
rs/
jni/
Note: src/instrumentTest/AndroidManifest.xml is not needed as it is created automatically.
You can change the standard project layout
sourceSets {
instrumentTest {
java {
srcDir '../other/src/java'
}
resources {
srcDir '../other/src/resources'
}
}
}