revert change breaking module resolution from output path; explicit '--patch-module' compiler option enables compilation with 'module-path' instead of 'classpath'

GitOrigin-RevId: 5c22cf1b937a783aa02e298ea995c863dc8c567c
This commit is contained in:
Eugene Zhuravlev
2025-02-18 14:03:03 +01:00
committed by intellij-monorepo-bot
parent 9818164a11
commit e381284d13
9 changed files with 68 additions and 20 deletions

View File

@@ -0,0 +1,7 @@
package aaa;
public class Main {
public static void main(String[] args) {
System.out.println("Hello");
}
}

View File

@@ -0,0 +1,7 @@
package aaa;
public class Main {
public static void main(String[] args) {
Class<?> srvClass = ppp.api.Service.class;
}
}

View File

@@ -2,7 +2,10 @@
package org.jetbrains.jps.javac; package org.jetbrains.jps.javac;
import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.util.io.FileUtilRt;
import org.jetbrains.annotations.*; import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.java.JavaSourceTransformer; import org.jetbrains.jps.builders.java.JavaSourceTransformer;
import org.jetbrains.jps.javac.Iterators.BooleanFunction; import org.jetbrains.jps.javac.Iterators.BooleanFunction;
import org.jetbrains.jps.javac.Iterators.Function; import org.jetbrains.jps.javac.Iterators.Function;
@@ -146,11 +149,7 @@ public final class JpsJavacFileManager extends ForwardingJavaFileManager<Standar
throw new IllegalArgumentException("Invalid kind: " + kind); throw new IllegalArgumentException("Invalid kind: " + kind);
} }
final JavaFileObject fo = super.getJavaFileForInput(location, className, kind); // todo final JavaFileObject fo = super.getJavaFileForInput(location, className, kind); // todo
boolean isModuleInfo = "module-info".equals(className); if (fo == null && !"module-info".equals(className)) {
if (location == StandardLocation.CLASS_OUTPUT && isModuleInfo) {
return null;
}
if (fo == null && !isModuleInfo) {
// workaround javac bug (missing null-check): throwing exception here instead of returning null // workaround javac bug (missing null-check): throwing exception here instead of returning null
throw new FileNotFoundException("Java resource does not exist : " + location + '/' + kind + '/' + className); throw new FileNotFoundException("Java resource does not exist : " + location + '/' + kind + '/' + className);
} }

View File

