Building Gradle EARs from pre-built WARs - gradle

I'm using Gradle and want to build an EAR that includes a pre-built WAR file found in a repository. I got things working like this:
dependencies
{
earlib 'PathName:NameOfPreBuiltWar:Version#war'
}
ear
{
libDirName '/'
}
This seems to work perfectly, but isn't the way earlib or libDirName were intended to be used. Is there a better way?

The ear plugin also provides a deploy configuration, so this should be sufficient:
dependencies {
deploy 'PathName:NameOfPreBuiltWar:Version#war'
}

Related

Unable to exclude Jar from grails war

I am using grails 4.0
In my build.gradle, I have following entry.
war {
exclude("**/abc-1.0.0.jar", "**/xyz-1.0.0.jar")
}
But for some reason, both these jars are included in the war file, when I run the command grails prod war
I have tried varies options, but nothing seems to work.
are you sure you're not trying to limit dependencies...?
ex.
dependencies {
...
compile("org.grails:grails-plugin-interceptors"){
exclude(module: 'org.slf4j:slf4j-api:1.7.22')
exclude(module: 'org.slf4j:jcl-over-slf4j:1.7.22')
}
}

Eclipse: How can I have gradle dependencies deployed to Tomcat

I'm creating a web project using Gradle (buildship) in Eclipse (WTP). I've put the libraries I need as "implementation" dependencies in my build.gradle, however they are not copied to Tomcat when I try to run the project from within Eclipse. When I build the WAR file (with gradle war), however, all the jar files are there.
I can't find anywhere the solution for this. It's beeing awful to manually (and redundantly) copying every jar and its dependency to WEB-INF/libs just to be able to run the app from Eclipse).
I've found a workaround here: https://github.com/eclipse/buildship/issues/496
It's adding this to build.gradle:
eclipse {
wtp {
component {
libConfigurations += [configurations.runtimeClasspath]
}
}
}
With this everything gets properly deployed.
UPDATE!
Gradle 5.3 has just been released and includes a fix for this issue and the hack above is not needed anymore.
The only thing that worked for me was changing
dependencies {
implementation group: 'org.projectlombok', name: 'lombok', version: '1.18.4'
}
too
dependencies {
compile group: 'org.projectlombok', name: 'lombok', version: '1.18.4'
}

Gradle: how to exclude jar from an ear file?

I have a question regarding excluding a jar file from an ear artifact. My project has the following modules:
project
- ejb_module
- war_module
- ear_module
- other_module
In my ear_module/build.gradle :
dependencies {
deploy project(ejb_module)
earlib project(ejb_module)
deploy project(war_module)
earlib project(war_module)
}
The problem is how I exclude the jar artifact produced from the war_module.
The war_module produces both war and jar artifact. The reason I need the jar artifact is that my other_module depends on it.
A complicated factor is that the war_module has some dependencies that needs to go via earlib.
So my question is how I exclude the war_module.jar from the ear file? It is included both at root and in APP-INF/lib.
I presume in your war_module you are applying both war and java plugins to get a .war. and .jar artifacts ?
Try:
deploy project(path: 'war_module', configuration: 'archives')
earlib project(path: 'war_module', configuration: 'archives')
It should pick up a .war only because if look into the Gradle war plugin code you can see that it overrides the default output of the project, if java plugin was included.
Additionally, war plugin uses java plugin to compile your code under the hood.
You, of course, can simply exclude the artefact from the build by using
config (project){exclude module: 'name'}
but I think this is not the best you can do here.
Try looking into providedRuntime and runtimeOnly configurations depending on which version of Gradle do you use.
If the artefact is used for compilation then compileOnly etc.
This configuration used in dependecies{} will use the jar but will not be going to expose it anywhere else then it should not land in any artefact that you build and this is probably what would fit you the most in your case, but the question wasn't asking about this it's just an advice.
Assume your EAR contains an another existing jar, said xxx.yyy.zzz.jar.
In your ear project's build.gradle, add the following
ext.replacement = 'your.group:xxx.yyy.zzz:your.version'
configurations.all {
resolutionStrategy {
eachDependency { DependencyResolveDetails details ->
// remove to.be.excluded.jar
if (details.requested.group == 'your.group' &&
details.requested.name == 'to.be.excluded' &&
details.requested.version == 'your.version') {
details.useTarget replacement
}
}
}
}
This way, the to.be.excluded.jar will be replaced by xxx.yyy.zzz.jar, that virtually removes it from the EAR.

Gradle include jar produced by another project in war

Currently I have two projects with gradle build.gradle. The first is going to create a fat jar file, which I would like to include in a war file. I thought compiling it would be enough, but it doesn't seem to be ending up in the /lib directory of my war file. Anyone have thoughts I am quite new to gradle.
dependencies {
compile project(':JarProject')
providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
providedCompile 'org.apache.tomcat:tomcat-jsp-api:7.0.55'
}
war {
archiveName 'WarProject.war'
from 'JarProject/build/libs'
webXml = file('src/web.xml')
}
Does the second project war need to be in providedRuntime? Or should I publish the jar from the other project in the local maven repo and include it that way?
The War task essentially behaves like a CopyTask with regards to stuff it packs in the war, so the documentation on working with files is useful. In essence, I think you need something like (untested):
from fileTree('JarProject/build/libs') {
into("lib")
}
That being said, using mavenLocal() and publishing there also works, but it can lead to unexpected results when the war includes some old version from local, picking up the jar explicitly from the file system like above is better.
I think the elegant solution would be to use multi project builds and project level dependencies. You would have the two builds as separate projects of the same Gradle build and add the "jar project" as a regular compile dependency.
How have you declared the dependency? I assume you have a multi-project build with subprojects A and B, both using the War plugin. I made an experiment using Gradle 2.4 and if I declare B/build.gradle like this:
apply plugin: 'war'
dependencies {
compile project(':A')
}
then B.war contains WEB-INF/lib/A.jar. If you correctly follow conventions of Gradle War plugin (place web resources in A/src/main/webapp/ and code-related resources in A/src/main/resources/), then A.jar should contain what you want.
see this

How to remove a class from the classpath after Gradle build

I have a jar that I need to include in my dependencies...
compile files('WebContent/WEB-INF/lib/wls-api.jar')
There's a class inside that jar that is causing trouble that I want to not be on the classpath when I run my app after a gradle build.
How do I get rid of that class after doing a gradle build?
it's a bit trickier than it looks like at first blink; because you will modify the original input!
You should create a configuration for the your modified artifact (this is a proof of concept build.gradle snipplet):
apply plugin: 'java'
task filteredJar(type:Jar){
// you may use a remote artifact by configuring a separate configuration for it and using a jar from:
// configurations.theConfig.resolvedConfiguration.resolvedArtifacts
from zipTree('a.jar')
archiveName 'xx.jar'
// use standard Copy/Sync like filters here, for the example i used
include '**/Tool.class'
}
configurations {
z1
}
artifacts {
z1 filteredJar
}
dependencies {
compile project(path: getPath(), configuration: 'z1')
}
or..alternatively, and might be more preferably:
put this magic into some separate project which will repackage this jar into a usebale one.

Resources