Skip to content

Commit

Permalink
Ensure projects can be imported into Eclipse IDE with JDK 17
Browse files Browse the repository at this point in the history
Prior to this commit, the Spring Framework projects could not be
imported into Eclipse IDE when using JDK 17 to build the projects.

The primary obstacle is the fact that Eclipse enforces a strict
"no split packages between the unnamed module and a system module" rule
when building with a "modular JDK" (such as JDK 17).

Resources:

- https://bugs.eclipse.org/bugs/show_bug.cgi?id=536928
- https://bugs.openjdk.java.net/browse/JDK-8215739
- http://mail.openjdk.java.net/pipermail/jigsaw-dev/2018-December/014077.html
- https://stackoverflow.com/questions/51094274/eclipse-cant-find-xml-related-classes-after-switching-build-path-to-jdk-10/53824670#53824670

Since the bug (JDK-8215739) has not been fixed in OpenJDK, the strict
"no split packages" rule does not apply to the Java compiler used in
Spring Framework's Gradle build or the compiler in IntelliJ IDEA. Hence,
this issue only arrises when building the framework in Eclipse IDE.

This commit addresses this issue in the following affected projects.

- spring-oxm: removal of the dependency on XPP3 which publishes
    javax.xml.namespace.QName as part of the JAR. The QName type is
    also published by the java.xml JDK 17 system module. To make the
    tests pass, we have switched to using the DomDriver instead of the
    XppDriver in our XStream tests.

- spring-test: HtmlUnit has a transitive dependency on xml-apis which
    publishes several packages also published by java.xml JDK 17 system
    module. Thus, we have explicitly excluded the transitive dependency
    on xml-apis for our `optional` configuration.

See gh-27407
  • Loading branch information
sbrannen committed Sep 22, 2021
1 parent b808b53 commit a247b83
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 10 deletions.
4 changes: 2 additions & 2 deletions gradle/ide.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import org.gradle.plugins.ide.eclipse.model.SourceFolder
apply plugin: 'eclipse'

eclipse.jdt {
sourceCompatibility = 1.8
targetCompatibility = 1.8
sourceCompatibility = 17
targetCompatibility = 17
}

// Replace classpath entries with project dependencies (GRADLE-1116)
Expand Down
6 changes: 5 additions & 1 deletion import-into-eclipse.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
This document will guide you through the process of importing the Spring Framework
projects into Eclipse or the Spring Tool Suite (_STS_). It is recommended that you
have a recent version of Eclipse. As a bare minimum you will need Eclipse with full Java
8 support, Eclipse Buildship, and the Groovy plugin.
17 support, Eclipse Buildship, and the Groovy plugin.