@@ -106,6 +106,7 @@ public final class JavaBuilder extends ModuleLevelBuilder {
private static final String PROCESSOR_MODULE_PATH_OPTION = "--processor-module-path"; private static final String PROCESSOR_MODULE_PATH_OPTION = "--processor-module-path";
private static final String SOURCE_OPTION = "-source"; private static final String SOURCE_OPTION = "-source";
private static final String SYSTEM_OPTION = "--system"; private static final String SYSTEM_OPTION = "--system";
private static final String PATCH_MODULE_OPTION = "--patch-module";
private static final Set<String> FILTERED_OPTIONS = Set.of( private static final Set<String> FILTERED_OPTIONS = Set.of(
TARGET_OPTION, RELEASE_OPTION, "-d" TARGET_OPTION, RELEASE_OPTION, "-d"
); );
@@ -471,12 +472,15 @@ public final class JavaBuilder extends ModuleLevelBuilder {
final Iterable<? extends File> classPath; final Iterable<? extends File> classPath;
final ModulePath modulePath; final ModulePath modulePath;
final Iterable<? extends File> upgradeModulePath; final Iterable<? extends File> upgradeModulePath;
if (moduleInfoFile != null) { // has modules if (moduleInfoFile != null || Iterators.contains(options, PATCH_MODULE_OPTION)) { // has modules or trying to patch a module
final ModulePathSplitter splitter = MODULE_PATH_SPLITTER.get(context); final ModulePathSplitter splitter = MODULE_PATH_SPLITTER.get(context);
final Pair<ModulePath, Collection<File>> pair = splitter.splitPath( final Pair<ModulePath, Collection<File>> pair = splitter.splitPath(
moduleInfoFile, outs.keySet(), ProjectPaths.getCompilationModulePath(chunk, false), collectAdditionalRequires(options) moduleInfoFile, outs.keySet(), ProjectPaths.getCompilationModulePath(chunk, false), collectAdditionalRequires(options)
); );
final boolean useModulePathOnly = Boolean.parseBoolean(System.getProperty(USE_MODULE_PATH_ONLY_OPTION))/*compilerConfig.useModulePathOnly()*/;
// always add everything to ModulePath if module path usagfe is forced or '--patch-module' is explicitly specified in the command line
final boolean useModulePathOnly = moduleInfoFile == null || Boolean.parseBoolean(System.getProperty(USE_MODULE_PATH_ONLY_OPTION))/*compilerConfig.useModulePathOnly()*/;
if (useModulePathOnly) { if (useModulePathOnly) {
// in Java 9, named modules are not allowed to read classes from the classpath // in Java 9, named modules are not allowed to read classes from the classpath
// moreover, the compiler requires all transitive dependencies to be on the module path // moreover, the compiler requires all transitive dependencies to be on the module path

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.jps.incremental.java; package org.jetbrains.jps.incremental.java;
import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Pair;
@@ -83,11 +83,11 @@ public final class ModulePathSplitter {
myModuleNameSearch = moduleNameSearch; myModuleNameSearch = moduleNameSearch;
} }
public Pair<ModulePath, Collection<File>> splitPath(File chunkModuleInfo, Set<? extends File> chunkOutputs, Collection<? extends File> path) { public Pair<ModulePath, Collection<File>> splitPath(@Nullable File chunkModuleInfo, Set<? extends File> chunkOutputs, Collection<? extends File> path) {
return splitPath(chunkModuleInfo, chunkOutputs, path, Collections.emptySet()); return splitPath(chunkModuleInfo, chunkOutputs, path, Collections.emptySet());
} }
public Pair<ModulePath, Collection<File>> splitPath(File chunkModuleInfo, Set<? extends File> chunkOutputs, Collection<? extends File> path, Collection<String> addReads) { public Pair<ModulePath, Collection<File>> splitPath(@Nullable File chunkModuleInfo, Set<? extends File> chunkOutputs, Collection<? extends File> path, Collection<String> addReads) {
if (myModuleFinderCreateMethod == null) { if (myModuleFinderCreateMethod == null) {
// the module API is not available // the module API is not available
return Pair.create(ModulePath.create(path), Collections.emptyList()); return Pair.create(ModulePath.create(path), Collections.emptyList());
@@ -140,14 +140,16 @@ public final class ModulePathSplitter {
return fName; return fName;
} }
private Set<String> collectRequired(File chunkModuleInfo, Iterable<? extends File> path) { private Set<String> collectRequired(@Nullable File chunkModuleInfo, Iterable<? extends File> path) {
final Set<String> result = new HashSet<>(); final Set<String> result = new HashSet<>();
// first, add all requires from chunk module-info if (chunkModuleInfo != null) {
final JavaModuleDescriptor chunkDescr = new JavaProjectBuilder(new OrderedClassLibraryBuilder()).addSourceFolder(chunkModuleInfo.getParentFile()).getDescriptor(); // first, add all requires from chunk module-info
for (JavaModuleDescriptor.JavaRequires require : chunkDescr.getRequires()) { final JavaModuleDescriptor chunkDescr = new JavaProjectBuilder(new OrderedClassLibraryBuilder()).addSourceFolder(chunkModuleInfo.getParentFile()).getDescriptor();
final JavaModule rm = require.getModule(); for (JavaModuleDescriptor.JavaRequires require : chunkDescr.getRequires()) {
if (rm != null) { final JavaModule rm = require.getModule();
result.add(rm.getName()); if (rm != null) {
result.add(rm.getName());
}
} }
} }
for (File file : path) { for (File file : path) {

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.ether; package org.jetbrains.ether;
import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.JavaSdkVersion;
@@ -158,6 +158,24 @@ public class Java9Test extends IncrementalTestCase {
assertTrue(classpath.contains(new File(libDir, "module_lib_3.jar"))); assertTrue(classpath.contains(new File(libDir, "module_lib_3.jar")));
} }
public void testPartialModuleCompilation() {
setupInitialProject();
final Map<String, JpsModule> modules = setupModules();
assertEquals(1, modules.size());
final JpsModule module = modules.values().iterator().next();
final File libDir = new File(getAbsolutePath("lib"));
for (File jarFile : libDir.listFiles((dir, name) -> name.endsWith(".jar"))) {
JpsLibrary lib = addLibrary(jarFile.getName(), jarFile);
JpsModuleRootModificationUtil.addDependency(module, lib, JpsJavaDependencyScope.COMPILE, false);
}
doBuild(CompileScopeTestBuilder.rebuild().allModules()).assertSuccessful();
modify(0);
doBuild(CompileScopeTestBuilder.make().allModules()).assertSuccessful();
}
public void testExplodedAutoModule() { public void testExplodedAutoModule() {
setupInitialProject(); setupInitialProject();

View File

@@ -93,6 +93,9 @@ class MultiReleaseOutputTest : MavenCompilingTestCase() {
} }
/*
todo: commented until IDEA-367746 is fixed
@Test @Test
fun `test java module compilation`() = runBlocking { fun `test java module compilation`() = runBlocking {
createProjectSubFile("src/main/java/module-info.java", """ createProjectSubFile("src/main/java/module-info.java", """
@@ -107,7 +110,7 @@ class MultiReleaseOutputTest : MavenCompilingTestCase() {
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1</version> <version>1</version>
<properties> <properties>
<maven.compiler.release>9</maven.compiler.release> <maven.compiler.release>9</maven.compiler.release>
</properties> </properties>
<build> <build>
<plugins> <plugins>
@@ -123,6 +126,10 @@ class MultiReleaseOutputTest : MavenCompilingTestCase() {
<compileSourceRoots> <compileSourceRoots>
<root>${'$'}{project.basedir}/src/main/java-additional</root> <root>${'$'}{project.basedir}/src/main/java-additional</root>
</compileSourceRoots> </compileSourceRoots>
<compilerArgs>
<arg>--patch-module</arg>
<arg>project=${'$'}{project.basedir}/src/main/java-additional</arg>
</compilerArgs>
</configuration> </configuration>
</execution> </execution>
</executions> </executions>
@@ -145,4 +152,5 @@ class MultiReleaseOutputTest : MavenCompilingTestCase() {
assertExists("target/classes/A.class") assertExists("target/classes/A.class")
assertExists("target/classes/B.class") assertExists("target/classes/B.class")
} }
*/
} }