Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gradle EAR with transitive libs from other projects

A Gradle build-script creates an EAR file with some jars and one war inside. This is all done in Maven before and is now a subject of migration to Gradle.

ENV:

  • Gradle 1.12
  • Groovy 2.2.1
  • Java 1.7.0_60 Oracle
  • Eclipse Kepler SR 2

Problem:

... is simple: It works so far - the ear plugin creates the ear file with all module files included from

deploy project(:core)

within the "dependencies" section and the "core-0.0.1.jar" is at ear-root and an module entry has been created in the application.xml. Now I discovered that the runtime libs are not included in the ear file. So I changed (according to docu) the inclusion to

earlib project(:core)

and found the libs within the libs directory as stated in the "libDirName" property from ear plugin configuration. But now there is no module entry within the application.xml AND the "core-0.0.1.jar" is within the libs directory.

Desired

We want the core-0.0.1.jar as a module within the ear root and all runtime libraries within the libs directory - WITHOUT the jar from the module itself! (core-0.0.1.jar is not a war !) Like so...

[APP.EAR]  
|--/libs  
|  |-- log4j.jar  
|  |-- commons.jar  
|  |>> app-core.0.0.1.jar <<== NOT !
|  
|-app-core-0.0.1.jar <== OK!  
|-app-xy-0.0.1.jar  
|-app-abc-0.0.1.war 

Question

Is this a fundamental lack of understanding of EAR concepts on my side or why does Gradle by itself do not behave the way we want? Or might this little, easy step require a more complex configuration?

like image 975
marmelin Avatar asked Jun 23 '14 12:06

marmelin


2 Answers

I found the solution myself.. after trying many ,many "solutions" from other posts. Here is what I did, and it is a combination of others:

In the CORE PROJECT

I created a provided configuration - so these dependencies wont show up in the compile configuration - and add it to the classpath of the project. So they are in the compile classpath but not in the compile configuration! I did that for all my projects.

// Libs need for compilation, but not to be published with EAR 
configurations { provided } 

dependencies {
    provided 'javax:javaee-api:6.0'
    provided 'org.slf4j:slf4j-api:1.7.7'

    compile 'com.application:application-common:1.4.5-SNAPSHOT'
}

configurations.provided.each { logger.debug("PROVIDED::core:  $it\n") }

// Include the PROVIDED libs into compile classpath
sourceSets { 
    main {  compileClasspath += configurations.provided }
}

In the EAR PROJECT

I had to include "deploy project.." for the module entry and root jar. For the transitive libs I used the "earlib project ..., configuration: 'compile'" to ensure, that only the files that are within the compilation configuration (and therefore they are mandatory for running the jar) are copied into the ear.

apply plugin: 'ear' 

dependencies { 
    // INCLUDE AS A MODULE with entry in application.xml 
    deploy project(path: ':core')
    // INCLUDE the TRANSITIVE LIBRARIES FOR RUNTIME not provided
    earlib project(path: ':core', configuration: 'compile')
} 

ear { .... 
} 

Thats all!

For this I have to say .... GRADLE ROCKS!!!!

like image 171
marmelin Avatar answered Nov 13 '22 16:11

marmelin


The accepted solution fails if there are compile time dependencies between ear modules. This is how I solved it in Gradle 2.14. Hope this helps someone.

apply plugin: 'ear'

def deployedModules = [ 'projectA', 'projectB', 'projectC' ]

deployedModules.forEach {
    def projectPath = ":${it}"

    evaluationDependsOn(projectPath)

    dependencies.add('deploy', dependencies.project(path: projectPath,
                                                    configuration: 'archives'))
    findProject(projectPath).configurations.runtime.allDependencies.forEach {
        boolean isEarModule = it instanceof ProjectDependency &&
                (it as ProjectDependency).dependencyProject.name in deployedModules
        if (!isEarModule) {
            dependencies.add('earlib', it)
        }
    }
}
like image 45
Tilo Avatar answered Nov 13 '22 16:11

Tilo