Copy files over before jarring - gradle

I can't get my script to wait until libraries are copied over to 'src/main/resources/libs' before it starts to jar up everything. The files are copied over but the jar task I think is not waiting until the files are copied over? Because they are not added to my jar. Unless I run script again :/ How to fix this?
task copyDependencies(type: Copy) {
from configurations.myLib
into 'src/main/resources/libs'
}
jar.dependsOn 'copyDependencies'
jar {
manifest {}
}

To get the execution order right, processResources would have to depend on copyDependencies. However, you shouldn't copy anything into src/main/resources. Instead, the libraries should be included directly in the Jar, without any intermediate steps:
jar {
into("libs") {
from configurations.myLib
}
}
This assumes that there is some custom process or class loader in place that makes use of the libraries in the Jar's libs directory. A standard JVM/class loader will ignore them.

Related

Gradle: Include dynamically generated file in build?

During my gradle build, I generate a temporary buildinfo.properties file containing things like Git commit info, build time, etc. I would like to include this file in my output *.jar / *.war files as a resource. However, I do not want to put this file in my project src/ folder (this would require fiddling with .gitignore and in general it just seems unnecessary to me). Ideally, the developer shouldn't even see this file at all, it should just be contained in the output archive.
How would you include a dynamically generated text file in a Gradle build?
Add that file in a jar task (Kotin DSL):
tasks {
val jar by getting(Jar::class) {
from("build/buildinfo.properties")
}
}
It will add build/buildinfo.properties file (assuming you generate it there with another taks) to the root of your JAR.
For dynamically generated file, standard gradle way to process resources is the gradle task called processResources. You can do something like this:
processResources {
dependsOn taskThatGeneratesYourBuildinfo
from("build/buildinfo.properties") {
into("desired/path/in/jar")
}
}

Exclude base directory inside Gradle tar/zip artifacts

The maven assembly plugin has an includeBaseDirectory option that (when set to false) avoids having a single top-level directory inside the tar/zip artifact with the same name as the artifact itself.
I'd like to achieve the same result with Gradle, but I don't see how. I'm using a configuration like this:
task distTar(type: Tar) {
compression Compression.GZIP
extension "tar.gz"
}
I don't see any options for the Tar task that do what I want. How can I exclude the base directory in my archive with Gradle?
By reconfiguring the distribution plugin (which gets implicitly applied by the application plugin) you can simply do (in Kotlin DSL):
distributions {
main {
contents {
into("/")
}
}
}
This affects the output in both Tar and Zip formats.
(Disclaimer: This answer is loosely based on this Gradle forum post).
Ok, I figured it out. It was simpler than I thought. To copy the library dependencies into lib at the root of the archive, I use a CopySpec:
task distTar(type: Tar) {
into('lib') {
from libsDir
include '*.jar'
}
}
Similar CopySpecs can be used to copy e.g. bin and conf directories.

Need a gradle jar task that copies classes normally and custom files

In my Gradle build, after the classes are compiled, I need to create a jar containing the classes in the typical location, but I also need the jar to include a set of other plain text files from a specific subdirectory of the project, and going into a different named folder in the jar.
So, for instance, at the root of the jar, I'll have the "com" folder that starts the classes tree, but I'll also have a "META-INF" folder which contains a custom subfolder name, containing the files copied from the project.
Update:
I tried adding the following:
jar {
from ("src/main/resources/yang") {
into ("META-INF/yang")
}
}
This comes close to working properly. It does copy all the files from that "from" folder" to the "into" folder in the resulting jar. However, the resulting jar ALSO has a "yang" folder containing the same files from "src/main/resources/yang". So, how do I prevent the default copying of that folder?
I might end up doing this as part of a custom plugin, but for now I'd like to see if I can configure a simple "jar" task to do this.
Update:
Based on the solution, the following worked:
jar {
exclude "yang"
from ("src/main/resources/yang") {
into ("META-INF/yang")
}
}
As far as I understood build.gradle can be modified in the following way:
apply plugin: 'java'
jar {
from('other') {
into('META-INF/other')
}
}
Full demo can be found here
UPDATE
This should work:
apply plugin: 'java'
jar {
from('src/main/resources/other') {
into('META-INF/other')
}
exclude 'other/**'
}

Copying Files From One Zip File Into Another In Gradle

We are working on migrating to Gradle from Maven. Unfortunately we still have a couple of War overlays to deal with.
As a work-around I am trying to copy the contents of one war file into another.
This is what I have so far:
task overlayWars (dependsOn: war) << {
// Get the source war files to copy the contents from...
def dependencyWars = configurations.runtime.filter { it.name.endsWith ('.war') }
dependencyWars.each { dependentWar ->
// Get the products, ie the target war file...
war.outputs.files.each { product ->
println "Copying $dependentWar contents into $product"
copy {
from { zipTree (dependentWar) }
into { zipTree (product)} // this seems to be the problem
include 'WEB-INF/classes/**/*.class'
include 'WEB-INF/jsp/**/*.jsp'
}
}
}
}
When into { zipTree (product)} is a file (like file ('tmp/whatever')) this works fine. When specifying another zip file (the target war file) it fails with the error:
Converting class
org.gradle.api.internal.file.collections.FileTreeAdapter to File using
toString() method has been deprecated and is scheduled to be removed
in Gradle 2.0. Please use java.io.File, java.lang.String,
java.net.URL, or java.net.URI instead.
If anyone has suggestions on this specifically, or a better way to "overlay" war files, I'd really appreciate it!
After chasing down a couple of different angles, I ended up with this:
war {
configurations.runtime.filter { it.name.endsWith ('.war') }.each {
from zipTree (it).matching {
include 'WEB-INF/classes/**/*.class'
include 'WEB-INF/jsp/**/*.jsp'
include 'images/**'
}
}
}
Basically I am just including filtered contents of any .war dependencies in the product. Being an alteration to the standard war task, the dependency tree is kept clean. It seems to work for us so far...
In case you are trying to merge Wars here, you can't do that with a Copy task/method. You'll have to use a Zip task (there is no equivalent method). In case you want to merge into an existing War, the way to do this is existingWar.from { zipTree(otherWar) }.

how to copy all source jars in the dependencies section to a directory in gradle

I can copy all the jars in dependency section for "compile" configuration like so
task('copyJars') {
ext.collection = files { genLibDir.listFiles() }
delete ext.collection
copy { from configurations.compile into genLibDir }
}
but how do I copy their source jar files somewhere?
thanks,
Dean
As of Gradle 1.0, I don't know of an easy way to deal with third-party sources Jars. You could add them as explicit dependencies (to a separate configuration) or maybe crawl the Gradle cache.
By the way, delete ext.collection is in the wrong spot. It will be executed in the configuration phase, and will delete files no matter which tasks are going to be executed. (Also listFiles() will get invoked for every build.)
Also, a task whose main purpose is copying should alway use the Copy task type rather than the copy method.

Resources