Reputation: 56
I am converting a Java project from Ant to Gradle. The IDE of choice for our team is Eclipse. I have installed the Spring Gradle plugin for Eclipse, applied the Gradle project nature and enabled dependency management. The result is some compilation errors.
The compilation errors occur because the Gradle dependency container is before the JRE container in the eclipse classpath. Some jars on the classpath contain classes that should come from rt.jar (and they are incompatible with our code, presumably older versions).
When dependency management is disabled gradle dependencies come after the JRE container and it compiles without error. This is also consistent with my use of Eclipse/Maven/m2e where the the Maven dependency container comes after the JRE container in eclipse.
Is this the default behaviour for the plugin (putting the gradle container before the JRE)? Is there a way to change it?
I tried to do it in my build.gradle using the eclipse hooks (whenMerged and withXml) but these seem to execute before the gradle dependencies are replaced with the container entry.
Upvotes: 1
Views: 261
Reputation: 56
Here is my code to swap the containers. It is probably a little verbose for a couple of reasons. 1. I am new to Groovy coming from a Java background. 2. Gradle is new to myself and the team, I want to be clear about what it is doing.
// Swap the order of the JRE and classpathcontainer
// https://issuetracker.springsource.com/browse/STS-4332
task afterEclipseImport(description: "Post processing after project generation", group: "IDE") {
doLast {
def cp = new XmlParser().parse(file(".classpath"))
def container
def cons = cp.classpathentry.findAll { it.@kind == "con" }
cons.find {
if ([email protected]("org.springsource.ide.eclipse.gradle.classpathcontainer")) {
println "found Gradle dependency container"
container = it
} else if ([email protected]("JRE_CONTAINER")) {
if (container == null) {
println "found JRE container before Gradle dependency container, nothing to do"
// Return true to end the loop (return by itself is not enough)
return true
}
println "found JRE container, swap with Gradle dependency container"
container.replaceNode(it)
it.replaceNode(container)
// Return true to end the loop (return by itself is not enough)
return true
}
return false
}
def builder = new StreamingMarkupBuilder()
builder.encoding = "UTF-8"
file(".classpath").withWriter {writer ->
writer << builder.bind { mkp.xmlDeclaration() }
def printer = new XmlNodePrinter(new PrintWriter(writer))
// println cp
printer.print(cp)
}
}
}
Upvotes: 1
Reputation: 3967
There is some controll over the order but it may be not precise enough for you. Right-click on the project and select 'Properties >> Gradle'.
Then select one of the sorting options, such as 'Alphabetically by Path'. After changing this option do a "Gradle >> Refresh All".
If you pick "As returned by BuildScript" which I gather must be what you have. The order will be reversed (Gradle before JRE). There is a bit of a conundrum here that the buildscript does not actually return the "gradle dependencies" container (only its contents) so the order is not really defined by the Build Script.
Unfortunately, you probably have a reason for picking that option and sorting the dependencies inside the container may not actually be a viable solution for you.
If so, there may be a second thing you can try.
When you import the project you the Import Wizard a "Run After" under "Import Options". You might try to use the task specified there to modify the .classpath file at the end of the import (and it will also be executed on refresh).
Finally... one last suggestion. Have you tried BuildShip? Maybe it works better for your projects.
Upvotes: 2