Search code examples
javaeclipsegradlests-springsourcetoolsuitegradle-eclipse

Having Spring Gradle dependency container before JRE container results in compilation errors


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.


Solution

  • 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)
            }
        }
    }