The following instructions have been tested against [STS](https://spring.io/tools) 4.12.0
([download](https://github.com/spring-projects/sts4/wiki/Previous-Versions#spring-tools-4120-changelog))
Expand All @@ -12,6 +12,10 @@ The instructions should work with the latest Eclipse distribution as long as you
[Buildship](https://marketplace.eclipse.org/content/buildship-gradle-integration). Note
that STS 4 comes with Buildship preinstalled.

If you are using Eclipse 4.21, you will need to install
[Java 17 Support for Eclipse 2021-09 (4.21)](https://marketplace.eclipse.org/content/java-17-support-eclipse-2021-09-421)
from the Eclipse Marketplace.

## Steps

_When instructed to execute `./gradlew` from the command line, be sure to execute it within your locally cloned `spring-framework` working directory._
Expand Down
1 change: 0 additions & 1 deletion spring-oxm/spring-oxm.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ dependencies {
optional("com.thoughtworks.xstream:xstream")
testImplementation(project(":spring-context"))
testImplementation(testFixtures(project(":spring-core")))
testImplementation("org.ogce:xpp3")
testImplementation("org.codehaus.jettison:jettison") {
exclude group: "stax", module: "stax-api"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver;
import com.thoughtworks.xstream.io.json.JsonWriter;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import com.thoughtworks.xstream.security.AnyTypePermission;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -84,6 +86,7 @@ void createMarshaller() {
marshaller = new XStreamMarshaller();
marshaller.setTypePermissions(AnyTypePermission.ANY);
marshaller.setAliases(Collections.singletonMap("flight", Flight.class.getName()));
marshaller.setStreamDriver(new DomDriver("UTF-8", new XmlFriendlyNameCoder()));
flight.setFlightNumber(42L);
}

Expand Down Expand Up @@ -139,7 +142,7 @@ void marshalStreamResultWriter() throws Exception {
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
marshaller.marshal(flight, result);
assertThat(XmlContent.from(writer)).isSimilarTo(EXPECTED_STRING);
assertThat(XmlContent.from(writer)).isSimilarToIgnoringWhitespace(EXPECTED_STRING);
}

@Test
Expand All @@ -148,7 +151,7 @@ void marshalStreamResultOutputStream() throws Exception {
StreamResult result = new StreamResult(os);
marshaller.marshal(flight, result);
String s = os.toString("UTF-8");
assertThat(XmlContent.of(s)).isSimilarTo(EXPECTED_STRING);
assertThat(XmlContent.of(s)).isSimilarToIgnoringWhitespace(EXPECTED_STRING);
}

@Test
Expand Down Expand Up @@ -254,7 +257,7 @@ void aliasesByTypeStringClassMap() throws Exception {

Writer writer = new StringWriter();
marshaller.marshal(flight, new StreamResult(writer));
assertThat(XmlContent.from(writer)).isSimilarTo(EXPECTED_STRING);
assertThat(XmlContent.from(writer)).isSimilarToIgnoringWhitespace(EXPECTED_STRING);
}

@Test
Expand All @@ -267,7 +270,7 @@ void aliasesByTypeStringStringMap() throws Exception {

Writer writer = new StringWriter();
marshaller.marshal(flight, new StreamResult(writer));
assertThat(XmlContent.from(writer)).isSimilarTo(EXPECTED_STRING);
assertThat(XmlContent.from(writer)).isSimilarToIgnoringWhitespace(EXPECTED_STRING);
}

@Test
Expand All @@ -276,7 +279,7 @@ void fieldAliases() throws Exception {
Writer writer = new StringWriter();
marshaller.marshal(flight, new StreamResult(writer));
String expected = "<flight><flightNo>42</flightNo></flight>";
assertThat(XmlContent.from(writer)).isSimilarTo(expected);
assertThat(XmlContent.from(writer)).isSimilarToIgnoringWhitespace(expected);
}

@Test
Expand Down Expand Up @@ -351,7 +354,7 @@ void annotatedMarshalStreamResultWriter() throws Exception {
flight.setFlightNumber(42);
marshaller.marshal(flight, result);
String expected = "<flight><number>42</number></flight>";
assertThat(XmlContent.from(writer)).isSimilarTo(expected);
assertThat(XmlContent.from(writer)).isSimilarToIgnoringWhitespace(expected);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;

import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import com.thoughtworks.xstream.security.AnyTypePermission;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand All @@ -55,6 +57,7 @@ public class XStreamUnmarshallerTests {
public void createUnmarshaller() {
unmarshaller = new XStreamMarshaller();
unmarshaller.setTypePermissions(AnyTypePermission.ANY);
unmarshaller.setStreamDriver(new DomDriver("UTF-8", new XmlFriendlyNameCoder()));
Map<String, Class<?>> aliases = new HashMap<>();
aliases.put("flight", Flight.class);
unmarshaller.setAliases(aliases);
Expand Down
9 changes: 9 additions & 0 deletions spring-test/spring-test.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ dependencies {
testRuntimeOnly("com.sun.xml.bind:jaxb-impl")
}

// Prevent xml-apis from being used so that the corresponding XML APIs from
// the JDK's `java.xml` module are used instead. This allows spring-test to
// build in Eclipse IDE which fails to compile if there is a split package
// between a JDK system module and the unnamed module (for JARs on the
// classpath).
configurations.optional {
exclude group: "xml-apis", module: "xml-apis"
}

test {
description = "Runs JUnit 4, JUnit Jupiter, and TestNG tests."
useJUnitPlatform {
Expand Down

0 comments on commit a247b83

Please sign in to comment.