Skip to content

Commit 831cde9

Browse files
Update default set of root modules for unnamed modules (eclipse-jdt#3572)
+ Implement new (simplified) rules as of https://bugs.openjdk.org/browse/JDK-8205169 + New methods to query the default root modules in a version-aware way + Deprecate old version-agnostic methods Fixes eclipse-jdt#2786
1 parent 6117b71 commit 831cde9

File tree

5 files changed

+110
-15
lines changed

5 files changed

+110
-15
lines changed

org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java

+51
Original file line numberDiff line numberDiff line change
@@ -9028,6 +9028,57 @@ public void testIssue23() throws CoreException {
90289028
deleteProject(p1);
90299029
}
90309030
}
9031+
public void testIssue2786_10() throws CoreException {
9032+
// module java.smartcardio is not in default root modules according to old rules of JEP 261
9033+
IJavaProject p10 = createJava10Project("J10", new String[] {"src"});
9034+
p10.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
9035+
try {
9036+
createFolder("/J10/src/p1");
9037+
createFile("/J10/src/p1/X.java",
9038+
"package p1;\n" +
9039+
"import javax.smartcardio.Card;\n" +
9040+
"public class X {\n" +
9041+
" Card card;\n" +
9042+
"}");
9043+
9044+
waitForManualRefresh();
9045+
waitForAutoBuild();
9046+
p10.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
9047+
IMarker[] markers = p10.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
9048+
sortMarkers(markers);
9049+
assertMarkers("unexpected markers",
9050+
"The import javax.smartcardio cannot be resolved\n" +
9051+
"Card cannot be resolved to a type",
9052+
markers);
9053+
} finally {
9054+
deleteProject(p10);
9055+
}
9056+
}
9057+
public void testIssue2786_11() throws CoreException {
9058+
// since JDK-8205169 module java.smartcardio is indeed in default root modules
9059+
IJavaProject p11 = createJava11Project("J11", new String[] {"src"});
9060+
p11.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
9061+
try {
9062+
createFolder("/J11/src/p1");
9063+
createFile("/J11/src/p1/X.java",
9064+
"package p1;\n" +
9065+
"import javax.smartcardio.Card;\n" +
9066+
"public class X {\n" +
9067+
" Card card;\n" +
9068+
"}");
9069+
9070+
waitForManualRefresh();
9071+
waitForAutoBuild();
9072+
p11.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
9073+
IMarker[] markers = p11.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
9074+
assertMarkers("Unexpected Markers",
9075+
"",
9076+
markers);
9077+
} finally {
9078+
deleteProject(p11);
9079+
}
9080+
}
9081+
90319082
protected void assertNoErrors() throws CoreException {
90329083
for (IProject p : getWorkspace().getRoot().getProjects()) {
90339084
int maxSeverity = p.findMaxProblemSeverity(null, true, IResource.DEPTH_INFINITE);

org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java

+13
Original file line numberDiff line numberDiff line change
@@ -6500,11 +6500,24 @@ public static IModuleDescription getAutomaticModuleDescription(IJavaElement elem
65006500
* @param allSystemRoots all physically available system modules, represented by their package fragment roots
65016501
* @return the list of names of default root modules
65026502
* @since 3.14
6503+
* @deprecated This method cannot distinguish strategies for old (9/10) vs new (11+) JDK versions. Please use {@link #defaultRootModules(Iterable, String)}
65036504
*/
6505+
@Deprecated
65046506
public static List<String> defaultRootModules(Iterable<IPackageFragmentRoot> allSystemRoots) {
65056507
return JavaProject.defaultRootModules(allSystemRoots);
65066508
}
65076509

6510+
/**
6511+
* Filter the given set of system roots by the rules for root modules from JEP 261.
6512+
* @param allSystemRoots all physically available system modules, represented by their package fragment roots
6513+
* @param release JDK version to select strategies before / after resolution of https://bugs.openjdk.org/browse/JDK-8205169
6514+
* @return the list of names of default root modules
6515+
* @since 3.41
6516+
*/
6517+
public static List<String> defaultRootModules(Iterable<IPackageFragmentRoot> allSystemRoots, String release) {
6518+
return JavaProject.defaultRootModules(allSystemRoots, release);
6519+
}
6520+
65086521
/**
65096522
* Compile the given module description in the context of its enclosing Java project
65106523
* and add class file attributes using the given map of attribute values.

org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java

+36-14
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,9 @@ public void computePackageFragmentRoots(
741741
if (limitModules != null) {
742742
rootModules = Arrays.asList(limitModules.split(",")); //$NON-NLS-1$
743743
} else if (isUnNamedModule()) {
744-
rootModules = defaultRootModules((Iterable) imageRoots);
744+
String release = JavaCore.ENABLED.equals(getOption(JavaCore.COMPILER_RELEASE, true))
745+
? getOption(JavaCore.COMPILER_COMPLIANCE, true) : null;
746+
rootModules = defaultRootModules((Iterable) imageRoots, release);
745747
}
746748
if (rootModules != null) {
747749
imageRoots = filterLimitedModules(entryPath, imageRoots, rootModules);
@@ -792,30 +794,50 @@ public void computePackageFragmentRoots(
792794
}
793795
}
794796

795-
/** Implements selection of root modules per JEP 261. */
797+
/**
798+
* Implements selection of root modules per JEP 261.
799+
* @deprecated This method cannot distinguish strategies for old (9/10) vs new (11+) JDK versions. Please use {@link #defaultRootModules(Iterable, String)}
800+
*/
801+
@Deprecated
796802
public static List<String> defaultRootModules(Iterable<IPackageFragmentRoot> allSystemRoots) {
803+
return defaultRootModules(allSystemRoots, JavaCore.VERSION_11); // 11 is fix version of https://bugs.openjdk.org/browse/JDK-8205169
804+
}
805+
806+
/**
807+
* Implements selection of root modules per JEP 261.
808+
* @param allSystemRoots all modules found in the JRT system
809+
* @param releaseVersion the release version which decides about the strategy for selecting root modules
810+
*/
811+
public static List<String> defaultRootModules(Iterable<IPackageFragmentRoot> allSystemRoots, String releaseVersion) {
797812
return internalDefaultRootModules(allSystemRoots,
798813
IPackageFragmentRoot::getElementName,
799-
r -> (r instanceof JrtPackageFragmentRoot) ? ((JrtPackageFragmentRoot) r).getModule() : null);
814+
r -> (r instanceof JrtPackageFragmentRoot) ? ((JrtPackageFragmentRoot) r).getModule() : null,
815+
releaseVersion);
800816
}
801817

802-
public static <T> List<String> internalDefaultRootModules(Iterable<T> allSystemModules, Function<T,String> getModuleName, Function<T,IModule> getModule) {
818+
public static <T> List<String> internalDefaultRootModules(Iterable<T> allSystemModules, Function<T,String> getModuleName, Function<T,IModule> getModule, String releaseVersion) {
803819
List<String> result = new ArrayList<>();
820+
boolean beforeJDK8205169 = JavaCore.VERSION_9.equals(releaseVersion) || JavaCore.VERSION_10.equals(releaseVersion);
804821
boolean hasJavaDotSE = false;
805-
for (T mod : allSystemModules) {
806-
String moduleName = getModuleName.apply(mod);
807-
if ("java.se".equals(moduleName)) { //$NON-NLS-1$
808-
result.add(moduleName);
809-
hasJavaDotSE = true;
810-
break;
822+
if (beforeJDK8205169) {
823+
for (T mod : allSystemModules) {
824+
String moduleName = getModuleName.apply(mod);
825+
if ("java.se".equals(moduleName)) { //$NON-NLS-1$
826+
result.add(moduleName);
827+
hasJavaDotSE = true;
828+
break;
829+
}
811830
}
812831
}
813832
for (T mod : allSystemModules) {
814833
String moduleName = getModuleName.apply(mod);
815-
boolean isJavaDotStart = moduleName.startsWith("java."); //$NON-NLS-1$
816-
boolean isPotentialRoot = !isJavaDotStart; // always include non-java.*
817-
if (!hasJavaDotSE)
818-
isPotentialRoot |= isJavaDotStart; // no java.se => add all java.*
834+
boolean isPotentialRoot = true; // since JDK-8205169 all system modules are considered
835+
if (beforeJDK8205169) {
836+
boolean isJavaDotStart = moduleName.startsWith("java."); //$NON-NLS-1$
837+
isPotentialRoot = !isJavaDotStart; // always include non-java.*
838+
if (!hasJavaDotSE)
839+
isPotentialRoot |= isJavaDotStart; // no java.se => add all java.*
840+
}
819841

820842
if (isPotentialRoot) {
821843
IModule module = getModule.apply(mod);

org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrt.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -242,14 +242,18 @@ protected Collection<String> selectModules(Set<String> keySet, Collection<String
242242
result.retainAll(limitModules);
243243
rootModules = result;
244244
} else {
245-
rootModules = JavaProject.internalDefaultRootModules(keySet, s -> s, this::getModule);
245+
rootModules = JavaProject.internalDefaultRootModules(keySet, s -> s, this::getModule, getReleaseVersion());
246246
}
247247
Set<String> allModules = new HashSet<>(rootModules);
248248
for (String mod : rootModules)
249249
addRequired(mod, allModules);
250250
return allModules;
251251
}
252252

253+
protected String getReleaseVersion() {
254+
return null;
255+
}
256+
253257
protected void addRequired(String mod, Set<String> allModules) {
254258
IModule iMod = getModule(mod);
255259
if(iMod == null) {

org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrtWithReleaseOption.java

+5
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ private String getReleaseOptionFromCompliance(String comp) throws CoreException
115115
}
116116
}
117117

118+
@Override
119+
protected String getReleaseVersion() {
120+
return this.release;
121+
}
122+
118123
public void loadModules() {
119124
if (this.fs == null || !this.ctSym.isJRE12Plus()) {
120125
ClasspathJrt.loadModules(this);

0 commit comments

Comments
 (0)