I was trying to create two separate jar files with a single build.gradle.
It is almost working but one will overwrite the other. What's the right way of doing it?
jar {
//include contents of output dir
from "$buildDir/classes/main"
exclude '**/a1/**'
archiveName "X1-1.0.0.jar"
}
jar {
//include contents of output dir
from "$buildDir/classes/main"
exclude '**/a2/**'
archiveName "X2-1.0.0.jar"
}
Thanks
Rather than configuring the same Jar task twice, you need to use two Jar tasks. Assuming you are using the java plugin, you can reuse the Jar task named jar added by that plugin, and add another one yourself:
// reconfigure the Java plugin's `jar` task
jar {
exclude '**/a1/**'
baseName = 'X1'
}
// need to configure this one from scratch
task x2jar(type: Jar) {
// referring to the output in this way
// allows Gradle to infer task dependencies automatically
from sourceSets.main.output
exclude '**/a2/**'
baseName = 'X2'
}
// one way to make `gradle build` run both Jar tasks
assemble.dependsOn(x2jar)
For details on the configuration options, refer to the Gradle Build Language Reference.
Related
I have a jar task (well a ShadowJar, but that shouldn't matter I think).
named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
archiveClassifier.set("")
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
There's a file called linux/x64/org/lwjgl/liblwjgl.so within a dependency which I need to rename to liblwjgl3.so. Is there a way to do that within the jar task?
I am using gradle to build some a uber jar file, this jar file has dependencies and I used this guide to create the task that I can run
My task is like this btw I am using kotlin
tasks.register<Jar>("uberJar") {
archiveClassifier.set("uber")
from(sourceSets.main.get().output)
duplicatesStrategy = DuplicatesStrategy.EXCLUDE;
dependsOn(configurations.runtimeClasspath)
from({
configurations.runtimeClasspath.get().filter { it.name.endsWith("jar") }.map { zipTree(it) }
}})
What can I add to this task to add my .java files as well.
Also I don't really understand much of what is going on here like what actually is SourceSets?
Try adding this to your build.gradle.kts and see if it works:
tasks.named<ProcessResources>("processResources") {
from("src/main/java")
}
When your uber-JAR builds, it should contain the source files. Though this will also add the source files to any JAR. If that is not what you want, then you will need to configure something similar in the uber-JAR setup.
I need to create a jar from a subset of java classes in my project.
I have 3 tasks: (Copy, Compile, Jar)
The copy and compile tasks work fine.
They are below for reference:
1. Copy files to a directory that are needed to compile the jar. There are additional files needed in this directory that are needed in the compile but not included in the jar files.
task copyCoreSharedFiles(type: Copy) {
includeEmptyDirs = false
from ('src/java/com/')
(List of includes and excludes)
into rootProject.rootDir.getAbsolutePath() + "/target" +"/coreshared"
println 'Copied core-shared files into directory'
}
2. Compile the java files and stored to another directory
task compileCoreShareJar(type: JavaCompile) {
source = file('target/coreshared')
destinationDir = file('target/buildtmp/core')
classpath = configurations.compile
println 'Compiled core-shared files into directory'
}
I am having trouble jarring all of the class files.
The task in below.
task jarCoreShareClassFiles(type: Jar) {
includeEmptyDirs = false
archiveName = "core-shared-SNAPSHOT.jar"
destinationDir = file("$rootDir/target/lib/")
from file('target/buildtmp/core')
include('**/com/common/*')
include('**/com/javaserver/*')
exclude('**/com/javaserver/dock/transaction/PrintTransaction.class')
println 'Jar core-shared files into directory'
}
I need to include and exclude specific directories and files.
When I use include('**/com/common/*') it includes the common directory files but not the subdirectory local under the common directory.
It does not include the javaserver directory at all.
How do I use include and exclude in the jar command?
The * pattern does not match subdirectories. To recurse into subdirectories you can use **.
In Gradle 3.x I was able to get some xml mapping files to copy into the classes directory prior to build/jar via the following block:
copy{
from 'src/main/java/com/company/mapping'
into 'build/classes/main/java/com/company/mapping'
include '**/*.xml'
}
In Gradle 4.9 this has been deprecated in favor of:
task copyMappings(type: Copy){
from 'src/main/java/com/company/mapping'
into 'build/classes/main/java/com/company/mapping'
include '**/*.xml'
}
The copyMappings task succeeds, but build/jar does not wait for copyMappings to finish. I have tried variations on build.dependsOn and doFirst{ copyMappings } doLast{ build } but nothing seems to get me the desired effect of having the copied files in place in the 'into' path prior to jar.
This is for Windows 10.
This works for me with Gradle 4.9 on Mac OS:
apply plugin: 'java'
task copyMappings(type: Copy) {
from 'src/main/java/com/company/mapping'
into 'build/classes/main/java/com/company/mapping'
include '**/*.xml'
}
jar.dependsOn copyMappings
jar.doFirst {
assert new File("${projectDir}/build/classes/main/java/com/company/mapping/abc.xml").exists()
assert new File("${projectDir}/build/classes/main/java/com/company/mapping/def.xml").exists()
}
command line is gradle clean jar
I like to model things around source sets where appropriate as doing so let's the build work more reliably with a wide range of plugins and use cases. For example, imagine you want to run an application direct from its class files and resources rather than packaging it as a JAR first. You could make sure that the "run" task depends on the copy as well, but you'd have to do that for every instance where this is a requirement.
Source sets are the ideal solution because they have the concept of a runtime classpath, which will work for packaging, instrumentation, running, testing and so on.
With that in mind, I would go for this simple declaration and get rid of the copy task:
sourceSets {
main {
resources {
srcDir "src/main/java"
include "**/*.xml"
}
}
}
The XML files will end up in a different directory from your current approach, but that shouldn't matter unless you have tasks that assume the location rather than using the source set model to get the necessary information.
Note The above include directive applies to all the resources in src/main/resources as well. So if you have properties files or text files or anything else in there, they will be excluded. The simplest solution is to add all required resource file patterns to the include directive.
I've successfully configured my gradle build script to create a zip distribution of my application with an extra 'config' folder at the root. This folder contains (at least right now) only one properties file in use by the application, and is on the classpath for the application.
What I'm looking for now, however, is a way to do the same with the 'run' task in the application plugin. When I try to run my application this way, (for testing), my program fails to run because of a class trying to access this properties file on the root of the classpath.
A bonus would be if I could get IntelliJ or Eclipse to also add this folder to its classpath just like the other folders (src/main/java, src/main/resources, ...) so I can run and debug my code from within the IDE without invoking a gradle task. I want to try to avoid as much as possible tying this code to any one IDE, so that when anybody needs to work on the project, they just need to import the build.gradle file and have the IDE make the appropriate config files it needs.
Here is my build.gradle file:
apply plugin: 'application'
mainClassName = "MainClass"
startScripts {
// Add config folder to classpath. Using workaround at
// https://discuss.gradle.org/t/classpath-in-application-plugin-is-building-always-relative-to-app-home-lib-directory/2012
classpath += files('src/dist/config')
doLast {
def windowsScriptFile = file getWindowsScript()
def unixScriptFile = file getUnixScript()
windowsScriptFile.text = windowsScriptFile.text.replace('%APP_HOME%\\lib\\config', '%APP_HOME%\\config')
unixScriptFile.text = unixScriptFile.text.replace('$APP_HOME/lib/config', '$APP_HOME/config')
}
}
repositories {
...
}
dependencies {
...
}
Likely what needs to happen is that I need to have the /src/dist/config folder to be copied into the build directory and added to the classpath, or have its contents be copied into a folder that is already on the classpath.
I ended up taking Opal's suggestion as a hint, and came up with the following solution. I added the following to my build.gradle file:
task processConfig(type: Copy) {
from('src/main/config') {
include '**/*'
}
into 'build/config/main'
}
classes {
classes.dependsOn processConfig
}
run {
classpath += files('build/config/main')
}
Alternatively, a simpler approach would be to add a runtime dependency to my project as such:
dependencies {
...
runtime files('src/main/config')
}
I didn't end up doing it this way, however, because my distribution package ended up having .properties files in the lib folder... and I'm just picky that way.
As you can see in the docs run is a task of type JavaExec. So classpath for it can be modified. Try to add config folder to the classpath. See here.