Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Referencing classes in Gradle's API jar that are also in the JDK cause compilation errors in Eclipse when building with Java 9 and later #19577

Open
wilkinsona opened this issue Jan 14, 2022 · 4 comments
Labels
a:bug in:api-evolution Bytecode upgrades, multi-gradle-version support

Comments

@wilkinsona
Copy link
Contributor

Expected Behavior

A project that depends on Gradle's API jar should build cleanly in Eclipse when using Java 9+.

Current Behavior

Compilation fails when trying to, for example, use code in javax.xml.parsers due to the package being split between the unnamed and java.xml modules.

Context

The generated Gradle API jar contains packages and classes that are part of the JDK. These split packages cause compilation failures in Eclipse. It does not fail on the command line which, as per this mailing list discussion, is due to a bug in the JDK. When the JDK bug is fixed, similar failures will occur with javac.

This problem prevents compilation of Spring Boot's buildSrc on its current main branch in Eclipse. Our buildSrc plugins use code in various javax.xml packages and it does not compile in Eclipse with Java 17.

IMO, Gradle's API jar should not contain classes and packages that are also part of the JDK.

Steps to Reproduce

Import the project in this zip file into Eclipse. I'm using 2021-09 but I believe it'll occur in other versions of Eclipse as well. You should see two errors:

DocumentBuilderFactory cannot be resolved to a type	                                        Example.java	/java-xml-split-package/src/main/java/com/example	line 7	Java Problem
The package javax.xml.parsers is accessible from more than one module: <unnamed>, java.xml	Example.java	/java-xml-split-package/src/main/java/com/example	line 3	Java Problem

Your Environment

Build scan URL: scans.gradle.com is unavailable

I don't think this problem is environment-specific. FWIW, I'm using Eclipse 2021-09 on macOS with Temurin-17+35 (build 17+35).

@donat donat assigned donat and unassigned donat Jan 14, 2022
@jbartok jbartok added in:building-gradle gradle/gradle build and removed to-triage labels Jan 17, 2022
@loetifuss
Copy link

Also having this issue. Our suite of Gradle plugins doesn't compile when imported with Eclipse Buildship and JDK 11. I can workaround this issue by limiting the module path of the Eclipse projects using the code below. The projects will compile now when "javax.xml" module is excluded.
Unfortunately this doesn't really help since now my Mockito tests throw ClassNotFoundExceptions for "java.beans.IntrospectionException" which is contained in the "java.desktop" module. The "java.desktop" module can't be added since it has a dependency on "javax.xml".

Is there any way to get this working in Eclipse and JDK 11? It seems to be working in Intellij IDEA.

pluginManager.withPlugin('eclipse') {
	eclipse {
		classpath {
			file {
				whenMerged {
					def jre = entries.find { it.path.contains 'org.eclipse.jdt.launching.JRE_CONTAINER' }
					jre.entryAttributes['module'] = 'true'
					jre.entryAttributes['limit-modules'] = '<ENTER_DESIRED_MODULES'
				}
			}
		}
	}
}

@infosuitemka
Copy link

Also have same issue, after finally being able to lift project baseline to Java 11. Everywhere we have custom Gradle tasks present and thus have the gradle API jar in the compile classpath. As we use the xml APIs, the java.xml module is required.

@jskov-jyskebank-dk
Copy link

I see the same problem trying to work on Gradle plugins in Eclipse targeting java 17.

Fortunately, it is possible to work around. The below works for me with Gradle 8.2.1, java 17, and Eclipse 2023-03.

// Workaround for https://github.com/gradle/gradle/issues/19577
//
// Makes a shaded copy of the gradle-api jar-file and switches the Eclipse classpath to use it.
// There is a per-root-project shaded file to allow for different shading configurations in different projects.
task makeShadedGradleApi(type: Zip) {
    def gradleVersion = project.gradle.gradleVersion
    def cacheDir = project.gradle.gradleUserHomeDir.toPath().resolve('caches').resolve(gradleVersion).resolve('generated-gradle-jars')
    def fileName = 'shaded-api-' + Integer.toHexString(project.rootDir.hashCode()) + '.jar'
    def shadedApiFile = cacheDir.resolve(fileName).toFile()
    def apiFile = cacheDir.resolve('gradle-api-' + gradleVersion + '.jar')

    archiveFile.set(shadedApiFile)
    from project.zipTree(apiFile)
    exclude "org/w3c/**/*"

    doFirst {
        logger.lifecycle("Shading $apiFile into $shadedApiFile")
    }
}

tasks.eclipseClasspath.dependsOn(makeShadedGradleApi)

eclipse {
    classpath {
        file {
            withXml {
                def cp = it.asNode()
                // Replace gradle-api library dependency with the shaded archive
                cp
                    .classpathentry
                    .findAll { e -> e.@kind == 'lib' && e.@path.contains('gradle-api') }
                    .each { e -> 
                        def c = e.clone()
                        c.@path = tasks.makeShadedGradleApi.archivePath

                        cp.remove(e)
                        cp.append(c)
                    }
            }
        }
    }
}

@infosuitemka
Copy link

infosuitemka commented Jul 26, 2023 via email

@ov7a ov7a added in:api-evolution Bytecode upgrades, multi-gradle-version support and removed in:building-gradle gradle/gradle build labels Mar 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a:bug in:api-evolution Bytecode upgrades, multi-gradle-version support
Projects
None yet
Development

No branches or pull requests

8 participants