ssindelar
ssindelar

Reputation: 2843

Missing project dependencies in eclipse

I'm currently in the situation of editing to gradle projects( "database" & "masterdata"). Masterdata depends on the database-project. Database is published to a Nexus server from where it is loaded by masterdata as a dependency.

The build.gradle of masterdata

import org.gradle.plugins.ide.eclipse.model.SourceFolder 

apply plugin: "java"
apply plugin: "eclipse"

sourceCompatibility = 1.7
version = '0.1-SNAPSHOT'
group = "net.example"

def nexusHost = "http://nexus:8081"

repositories {
    logger.lifecycle("Configuration: Repositories")
    maven {
          url nexusHost + "/nexus/content/groups/public"
    }
}


dependencies {
    logger.lifecycle("Configuration: Dependencies")

    compile 'net.example:database:0.1-SNAPSHOT' // project where the changes happen
    compile 'com.google.guava:guava:14.0.1'

    testCompile 'ch.qos.logback:logback-classic:1.0.13'
    testCompile 'org.testng:testng:6.8.5'
    testCompile 'org.dbunit:dbunit:2.4.9'
    testCompile 'org.mockito:mockito-all:1.9.5'
    testCompile 'org.easytesting:fest-assert-core:2.0M10'
    testCompile 'org.hsqldb:hsqldb:2.2.9'

}

eclipse.classpath.file {
    beforeMerged { classpath -> 
        classpath.entries.clear()
        logger.lifecycle("Classpath entries cleared")
    }
    whenMerged {  cp -> 
        cp.entries.findAll { it instanceof SourceFolder && it.path.startsWith("src/main/") }*.output = "bin/main" 
        cp.entries.findAll { it instanceof SourceFolder && it.path.startsWith("src/test/") }*.output = "bin/test" 
        cp.entries.removeAll { it.kind == "output" }
        logger.lifecycle("Classpath entries modified")
    }
}

When I change something in the database project it needs a complete build, publish, etc. till I see the changes in the masterdata project. In the company where I previously worked we had a similar setup using maven. There I saw changes in dependencies immediately with out publishing them first. Is this also possible with gradle? Maybe via Multi-Project Builds?

Basically a the following entry is missing from .classpath:

<classpathentry combineaccessrules="false" kind="src" path="/database"/>

Is there a way to automate the generation of it.

Update: As a workaround I add the entry manually to the .classpath

Upvotes: 2

Views: 3923

Answers (1)

ssindelar
ssindelar

Reputation: 2843

I did some additional searching and currently this is only possible with multi-project builds. Basically you need all your projects in one gigantic multi-project build. There you can reference them as you like and get the correct dependencies in eclipse as it seems.

There is a jira issue with a feature request to make that possible without a multi-project build. Custom logic for eclipse will only help with builds in eclipse, because in a gradle build it would use the dependency from the repository, where the changes are missing. You need to make sure that all changed dependencies are build and published before building the main project.

Eclipse workaround:

eclipse.classpath.file {
    whenMerged {  cp -> 
        // remove library dependencies
        def toBeRemoved = cp.entries.findAll { it instanceof Library 
              && ((Library) it).library.path.contains('someProject') }

        //configure the project dependencies:
        def toBeAdded = [ new ProjectDependency('/someProject', null)]

        cp.entries -= toBeRemoved
        cp.entries += toBeAdded
    }
}

This would still fail when doing a manual gradle build, but if you using a CI-system with a good build order you should be fine.

Solution Multi-Project Build:

Creating a Multi-Project build is easier than I thought and it is also possible when the "subproject" is on the same level.

settings.gradle:

includeFlat 'database'

build.gradle:

dependencies {
    ...
    compile project(':database')
    ...           
}

This works well with gradle builds and with eclipse. The only disadvantage is that you always have to checkout the subproject everytime you checkout the project that depends on it. I'm sure someone can build some fancy groovy logic to fix that.

Upvotes: 2

Related Questions