Gradle zip packaging: copy Jar file from repository - groovy

I have to copy a jar from the repository (say local) in my ZIP packaging. I understand that we can define compile/runtime in dependencies. However, I could not use it them in ZIP.
I'm able to copy the jar file by specifying the path in my filesystem. However, I don't know how to do it from repository.
Here is how my code looks like:
task createZipFile (type: Zip, dependsOn: [...]) {
baseName 'xyz'
from(fileTree("src/main"), {
include "prjName/css/**"
include "prjName/images/**"
include "prjName/javascript/**"
include "prjName/WEB-INF/**"
exclude "prjName/WEB-INF/web.xml"
})
from file("<Absolute-path-to-jar-file-in-my-filesystem>") //this works
// how to copy the same jar file from repository ??
}

Assuming your dependencies are in the runtime configuration ie:
runtime 'org.slf4j:slf4j-log4j12:1.6.2'
you can do:
task createZipFile( type: Zip, dependsOn: [...] ) {
baseName 'xyz'
from fileTree("src/main"), {
include "prjName/css/**"
include "prjName/images/**"
include "prjName/javascript/**"
include "prjName/WEB-INF/**"
exclude "prjName/WEB-INF/web.xml"
}
from configurations.runtime.files { it.name == 'slf4j-log4j12' }
}
To add all jars downloaded for the dependency with the name slf4j-log4j12

To specify a specific jar without its dependencies, qualify it with "#jar". E.g.
"commons-beanutils:commons-beanutils:1.6#jar"
For an example that explains how to reference a set of jars using a custom configuration, see Download some dependencies and copy them to a local folder

Related

Gradle Sync task, sync into folder but ignore specified directories in destination

