Search code examples
javaeclipsegradleear

Gradle generate Eclipse project EAR project


I'm migrating a legacy project from ant to gradle (to use its dependency management and build features) and I'm facing a problem when generating the eclipse projects. The big problem today is because the project has some subprojects that are split into war and jar packages to deploy into a single ear. This is made by ant today. To use gradle I split the eclipse projects into separate jar and war projects. So I have the following structure:

ProjectRoot
-lib
-Project1.jar
-Project1.war
-Project2.jar
-Project3.war

And here's my gradle file:

apply plugin: 'ear'
def jboss_home = '/home/augusto/Development/servers/jboss6X' 
def deploy_name = 'default'

allprojects {
    repositories {
        mavenCentral()
    }
    apply plugin: 'eclipse'
    apply plugin: 'eclipse-wtp'
}

dependencies {
    deploy project(path: 'Project1.jar', configuration: 'archives')
    deploy project(path: 'Project1.war', configuration: 'archives')
    deploy project(path: 'Project2.jar', configuration: 'archives')
    deploy project(path: 'Project2.war', configuration: 'archives')
    earlib fileTree(dir: 'lib', include: '*.jar')
}

ear {
    libDirName = "lib"
    deploymentDescriptor {
        applicationName = "MyApp"
        initializeInOrder = true
        displayName = "MyApp"
        module("Project1.jar", "java")
        module("Project2.jar", "java")
        webModule("Project1.war", "/Project1")
        webModule("Project2.war", "/Project2")
    }
}

project('MyJarLib') {
    apply plugin: 'java'
    dependencies {
        compile files('../lib/ajar.jar')
        compile fileTree(dir: jboss_home + '/common/lib', include: '*.jar')
        compile fileTree(dir: jboss_home + '/client', include: '*.jar')
        compile fileTree(dir: jboss_home + '/lib', include: '*.jar')
        compile fileTree(dir: jboss_home + '/server/' + deploy_name + '/lib', include: '*.jar')
    }
}

project('Project1.jar') {
    apply plugin: 'java'
    dependencies {
        compile 'org.apache.poi:poi:3.2-FINAL', 'jdom:jdom:1.1'
        compile project(':MyJarLib.jar')
    }
}

project('Project1.war') {
    apply plugin: 'war'
}

project('Project2.jar') {
    apply plugin: 'java'
    dependencies {
        compile 'net.sf.jasperreports:jasperreports:3.7.0', 'jdom:jdom:1.1'
        compile project(':MyJarLib.jar')
    }
}

project('Project2.war') {
    apply plugin: 'war'
}

I've put the ear plugin in the sub projects to deploy it to server using eclipse. If I let just jar, I cannot deploy it to server using eclipse (and I want to do this to use the hot deploy feature from jboss 6). Our team has big productivity problem to maitain this application because of ant builds. It takes almost 15 minutes to test a feature because they can't use hot deploy... The problem with eclipse: it does not generate a single ear in its deploy. It deploys the packages separately and the server fails to deploy. The problem with the gradle build: it is generating the right structure, but it is creating application.xml files inside each jar project (because of the ear plugin). I use only the root application.xml. Can you help me solve both this problems? Thanks.

EDIT

I've managed to make eclipse deploy my project right using the tips in the comments. In all java projects I've put this configuration:

apply plugin: 'ear'
ear.onlyIf { false }
ear {
    //appDirName 'src/main/java'
    libDirName '../lib'
}

sourceSets {
    main {
    java {
        srcDir 'src/main/application'
    }
    }
}
eclipse.wtp.facet {
    facet name: 'jst.ejb', version: '3.1'
    facet name: 'java', version: '1.6'
}
eclipse.classpath.file{
    withXml {
    def nodes = it.asNode().children().findAll{it.@kind == 'lib'}
    nodes.each {
        if(it.attributes[0] == null)
            it.appendNode('attributes').appendNode('attribute', [name:'org.eclipse.jst.component.dependency', value: '../lib'])
        else
            it.attributes[0].attribute[0].@value = '../lib'
    }
    }
}

I've put the ear plugin, so gradle generates the project ready to deploy in eclipse. The ear.onlyIf { false } makes gradle not generate the artifact in ear structure. After this I've changed the eclipse preferences to set the facet of the project to EJB and changed the classpath entries to deploy the dependencies in the ear lib directory instead of the root of the ear. My problem now is in the build from gradle. When I call gradle ear it is generating lots of dependency errors due the fact that the web container library is not in the classpath... So I have a lot of classnotfound exceptions. If I put all the classes as dependencies from my project, it will mess with the eclipse classpath (and deploy). The question is: Is there a way to provide a provided dependency for java projects in gradle and is there an easy way to provide all those jars from jboss instead of each one?


Solution

  • I've managed to make all work. Using the workarounds in my edit part of the question and some points of this article. Here's what I have to do:

    configurations {
        provided
    }
    
    sourceSets {
        main {
        compileClasspath += configurations.provided
        compileClasspath += configurations.compile
        compileClasspath += configurations.runtime
        java {
            srcDir 'src/main/application'
        }
        }
    }
    

    This made possible to use provided in the dependencies of all my projects and it does not mess with the eclipse project.