How to include all files from jar into war using Gradle - gradle

I was trying plugins:
io.freefair.war-overlay - but it just overlay one war to another,
waroverlay - it has appropriate option "includeWarJars true" but it
does't works for me.
Currently I'm trying write script:
dependencies {
/* jar, his files I would like to include in war */
compile project(':my_jar_1')
}
war {
/* Step 1. Copy all from my_jar_1 into WEB-INF/classes */
into('WEB-INF/classes') {
from configurations.compile
.filter { it.name.startsWith("my_jar_1") }
.collect { zipTree(it).matching { exclude 'META-INF/**/*.*' }}
}
/* Step 2. Deleting jar from war WEB-INF/lib. I got stuck here. It println, but doesn't delete jar */
doLast {
zipTree('build/libs/war_1-0.0.0.war').files.each {
if (it.path.endsWith('.jar')) {
delete it
println 'DELETED ' + it.path
}
}
}
}
Could somebody tell me how to make it work?
Or maybe smb know more elegant solution?
Also I was trying to declare my own configuration
configurations { overlay }
dependencies {
overlay project(':my_jar_1')
}
war {
into('WEB-INF/classes') {
from configurations.overlay
...
But it shows error
FAILURE: Build failed with an exception.
What went wrong: Failed to capture snapshot of input files for task 'war' property 'rootSpec$1$1' during up-to-date check.
Failed to create MD5 hash for file '/home/user/projects/OveralJarToWar/my_jar_1/build/libs/my_jar_1-1.0-SNAPSHOT.jar'.

The content of WEB-INF/lib and WEB-INF/classes is configured by single property classpath of war task. According to documentation:
Any JAR or ZIP files in this classpath are included in the WEB-INF/lib directory. Any directories in this classpath are included in the WEB-INF/classes directory
So, in your case, the classpath should be modified as follow
war {
def myJar = project(':my_jar_1').jar.outputs
def myClassesAndResources = project(':my_jar_1').sourceSets.main.output
classpath = classpath - myJar + myClassesAndResources
}

Related

How do I build a fat jar (bundle) with Bndtools in a Gradle project?

I am currently trying to create a bundle with bnd in a Gradle project.
The idea was to try getting the list of jar dependencies with Gradle and modify the jar task to add the libs inside the bundle.
Let's say, I would like to remove the includeresource.
-includeresource: lib/jsoup.jar=jsoup-1.14.3.jar
Bundle-ClassPath: ., lib/jsoup.jar
I tried some variations of:
jar {
duplicatesStrategy = 'EXCLUDE'
from {
configurations.runtimeClasspath.findAll {
it.name.endsWith('jar')
}.collect { println it.name; zipTree(it) }
}
}
I can see the name of the jar being printed, but not included inside the bundle, (I know zipTree would expand).
Suggestions from https://discuss.gradle.org/t/how-to-include-dependencies-in-jar/19571/16 do not seem to be valid for bnd, and I suspect bnd overrides the jar task somehow.
A suggestion as:
jar {
def libBuildDir = mkdir "${buildDir}/resources/main/lib"
copy {
from { configurations.jarLibs }
into { libBuildDir }
}
}
Would be perfect, but it does not seem to work for bundles.
Any ideas?

Gradle - Copy folder into jar

In my gradle.build I have the following code in order to copy the content of a folder into the jar during the build process
sourceSets {
main {
resources {
srcDirs = ["build/swagger-ui-myapp/"]
}
output.resourcesDir = "build/resources/main/swagger-ui-myapp"
}
}
The content of the folder ends up in the BOOT-INF/classes/ folder in the jar. But I don't want the content of the folder in that directory, I want the files to be inside the original folder, so I want them inside BOOT-INF/classes/swagger-ui-myapp.
How can I achieve this?
I wouldn't change the resources to do that. instead, I would just configure the bootJar task:
bootJar {
dependsOn(taskWhichGeneratesTheBuildSwaggerUiMyapp)
bootInf {
into("classes/swagger-ui-myapp") {
from("$buildDir/swagger-ui-myapp")
}
}
}

Fat Jar expands dependencies with Gradle Kotlin DSL

I am trying to build a fat jar using the following in my Kotlin based gradle file.
val fatJar = task("fatJar", type = Jar::class) {
baseName = "safescape-lib-${project.name}"
// manifest Main-Class attribute is optional.
// (Used only to provide default main class for executable jar)
from(configurations.runtimeClasspath.map({ if (it.isDirectory) it else zipTree(it) }))
with(tasks["jar"] as CopySpec)
}
tasks {
"build" {
dependsOn(fatJar)
}
}
However, the fat jar has all the dependencies expanded out. I would like to have the jars included as is in a /lib directory but I cannot work out how to achieve this.
Can anyone give any pointers as to how I can achieve this?
Thanks
Well you are using zipTree in that map part of the spec, and it behaves according to the documentation: it unzips the files that are not a directory.
If you want the jars in /lib, replace your from with:
from(configurations.runtimeClasspath) {
into("lib")
}
In case anyone is using kotlin-multiplatform plugin, the configuration is a bit different. Here's a fatJar task configuration assuming JVM application with embedded JS frontend from JS module:
afterEvaluate {
tasks {
create("jar", Jar::class).apply {
dependsOn("jvmMainClasses", "jsJar")
group = "jar"
manifest {
attributes(
mapOf(
"Implementation-Title" to rootProject.name,
"Implementation-Version" to rootProject.version,
"Timestamp" to System.currentTimeMillis(),
"Main-Class" to mainClassName
)
)
}
val dependencies = configurations["jvmRuntimeClasspath"].filter { it.name.endsWith(".jar") } +
project.tasks["jvmJar"].outputs.files +
project.tasks["jsJar"].outputs.files
dependencies.forEach { from(zipTree(it)) }
into("/lib")
}
}
}

Gradle: Overwrite file in WAR

I'm trying to replace a file in WAR file generated with Gradle.
Files structure:
- nodes
- staging
- localConfig.yml
- logback.groovy
- grails-app
- conf
- application.yml
- logback.groovy
I want to copy files from nodes/staging to WEB-INF/classes in the final WAR when I execute gradle script with parameter -Pnode=staging.
This is my approach:
war {
if (project.hasProperty('node')) {
from("stacks/${project.node}") {
include('localConfig.yml')
include('logback.groovy')
into('WEB-INF/classes')
}
}
}
This gradle script will copy localConfig.yml to WEB-INF/classes, however the logback.groovy is not replaced.
How can I set up gradle to replace duplicate files instead of keeping the original ones?
I think you'll need to use the classpath method to add to WEB-INF/classes
eg:
war {
if (project.hasProperty('node')) {
classpath "stacks/${project.node}/localConfig.yml", "stacks/${project.node}/logback.groovy"
}
}
Or perhaps
war {
if (project.hasProperty('node')) {
classpath fileTree("stacks/${project.node}")
}
}

Gradle: ear deploymentDescriptor - Exclude module from application.xml

I have the following in my gradle build file. My problem is that log4j.properties is being added as an ejb module in application.xml, despite my attempt to remove it from the xml per the thread here:
http://forums.gradle.org/gradle/topics/ear_plugin_inserts_unneeded_ejb_modules_in_the_application_xml_ear_descriptor
apply plugin: 'ear'
ear {
deploymentDescriptor {
applicationName = 'ourapp'
displayName = 'ourapp'
initializeInOrder = true
//This doesn't work:
withXml { xml ->
xml.asNode().module.removeAll { it.ejb.text.equals('log4j.properties') }
}
}
//Add log4j.properties to ear root
from('../../lib/log4j.properties', 'log4jProperties')
}
dependencies
{
deploy 'javax:javax.jnlp:1.2'
deploy 'com.oracle:ojdbc6:1.6.0'
earlib 'org.apache:apache-log4j:1.2.16'
}
How can I get the gradle to exclude log4j.properties from application.xml?
EDIT
This is causing a failure to start up in my application server (JBoss 6.0.0) because it doesn't know what to do with log4j.properties. I can work around it by manually creating my application.xml file, but that makes for another thing that has to be maintained. Any assistance would be welcome!
This code works for me. You need to protect the 'remove' method with an 'if' block because the closure is called multiple times. I found that the first time its called, log4jNode is set to 'null'.
withXml {
def log4jNode = asNode().module.find { it.ejb.text() == 'log4j.properties' }
if (log4jNode) {
asNode().remove( log4jNode )
}
}

Resources