Gradle - Include multiple WAR projects in an EAR - gradle

So I'm trying to create a root level ear project that will include multiple war projects and I can't seem to get it to work. To pare it down to the simplest level, lets suppose I have a directory structure like this:
myEar/
├── build.gradle
├── myWar1
│ ├── build.gradle
│ └── src
│ └── main
│ ├── java
│ │ └── com
│ │ └── foo
│ │ └── hello.java
│ ├── resources
│ └── webapp
│ ├── test.html
│ └── WEB-INF
│ └── web.xml
├── myWar2
│ ├── build.gradle
│ └── src
│ └── main
│ ├── java
│ │ └── com
│ │ └── foo
│ │ └── hello.java
│ ├── resources
│ └── webapp
│ ├── test.html
│ └── WEB-INF
│ └── web.xml
├── settings.gradle
└── src
└── main
└── application
└── application.xml
Each build.gradle file in the myWarX subporjects is simply this:
defaultTasks 'war'
apply plugin: 'war'
When I run gradle from inside the myWar1/2 folder I get the expected output:
jar -xvf myWar1.war
created: META-INF/
inflated: META-INF/MANIFEST.MF
created: WEB-INF/
created: WEB-INF/classes/
created: WEB-INF/classes/com/
created: WEB-INF/classes/com/foo/
inflated: WEB-INF/classes/com/foo/hello.class
inflated: WEB-INF/web.xml
inflated: test.html
Now at the root project level myEar, I have the following settings.gradle file:
include ":myWar1", ":myWar2"
and build.gradle looks like this:
defaultTasks 'assemble'
allprojects {
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'war'
apply plugin: 'ear'
}
dependencies {
deploy project(path: ':myWar1', configuration: 'archives')
deploy project(path: ':myWar2', configuration: 'archives')
}
Now when I run this, it builds an myEar.ear file sure enough but both the war projects are being listed as myWar1/2.ear in the archive. In addition, if I expand out those ear files, it is missing things like the html files and the web.xml:
jar -xvf myEar.ear
created: META-INF/
inflated: META-INF/MANIFEST.MF
inflated: myWar1.ear
inflated: myWar2.ear
inflated: application.xml
inflated: META-INF/application.xml
jar -xvf myWar1.ear
created: META-INF/
inflated: META-INF/MANIFEST.MF
created: com/
created: com/foo/
inflated: com/foo/hello.class
inflated: META-INF/application.xml
It seems like there should be a simple solution to this but I can't for the life of me find it. Any help would be gratly appreciated.
Thanks,
Marcus.

ok I'm an idiot. It was because I am applying the 'ear' plugin to allprojects. If I replace:
allprojects {
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'war'
apply plugin: 'ear'
}
with simply
apply plugin 'ear'
everything works as intended.

Related

Gradle subproject dependency is not resolvable by project that needs it

I have the following project strucuture:
example
├── build.gradle
├── module1
│   ├── build.gradle
│   └── main
│   ├── java
│   │   ├── module-info.java
│   │   └── com.example.module1
│   │   └── Example.java
│   └── resources
│   └── application.yml
└── module2
├── build.gradle
├── main
│   ├── java
│   │   ├── module-info.java
│   │   └── com.example.module2
│   │   └── Example2.java
└── test
module1 build.gradle
repositories {
maven {
url 'http://download.osgeo.org/webdav/geotools/'
name 'Open Source Geospatial Foundation Repository'
}
maven {
url 'https://repo.boundlessgeo.com/main/'
name 'Boundless Maven Repository'
}
maven {
url 'http://repo.boundlessgeo.com/snapshot'
name 'Geotools SNAPSHOT repository'
mavenContent {
snapshotsOnly()
}
}
mavenCentral()
jcenter()
}
dependencies {
implementation "org.geotools:gt-main:$geotoolsVersion"
}
module2 build.gradle (depends on module1)
repositories {
mavenCentral()
jcenter()
}
dependencies {
implementation project(':module1')
}
The problem is that when resolving the dependencies for module2, it is unable to find the transitive dependencies of module1, and so I get the following error:
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ':module2'.
> Could not resolve all files for configuration ':module2:runtimeClasspath'.
> Could not find org.geotools:gt-main:21.2.
Searched in the following locations:
- https://repo.maven.apache.org/maven2/org/geotools/gt-main/21.2/gt-main-21.2.pom
- https://repo.maven.apache.org/maven2/org/geotools/gt-main/21.2/gt-main-21.2.jar
- https://jcenter.bintray.com/org/geotools/gt-main/21.2/gt-main-21.2.pom
- https://jcenter.bintray.com/org/geotools/gt-main/21.2/gt-main-21.2.jar
Required by:
project :module2 > project :module1
It looks like it is only searching for the transitive deps of module1 using the repositories declared in module2 instead of in module1.
Interestingly, if I change the dependency in module2 to:
dependencies {
compileClasspath project(':module1')
}
The dependencies are resolved. However this means that at runtime, module1 is not part of the classpath, so running the application still fails.
How can I fix this?
The problem is that project dependencies do not leak their repository locations when depended on.
The fix is to move the repositories into the root build.gradle. Something like:
subprojects {
repositories {
//https://docs.geotools.org/latest/userguide/build/maven/repositories.html
maven {
url 'http://download.osgeo.org/webdav/geotools/'
name 'Open Source Geospatial Foundation Repository'
}
maven {
url 'https://repo.boundlessgeo.com/main/'
name 'Boundless Maven Repository'
}
}
}
See the following github issues:
https://github.com/gradle/gradle/issues/4106
https://github.com/gradle/gradle/issues/8811

