Skip to content

Commit 5af3279

Browse files
committed
Replace the convolved hack (which was moving files around) by symbolic link.
This hack is needed only when we want to simulate the Maven 3 behaviour for compatibility reasons. This hack is fragile to the case where a module name is a single name (without dot) and that name is the same as the package name. This ambiguity breaks two tests. For allowing the tests to pass, this commit renames "foo" module as "foo.bar".
1 parent 41276aa commit 5af3279

File tree

7 files changed

+28
-57
lines changed

7 files changed

+28
-57
lines changed

src/it/jpms_compile-main-foo-test-bar/src/main/java/module-info.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* under the License.
1818
*/
1919

20-
module foo {
20+
module foo.bar {
2121
requires org.apache.commons.lang3;
2222

2323
exports foo;

src/it/jpms_compile-main-foo-test-bar/src/test/java/bar/BarTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@ void constructor() {
3030
@Test
3131
void moduleNameIsFoo() {
3232
Assertions.assertTrue(Foo.class.getModule().isNamed(), "Foo resides in a named module");
33-
Assertions.assertEquals("foo", Foo.class.getModule().getName());
33+
Assertions.assertEquals("foo.bar", Foo.class.getModule().getName());
3434
}
3535
}

src/it/jpms_compile-main-foo-test-bar/src/test/java/module-info.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
* under the License.
1818
*/
1919

20-
open module bar {
21-
requires foo;
20+
open module bar.biz {
21+
requires foo.bar;
2222
requires java.scripting;
2323
requires org.junit.jupiter.api;
2424
}

src/it/jpms_compile-main-foo-test-foo/src/main/java/module-info.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@
1717
* under the License.
1818
*/
1919

20-
module foo {
20+
module foo.bar {
2121
requires org.apache.commons.lang3;
2222
}

src/it/jpms_compile-main-foo-test-foo/src/test/java/foo/FooTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ void constructor() {
2929
@Test
3030
void moduleNameIsFoo() {
3131
Assertions.assertTrue(Foo.class.getModule().isNamed(), "Foo resides in a named module");
32-
Assertions.assertEquals("foo", Foo.class.getModule().getName());
32+
Assertions.assertEquals("foo.bar", Foo.class.getModule().getName());
3333
}
3434
}

src/it/jpms_compile-main-foo-test-foo/src/test/java/module-info.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* under the License.
1818
*/
1919

20-
open module foo {
20+
open module foo.bar {
2121
// main
2222
requires org.apache.commons.lang3;
2323

src/main/java/org/apache/maven/plugin/compiler/ToolExecutorForTest.java

+21-50
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,10 @@
2424

2525
import java.io.IOException;
2626
import java.io.InputStream;
27-
import java.io.UncheckedIOException;
2827
import java.io.Writer;
2928
import java.lang.module.ModuleDescriptor;
30-
import java.nio.file.FileVisitResult;
3129
import java.nio.file.Files;
3230
import java.nio.file.Path;
33-
import java.nio.file.SimpleFileVisitor;
34-
import java.nio.file.attribute.BasicFileAttributes;
3531
import java.util.ArrayList;
3632
import java.util.HashSet;
3733
import java.util.LinkedHashMap;
@@ -40,7 +36,6 @@
4036
import java.util.Map;
4137
import java.util.Set;
4238
import java.util.StringJoiner;
43-
import java.util.stream.Stream;
4439

4540
import org.apache.maven.api.Dependency;
4641
import org.apache.maven.api.JavaPathType;
@@ -86,6 +81,13 @@ class ToolExecutorForTest extends ToolExecutor {
8681
*/
8782
private final boolean hasTestModuleInfo;
8883

84+
/**
85+
* Whether the tests are declared in their own module. If {@code true},
86+
* then the {@code module-info.java} file of the test declares a name
87+
* different than the {@code module-info.java} file of the main code.
88+
*/
89+
private boolean testInItsOwnModule;
90+
8991
/**
9092
* Whether the {@code module-info} of the tests overwrites the main {@code module-info}.
9193
* This is a deprecated practice, but is accepted if {@link #SUPPORT_LEGACY} is true.
@@ -154,6 +156,7 @@ class ToolExecutorForTest extends ToolExecutor {
154156
if (testModuleName != null) {
155157
overwriteMainModuleInfo = testModuleName.equals(getMainModuleName());
156158
if (!overwriteMainModuleInfo) {
159+
testInItsOwnModule = true;
157160
continue; // The test classes are in their own module.
158161
}
159162
}
@@ -191,10 +194,12 @@ class ToolExecutorForTest extends ToolExecutor {
191194
PathType pathType = JavaPathType.CLASSES;
192195
if (hasModuleDeclaration) {
193196
pathType = JavaPathType.MODULES;
194-
String moduleToPatch = getMainModuleName();
195-
if (!moduleToPatch.isEmpty()) {
196-
pathType = JavaPathType.patchModule(moduleToPatch);
197-
directoryLevelToRemove = outputDirectory.resolve(moduleToPatch);
197+
if (!testInItsOwnModule) {
198+
String moduleToPatch = getMainModuleName();
199+
if (!moduleToPatch.isEmpty()) {
200+
pathType = JavaPathType.patchModule(moduleToPatch);
201+
directoryLevelToRemove = outputDirectory.resolve(moduleToPatch);
202+
}
198203
}
199204
}
200205
dependencies.computeIfAbsent(pathType, (key) -> new ArrayList<>()).add(0, mainOutputDirectory);
@@ -226,7 +231,7 @@ private String getMainModuleName() throws IOException {
226231
*/
227232
@Override
228233
final String inferModuleNameIfMissing(String moduleName) throws IOException {
229-
return moduleName.isEmpty() ? getMainModuleName() : moduleName;
234+
return (!testInItsOwnModule && moduleName.isEmpty()) ? getMainModuleName() : moduleName;
230235
}
231236

232237
/**
@@ -334,53 +339,19 @@ public boolean applyIncrementalBuild(AbstractCompilerMojo mojo, Options configur
334339
@Override
335340
public boolean compile(JavaCompiler compiler, Options configuration, Writer otherOutput) throws IOException {
336341
addModuleOptions(configuration); // Effective only once.
342+
Path delete = null;
337343
try {
344+
if (directoryLevelToRemove != null) {
345+
delete = Files.createSymbolicLink(directoryLevelToRemove, directoryLevelToRemove.getParent());
346+
}
338347
return super.compile(compiler, configuration, otherOutput);
339348
} finally {
340-
if (directoryLevelToRemove != null && Files.exists(directoryLevelToRemove)) {
341-
Path target = directoryLevelToRemove.getParent();
342-
try (Stream<Path> files = Files.list(directoryLevelToRemove)) {
343-
files.forEach((path) -> {
344-
try {
345-
Files.move(path, deleteRecursively(target.resolve(path.getFileName())));
346-
} catch (IOException e) {
347-
throw new UncheckedIOException(e);
348-
}
349-
});
350-
} catch (UncheckedIOException e) {
351-
throw e.getCause();
352-
}
353-
Files.delete(directoryLevelToRemove);
349+
if (delete != null) {
350+
Files.delete(delete);
354351
}
355352
}
356353
}
357354

358-
/**
359-
* Deletes the specified directory recursively.
360-
*
361-
* @param delete the directory to delete
362-
* @return the given directory
363-
*/
364-
private static Path deleteRecursively(Path delete) throws IOException {
365-
if (Files.notExists(delete)) {
366-
return delete;
367-
}
368-
return Files.walkFileTree(delete, new SimpleFileVisitor<Path>() {
369-
@Override
370-
public FileVisitResult postVisitDirectory(Path dir, IOException error) throws IOException {
371-
var result = super.postVisitDirectory(dir, error);
372-
Files.delete(dir);
373-
return result;
374-
}
375-
376-
@Override
377-
public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) throws IOException {
378-
Files.delete(file);
379-
return super.visitFile(file, attributes);
380-
}
381-
});
382-
}
383-
384355
/**
385356
* Separates the compilation of {@code module-info} from other classes. This is needed when the
386357
* {@code module-info} of the test classes overwrite the {@code module-info} of the main classes.

0 commit comments

Comments
 (0)