diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java index a229be897a7..cb33ebcdece 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java @@ -680,7 +680,7 @@ PackageBinding combineWithPackagesFromOtherRelevantModules(PackageBinding curren } List otherRelevantModules(char[][] declaringModuleNames) { - if (isUnnamed() && declaringModuleNames != null) { + if ((isUnnamed() || isAutomatic()) && declaringModuleNames != null) { // unnamed module reads all named modules, // so all modules declaring the given package are relevant: return Arrays.stream(declaringModuleNames) diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java index bc922ac00ca..db9a61cb073 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java @@ -21,6 +21,7 @@ import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; @@ -6356,4 +6357,123 @@ public void accept(SplitPackageBinding t) { SplitPackageBinding.instanceListener = null; } } + + public void testGH2748() throws IOException { + File outputDirectory = new File(OUTPUT_DIR); + Util.flushDirectoryContent(outputDirectory); + + List modules = new ArrayList<>(); + // compile two explicit modules + for (String m : new String[] { "A", "B" }) { + String out = OUTPUT_DIR + File.separator + "module" + m + File.separator + "bin"; + String src = OUTPUT_DIR + File.separator + "module" + m + File.separator + "src"; + modules.add(out); + + List files = new ArrayList<>(); + writeFileCollecting(files, src, + "module-info.java", + "module split.module" + m + " {\n" + + " exports pkg.bug.split.sub" + m + ";\n" + + "}"); + writeFileCollecting(files, Paths.get(src, "pkg", "bug", "split", "sub" + m).toString(), + "SubModule" + m + ".java", + "package pkg.bug.split.sub" + m + ";\n" + + "\n" + + "public class SubModule" + m + " {\n" + + " \n" + + "}"); + + StringBuilder buffer = new StringBuilder(); + buffer.append("-d " + out ) + .append(" -9 ") + .append(" -proc:none ") + .append(" -classpath \"") + .append(Util.getJavaClassLibsAsString()) + .append("\" "); + runConformModuleTest( + files, + buffer, + "", + "", + false); + } + + // compile a jar which serves as auto-module + String[] sources = { + "pkg/bug/service/IService.java", + """ + package pkg.bug.service; + + public interface IService { + + }""", + }; + String jarPath = OUTPUT_DIR + File.separator + "autoModule.jar"; + Util.createJar(sources, jarPath, "1.8"); + modules.add(jarPath); + + // compile the main code which requires the other modules + String outFinal = OUTPUT_DIR + File.separator + "modularizedApp" + File.separator + "bin"; + String srcFinal = OUTPUT_DIR + File.separator + "modularizedApp" + File.separator + "src"; + + List files = new ArrayList<>(); + writeFileCollecting(files, srcFinal, + "module-info.java", + """ + module split.app {\t + requires autoModule; + requires split.moduleA; + requires split.moduleB; + \t + exports pkg.bug.app; + }"""); + writeFileCollecting(files, Paths.get(srcFinal, "pkg", "bug", "app").toString(), + "App.java", + """ + package pkg.bug.app; + + import pkg.bug.split.subA.SubModuleA; + + public class App { + public static void main(String[] args) { + new SubModuleA(); + } + }"""); + writeFileCollecting(files, Paths.get(srcFinal, "pkg", "bug", "service", "impl").toString(), + "AppServiceImpl.java", + """ + package pkg.bug.service.impl; + + import pkg.bug.service.IService; + + public class AppServiceImpl implements IService { + + }"""); + + String modulePath = String.join(File.pathSeparator, modules); + StringBuilder buffer = new StringBuilder(); + buffer.append("-d " + outFinal ) + .append(" -9 ") + .append(" -proc:none ") + .append(" --module-path \"") + .append(Util.getJavaClassLibsAsString()) + .append(File.pathSeparatorChar) + .append(modulePath) + .append("\" ") + .append(" --add-modules autoModule "); + runConformModuleTest( + files, + buffer, + "", + """ + ---------- + 1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/modularizedApp/src/module-info.java (at line 2) + requires autoModule; + ^^^^^^^^^^ + Name of automatic module 'autoModule' is unstable, it is derived from the module's file name. + ---------- + 1 problem (1 warning) + """, + false, outFinal); + } }