Adding sub project dependency in gradle works weirdly, IntelliJ

I have a gradle multi project.
'root' has 2 sub projects which named 'domain' and 'web'. 'web' needs to use classes which are declared in 'domain' project.
However whenever I add compile project(':domain') into dependencies of 'web'.
Intellij says 'root_main', 'root_test', 'web_main', 'web_test' are not imported from Gradle anymore, which I don't want to.
Could you tell me how I can add dependency 'domain' into 'web'?
The structure is below :
root
├── build.gradle
├── domain
│ ├── build.gradle
│ └── src
│ └── main
│ └── test
│
├── web
│ ├── build.gradle
│ └── src
│ └── main
│ └── test
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
'build.gradle' in root
version '1.0-SNAPSHOT'
allprojects {
group = 'com.sample.projects.multi'
apply plugin: 'java'
apply plugin: 'eclipse'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}
}
'build.gradle' in domain
version '1.0-SNAPSHOT'
dependencies {
}
'build.gradle' in web
version '1.0-SNAPSHOT'
dependencies {
compile project(':domain')
}
For ppl who might have same issue with me, I resolved this by updating Intellij to newer one. Mine was 2017.1 and I updated it to 2018.1.

gradle local jar dependency not working

I am pretty new to gradle.
This is my project configuration
Project
.
├── build.gradle
├── sub-project-1
│   ├── build.gradle
├── tests
│   ├── rest
│   └── unit
│   ├── build.gradle // Lets call this unit_build.gradle
My unit tests have a dependency on derby.jar, and the unit_build.gradle has the following:
dependencies{
..
testCompile fileTree(dir: "${System.getProperty('java.home')}/../db/lib", include: "derby.jar")
testCompile fileTree(dir: "${System.getProperty('java.home')}/../db/lib", include: "derbyclient.jar")
}
Note: We have our own repository and derby is not included in that. So we use it by adding it from local.
This works fine when I run a gradle build, followed by my test task.
But we also publish the jar to a test server and run it there where it fails with a class not found exception on derby.
What can be the reason? What should be done to fix this?
Gradle version - 1.12
this happens because you choose wrong target dependency configuration. I mean testCompile, instead of this you should use: testRuntime or testRuntimeClasspath

Gradle issue in inherit properties

I have a spring project build by gradle. I upgraded gradle from 1.7 to 2.13
Project Structure
Project
├─ modules
│ └───apps
│ ├─service-engine
│ │ └──build.gradle
│ └─ build.gradle
└─ build.gradle
settings.gradle file
include 'modules:apps:service-engine',
Root build script
def prepareWar(war, project) {
//do somthing here
}
build script in apps module
subprojects {
apply plugin: 'war'
}
build script in service-engine
project.ext.set('moduleName', 'Service-Engine')
prepareWar(war, project)
But it gives error
What went wrong: A problem occurred evaluating project >':modules:apps:service-engine'.
Could not find property 'war' on project ':modules:apps:service-engine'.
It works fine with gradle 1.7, I could not find the reason for this error.
Please anybody can help me?
Adding build.gradle file in modules and add subprojects {
apply plugin: 'war'} to build script work for me.

Gradle: Adding publish task of submodule as dependency to another submodule

My project layout is like this
A
├── B
│   ├── build.gradle
│   └── Example-0.0.1.jar
├── build.gradle
├── C
│   ├── build.gradle
│   └── src
│   └── main
│   └── java
│   └── com
│   └── sample
│   └── Hello.java
└── settings.gradle
Now, B uses maven-publish to publish Example-0.0.1.jar to local maven archives (i.e ~/.m2/repositories)
C is a java project. The Hello.java file uses the Example jar file.
I am using gradle 2.2 to build this project.
I have
$ cat A/build.gradle
allprojects {
repositories {
mavenCentral()
mavenLocal()
}
}
and
$ cat A/settings.gradle
include ':B'
include ':C'
and
$ cat A/B/build.gradle
apply plugin: 'maven-publish'
publishing {
publications {
maven(MavenPublication) {
groupId 'com.example'
artifactId 'abc'
version '0.0.1'
artifact 'Example-0.0.1.jar'
}
}
}
and
$ cat A/C/build.gradle
apply plugin: 'java'
apply plugin: 'maven'
dependencies {
compile project(':B')
compile 'com.example:abc:0.0.1'
}
Now, whenever I run any gradle command, I get the following error:
$ gradle tasks
Execution failed for task ':tasks'.
> Could not determine the dependencies of task ':C:compileJava'.
Is there any way such that task B:publishToMavenLocal be run before building of C in order to include the jar?
I was also stuck with the same issue.
Figured out a way to achieve this. I added following to parent build.gradle file and everything is now working as expected.
project(':project-B').tasks.compileJava.dependsOn project(':project-A').tasks.install
So now when i am executing the build, artifacts of project-A is being installed to local repository and then project-B is able to take them from there. Good Luck!!

Resources