Gradle: create zip file containing classes and dependencies - gradle

I have to create a zip-file containing the classes (and the manifest etc.!) in a classes-folder and the dependency jar-files in an libs folder. My current attempt is:
task createZip(type: Jar) {
into('classes')
extension('zip')
with jar
}
but it does not add the dependencies (as anyone would have guessed)

ok, i solved it
task plugin(type: Zip) {
from (configurations.compile) {
into ('libs/')
}
from (sourceSets.main.output.classesDir) {
into ('classes/')
}
from (sourceSets.main.resources) {
into ('classes/')
}
from (new File(project.buildDir, 'tmp/jar/')) {
into ('classes/META-INF/')
}
}
plugin.dependsOn jar
this copies the dependencies into libs and all the compiled classes, resources and the manifest into libs. plugin.dependsOn jar is important because the manifest ist generated by the jar task.

Your question says you desire a zip file, though your attempt uses a Jar task. Regardless of whether you zip or jar (since the jar task extends zip), the below snippet will collect all compiled dependencies, and you can put them wherever you desire:
from (configurations.compile.collect { it.isDirectory() ? it : zipTree(it) })

Related

Depend on Kotlin Multiplatfrom JS Module from JVM

I have a Kotlin Multiplatform project with a common, a JS and a JVM module. The JVM module uses a JavaFX WebView to display a GUI. This GUI however shall be implemented as the JS module. How do I add the JS module as a dependency correctly? I tried
dependencies {
compile project(":myproject-js")
}
however, this does not include the resulting JS files anywhere in the classpath. The JS module does indeed create a JAR file with the required dependencies, but I could not find a way to access them.
I also tried simply copying the JS files into my build output, but they are still ignored:
configurations {
js
}
dependencies {
js project(":myproject-js")
}
project.afterEvaluate {
build.dependsOn copyResources
}
task copyResources(type: Copy) {
dependsOn configurations.js
into file("${project.buildDir}/resources")
from {
configurations.js.asFileTree.each {
from (zipTree(it))
}
null
}
}
Is there a way to achieve this?
Here's what should work:
Create a configuration for the myproject-js dependency:
configurations {
js
}
Add the project dependency to that configuration:
dependencies {
js project(":myproject-js")
}
Add the configuration files to the processResources task with .from(...), and the corresponding build dependency:
processResources {
dependsOn configurations.js
from(configurations.js.collect { zipTree(it) })
}
Then, whenever you build the JVM project, the JS module's files get unpacked into the resources output directory and then packed into the JAR.

Gradle - how do I exclude a resource from the executable jar?

I have a "production" logback configuration file logback.xml under src/main/resources... but that directory also contains the "testing" logback configuration file logback-test.xml (which logback looks for first).
When creating an executable jar I want to delete the "testing" xml file.
I tried this
jar {
manifest {
// PS this is the correct line for Shadow Plugin...
attributes 'Class-Path': '/libs/a.jar'
attributes 'Main-Class': 'core.MyMainClass'
}
exclude("**/resources/*test*")
}
and I tried this
jar {
manifest {
attributes 'Class-Path': '/libs/a.jar'
attributes 'Main-Class': 'core.MyMainClass'
}
doLast {
exclude("**/resources/*test*")
}
}
... what am I doing wrong?
later
I find here that I was probably making life difficult for myself in putting these xmls under /src/main/resources ... so I created a new directory under src, /logback, and put the files in there instead. I added this to the classpath (as logback says that's where it looks for these files) by doing this:
test {
classpath += files( 'src/logback' )
}
Interestingly, as well as meaning that logging during testing happens OK, this is enough to get the resulting executable jar to use logback OK when run.
Unfortunately, configuring the "shadowJar" task like this
shadowJar {
baseName = 'DocumentIndexer'
classifier = null
version = project.version
exclude("logback/*test*")
}
or configuring "jar" task like this:
jar {
manifest {
attributes 'Class-Path': '/libs/a.jar'
attributes 'Main-Class': 'core.ConsoleIOHandler'
}
exclude("logback/*test*")
}
... just refuses to work: the file logback-test.xml is still there in the jar.
I got the answer from the forums at gradle.org.
The basic answer is that the "test" logback config file should go under src/test/resources and the "production" config file should go under src/main/resources. This way the former will be excluded from the jar.
The answerer also said the "resources" is one of the roots from which relative paths are specified.
configurations {
provided
compile.extendsFrom provided
}
dependencies {
provided 'WHATEVER' // Packages you don't need to add to jar
provided 'Other WHATEVER' // Packages you don't need to add to jar
shadow 'OTHER' // Packages you need to add to jar
shadow 'Another OTHER' // Packages you need to add to jar
}
shadowJar {
configurations = [project.configurations.shadow] // ***
}
as mentioned here
line *** is the way to tell shadow what dependencies to include in jar

Filter class files from compiled sourcesets to be added in a JAR in Gradle/Groovy

I'm trying to include the compiled .class files from Project1 into the jar for Project2 since my project structure requires it to be done. For that, in the build.gradle for Project2, I write :
jar {
from project(':Project1').sourceSets.main.output.classesDir
}
Which successfully does what I had to do. But, I now want to filter some of the classes that are added based on path and/or some pattern. For example, to include only delegate files, I tried this :
jar {
from project(':Project1').sourceSets.main.output.classesDir {
include '**/*Delegate*.class'
}
}
But unfortunately it doesn't work. Is there a way to achieve this in Gradle/Groovy?
Using Gradle 2.12, the following works for me (this is build.gradle for Project 2):
task myBuild(type: Jar) {
baseName "myjar"
from project(':Project1').sourceSets.main.output.classesDir,
{ include "**/*Delegate*.*" }
}
From the doc for Jar.from, note that it takes 2 arguments (hence, the comma is used).
Thanks Michael
Although I got my answer as well, I was just missing a parantheses. The correct and working code goes something like this :
jar {
from (project(':Project1').sourceSets.main.output.classesDir) {
include '**/*Delegate*.class'
}
}

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.

Copy files over before jarring

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.

Resources