I want to synchronize a folder on my drive with another folder that contains a folder named 'logs' that i want to keep. confused? here's a diagram:
C:\
|-- mydir/ # sync this folder
| `-- someotherfiles.txt
`-- anotherDir/ # into this folder
|-- logs/ # but if this exists, leave it there
`-- someotherfiles.txt
Is this possible using the sync task? I can't seem to configure it properly, my latest attempt might allude you to my scenario so here it is (not working):
task syncDevDeployFolder(type: Sync, group: 'dev') {
from currentDeliverablesDir
destinationDir = file(project.properties['dev.deployment.dir'])
into (project.properties['dev.deployment.dir']) {
exclude "logs"
}
}
At the time of writing, the current version of Gradle is 3.3 and since version 3.1 there is an incubating feature called 'preserve' which can be used to achieve what you want:
See the example from the documentation:
// You can preserve output that already exists in the
// destination directory. Files matching the preserve
// filter will not be deleted.
task sync(type: Sync) {
from 'source'
into 'dest'
preserve {
include 'extraDir/**'
include 'dir1/**'
exclude 'dir1/extra.txt'
}
}
So in your case you could specify it like this:
preserve {
include 'logs/**'
}
Is this possible using the sync task?
No, the Sync task doesn't currently support this.
You can fallback to ant's sync task. ant object is available to all gradle build scripts anyways
task antSync << {
ant.sync(todir:"dest/"){
ant.fileset(dir: "source/")
ant.preserveintarget(includes: "logs/")
}
}

Groovy - How to Build a Jar

I've written a Groovy script which has a dependency on a SQL Server driver (sqljdbc4.jar). I can use the GroovyWrapper (link below) to compile it into a JAR, however how can I get dependencies into the Jar? I'm looking for a "best practice" sort of thing.
https://github.com/sdanzan/groovy-wrapper
Both of the replies below have been helpful, but how can I do this for signed Jar files? For instance:
Exception in thread "main" java.lang.SecurityException: Invalid signature file d
igest for Manifest main attributes
In the groovy wrapper script, you'll see this line near the bottom:
// add more jars here
That's where you can add your dependencies. If the jar file is in the same directory you're building from, add a line like this:
zipgroupfileset( dir: '.', includes: 'sqljdbc4.jar' )
Then rerun the script and your jar will include the classes from sqljdbc4.jar.
Edit:
If the jar file you depend on is signed and you need to maintain the signature, you'll have to keep the external jar. You can't include jar files inside of other jar files without using a custom classloader. You can, however, specify the dependency in the manifest to avoid having to set the classpath, i.e. your jar still executable with java -jar myjar.jar. Update the manifest section in the wrapping script to:
manifest {
attribute( name: 'Main-Class', value: mainClass )
attribute( name: 'Class-Path', value: 'sqljdbc4.jar' )
}
From your link, if you look at the source of the GroovyWrapper script, there's this line:
zipgroupfileset( dir: GROOVY_HOME, includes: 'embeddable/groovy-all-*.jar' )
zipgroupfileset( dir: GROOVY_HOME, includes: 'lib/commons*.jar' )
// add more jars here
I'd explicitly add it there.

Specify ivy configuration in gradle dependency

I want to resolve dependencies from ivy repository but I don't know how to specify ivy configuration for it. I found that I should do it in this way:
myconf group: 'com.eu', module:'MyModule', version:'1.0.0', configuration: 'ivyconf'
but it doesn't work. When I run gradle dependencies command gradle returns this error:
Could not create a dependency using notation: {group=com.eu, module=MyModule, version=1.0.0, configuration=ivyconf}
My build doesn't use plugins. I want to download dependencies in simple build which should create product from downloaded dependencies.
Build looks like this:
group = 'com.eu'
version = '0.9a'
configurations {
myconf
}
repositories {
ivy {
url 'http://ivyrepo.local/ivyrep/shared'
layout "pattern", {
artifact "[organisation]/[module]/[revision]/[type]s/[artifact].[ext]"
}
}
}
dependencies {
myconf group: 'com.eu', module:'MyModule', version:'1.0.0', configuration: 'ivyconf'
}
Instead of module, it has to be name. (see "49.4. How to declare your dependencies" in the Gradle User Guide). The declared configuration (myConf) must match the configuration used in the dependencies block (installer).

Create multiple .WAR files with different dependencies in Gradle

I am using the war plugin to generate a simple .WAR file for my project in gradle. I'd like to know how to configure gradle so that I can create 4 different .WAR files with different dependencies.
I've configured the dependency compile configuration with the jars that are needed to go into the distribution. None of the code in the src depends on a couple of these jars but I would like to know how to configure the project to create
a standard.WAR file that contains all of the jars in the dependency graph (Even though they aren't used - that is OK - I am testing something)
another standard-qas-only.WAR file that only contains the qas.jar
another standard-qas-log4j.WAR file that contains qas.jar and log4j
What tasks do i configure to have the artifact generated use a particular dependency configuration?
FYI: The only jar that is required for compilation is qas.jar in this case.
My example below creates a war file that only includes one jar but i'd like to have 5 different .war files generated with different jars.
build.gradle
apply plugin: 'java'
apply plugin: 'war'
dependencies {
compile files('/lib/qas.jar','/lib/axis1-1.4.jar','/lib/axis2-kernel-1.3.jar','/lib/dom4j-1.6.1.jar','/lib/log4j-1.2.14.jar')
providedCompile files('/lib/j2ee-1.4.03.jar')
}
war {
classpath = ['/lib/qas.jar']
}
task dist(dependsOn: 'war') << {
copy {
from war.archivePath
into "dist/"
}
}
I got a bit confused on how many WAR distributions you are actually trying to build. You can easily modify it to create additional WAR files. Here's one approach to make this happen:
task createStandardWar(type: War, dependsOn: classes) {
baseName = 'standard'
destinationDir = file("$buildDir/dist")
}
task createStandardWarQasOnly(type: War, dependsOn: classes) {
baseName = 'standard-qas-only'
destinationDir = file("$buildDir/dist")
classpath = war.classpath.minus(files('/lib/axis1-1.4.jar','/lib/axis2-kernel-1.3.jar','/lib/dom4j-1.6.1.jar','/lib/log4j-1.2.14.jar'))
}
task createStandardWarQasAndLog4J(type: War, dependsOn: classes) {
baseName = 'standard-qas-log4j'
destinationDir = file("$buildDir/dist")
classpath = war.classpath.minus(files('/lib/axis1-1.4.jar','/lib/axis2-kernel-1.3.jar','/lib/dom4j-1.6.1.jar'))
}
task createDists(dependsOn: [createStandardWar, createStandardWarQasOnly, createStandardWarQasAndLog4J])
This build script excerpt creates three different WAR files by declaring enhanced tasks of type War. It assumes that you still want to have your compiled source files under WEB-INF/classes within the WAR files so I didn't remove it from the classpath. The distributions end up in the directory build/dist. The task createDists creates all of them.

How can I create a pathing jar in Gradle

When running groovyc in a Windows env, I am running into issues due to the length of the classpath, in my situation. I would like to work around this by creating a pathing jar, and then put that jar on the cp. How can I create a pathing jar w/ all of the classpath entries specified automatically in gradle and then add that jar to the cp?
Here is a tested solution:
task pathingJar(type: Jar) {
appendix = "pathing"
doFirst {
manifest {
attributes "Class-Path": configurations.compile.files.join(" ")
}
}
}
compileGroovy {
dependsOn(pathingJar)
classpath = files(pathingJar.archivePath)
}
Depending on your exact requirements, you might have to tweak this a bit. For example, if you have tests written in Groovy, you will also need a pathing Jar for the test compile class path. In this case you'll need to repeat above configuration as follows:
task testPathingJar(type: Jar) {
appendix = "testPathing"
doFirst {
manifest {
attributes "Class-Path": configurations.testCompile.files.join(" ")
}
}
}
compileTestGroovy {
dependsOn(testPathingJar)
classpath = files(testPathingJar.archivePath)
}
I finally got the "pathing jar" idea to work. I consider this to be a permanent workaround. This could be considered a solution if it is made part of gradle itself.
The original pathing jar code was provided by Peter, but it didn't work. The problem: classpath elements referenced in the pathing jar must be relative to the location of the pathing jar. So, this appears to work for me.
task pathingJar(type: Jar , dependsOn: 'cleanPathingJar') {
/**
* If the gradle_user_home env var has been set to
* C:\ on a Win7 machine, we may not have permission to write the jar to
* this directory, so we will write it to the caches subdir instead.
* This assumes a caches subdir containing the jars
* will always exist.
*/
gradleUserHome = new File(gradle.getGradleUserHomeDir(), "caches")
relativeClasspathEntries = configurations.compile.files.collect {
new File(gradleUserHome.getAbsolutePath()).toURI().
relativize(new File(it.getAbsolutePath()).toURI()).getPath()
}
appendix = "pathing"
destinationDir = gradleUserHome
doFirst {
manifest {
attributes "Class-Path": relativeClasspathEntries.join(" ")
}
}
}
compileGroovy {
dependsOn(pathingJar)
classpath = files(pathingJar.archivePath)
}
This is what helped me:
"The filename or extension is too long error" using gradle
In other words: use the com.github.ManifestClasspath plugin.
The other solutions did not work for me because the actual project main class ended up no being included in the classpath at execution time.

Resources