Gradle war plugin : exclude - gradle

I have some difficulties in understanding following built.gradle script
war {
archiveName = 'myapps.war'
from ( 'src/main/webapp/WEB-INF/struts' ) {
exclude '**/struts.properties'
into 'WEB-INF/classes'
}
exclude 'WEB-INF/properties'
exclude 'WEB-INF/struts'
}
After simple look , we can say that do not add struts.properites in generated war. Then what is meaning of exclude properties and struts directory in subsequent lines?

It seems to be so: the first, is to copy everything from src/main/webapp/WEB-INF/struts into WEB-INF/classes of artifact, but exclude while copying any struts.properties files. And the second is to exlude from artifact 2 folders WEB-INF/properties and WEB-INF/struts (as for WEB-INF/struts, it's content is already copied to WEB-INF/classes)

Related

Gradle Ear plugin should not copy resources into .ear root

I have the following folder structure of my gradle module:
src
main
application
META-INF
application.xml
was.policy
was.webmodule
java
resources
image.bmp
logback.xml
... other files, properties
webapp
My goal is to build an ear archive, which will contain only Tclient.war and META-INF. However, gradle copies all resource files to the ear root.
Gradle documentation about Ear Plugin says that:
The default behavior of the Ear task is to copy the content of
src/main/application to the root of the archive. If your application
directory doesn’t contain a META-INF/application.xml deployment
descriptor then one will be generated for you.
So, It's not really clear why it puts resources into the root. Maybe, it work's like the org.gradle.api.tasks.bundling.Jar task and I should override this behaviour in some way?
Here is my partially build.gradle file:
jar {
description 'Creates tclient.jar'
archiveBaseName = 'tclient'
destinationDirectory = file('src/main/webapp/WEB-INF/lib')
from sourceSets.main.output
include '**/*'
include '**/*.properties'
include '**/*.cmd'
}
ear{
description = "Ear archive for WebSphere server"
archiveBaseName = 'Tclient'
appDirName('src/main/application')
// workaround to exclude classes from ear root
rootSpec.exclude('**/de/**')
rootSpec.exclude('**/org/**')
}
war {
archiveFileName = 'Tclient.war'
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
webInf {
from configurations.natives into 'lib/bin'
}
// do not put compiled classes inside WEB-INF/classes
rootSpec.exclude('**/de/**')
rootSpec.exclude('**/org/**')
rootSpec.exclude('urlrewrite*.dtd')
from(jar) {
into 'WEB-INF/lib'
}
}
dependencies {
// Place .war inside .ear root
deploy files(war)
....
}
The possible workaround is to exclude redundant resources from the rootspec:
ear{
description = "Ear archive for WebSphere server"
archiveBaseName = 'Tclient'
appDirName('src/main/application')
// workaround to exclude classes from ear root
rootSpec.exclude('**/de/**')
rootSpec.exclude('**/org/**')
// workaround
rootSpec.exclude('*.properties')
rootSpec.exclude('*.xml')
rootSpec.exclude('*.dtd')
rootSpec.exclude('*.bmp')
}
However, I'm finding this workaround a little bit ugly and it's a dirty hack.

How to exclude all the files from configuration folders in ShadowJar

I would like to exclude all configuration xml files from /conf folder. However, with my shadowJar setting below (see line ***), I still see names.xml (which is a xml file under /conf) is included in the jar.
If I specifically exclude the names.xml file. I wouldn't see it but I will have to put exclude for each file under /conf folder.
Is there a way I can use something like exclude "conf/*.xml" to achieve this?
My project structure is like below:
myproject
- conf
- src
-java
-spring
and my shadowJar definition is:
shadowJar {
version = '0.0.1'
mergeServiceFiles()
append("META-INF/spring.schemas")
append("META-INF/spring.handlers")
manifest {
attributes "Main-Class": "com.common.server.Main.java"
}
exclude "names.xml" //this is working.
exclude "conf/*" //***this is not working
}
I am a newbie to shadowJar and I tried several ways to exclude files under a folder with no luck, could someone please give me a hint?
dependencies {
exclude "META-INF/*.SF"
exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA"
exclude "**/*.html"
exclude "module-info.*"
exclude "Log4j-*"
exclude "mime.types"
exclude "VersionInfo.java"
}
Please try in this format.

How to exclude a file in war with gradle

My build.gradle includes the following (in addition to other stuff):
war {
from("src/main/application") {
into("WEB-INF/application")
}
}
Along the way, it copies src/main/webapp into the root of the war file. Cool. Problem is I have one file that I’d like it to exclude from that copy. Let’s call it abc.jar. How can I make gradle continue to do everything it’s doing when creating a war file but exclude abc.jar from being copied from src/main/webapp to the root of the war file?
Thanks!
Blake McBride
You can try this,
war {
rootSpec.exclude("**/abc.jar")
}

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/**'
}

Gradle dependency destination on non-jar config file

I can create a dependency to something other than a jar file like this:
dependencies {
compile files("../other-project/config.txt")
}
The above works fine, except that config.txt ends up in the WEB-INF/lib folder of my war file. Instead I need it to be in WEB-INF/classes in the war file, and in src/main/resources for jettyRun.
How can I control where the dependency ends up? Or am I going about this the wrong way?
I can also solve this with a copy task, but this really is a dependency in that I don't need the file updated unless it changes. An unconditional copy would work, but I'd rather do this the right way.
The war task (as configured by the war plugin) puts dependencies into WEB-INF/lib, the web project's own code/resources into WEB-INF/classes, and web app content (which by default goes into src/main/webapp) into WEB-INF. Other content can be added by explicitly configuring the war task. For example:
war {
into("WEB-INF/classes") {
from "../other-project/config.txt"
}
}
One way to make this work with embedded Jetty (though maybe not the most convenient during development) is to use jettyRunWar instead of jettyRun. Another solution that comes to mind, particularly if the content to be added resides in its own directory, is to declare that directory as an additional resource directory of the web project (sourceSets.main.resources.srcDir "../other-project/someResourceDir"). This is in fact an alternative to configuring the war task. If the web project already has a dependency on the other project, you could instead configure an additional resource directory for that project.
Let's say you have configured a multi-project build with the following directory and file structure:
/combined-war
/main-project
/src
/webapp
/WEB-INF
web.xml
build.gradle
/other-project
/resources
/WEB-INF
/classes
config.txt
build.gradle
build.gradle
In order to allow jettyRun to combine the contents of the webapp directory from main-project with the contents of the resources directory in other-project you need to add a workaround to your build.gradle of main-project (I've adapted the one posted by the user siasia on gist).
Adding the same directory content to the war file is quite simple and is documented in the Gradle User Guide and and the DSL reference.
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'jetty'
import org.gradle.api.plugins.jetty.internal.JettyPluginWebAppContext
def newResourceCollection(File... resources) {
def script = '''
import org.mortbay.resource.ResourceCollection
new ResourceCollection(resources)
'''
def shell = new GroovyShell(JettyPluginWebAppContext.class.classLoader)
shell.setProperty("resources", resources as String[])
return shell.evaluate(script)
}
jettyRun.doFirst {
jettyRun.webAppConfig = new JettyPluginWebAppContext()
jettyRun.webAppConfig.baseResource = newResourceCollection(
// list the folders that should be combined
file(webAppDirName),
file("${project(':other-project').projectDir}/resources")
)
}
war {
from("${project(':other-project').projectDir}/resources")
}
Whenever you execute gradle jettyRun a new ResourceCollection is created that combines the given directories. Per default Jetty locks (at least on Windows) all the files it's serving. So, in case you want to edit those files while Jetty is running take a look at the following solutions.
Update
Since other-project in this case is not another Gradle project the two tasks in build.gradle should look like that:
jettyRun.doFirst {
jettyRun.webAppConfig = new JettyPluginWebAppContext()
jettyRun.webAppConfig.baseResource = newResourceCollection(
file(webAppDirName),
file("$projectDir/../other-project/resources")
)
}
war {
from("$projectDir/../other-project/resources")
}
I'm not aware of any solution that adds only one file (e.g. config.txt). You'll always have to add a complete directory.
As I mentioned above, it's simple enough to do an unconditional copy that solves the problem. Again, not the question I originally asked. But here's my solution that works for both war and jettyRun tasks:
processResources.doFirst {
copy {
from '../other-project/config.txt'
into 'src/main/resources'
}
}

Resources