8233332: Need to create exploded tests covering all forms of modules

Reviewed-by: herrick, almatvee
This commit is contained in:
Alexey Semenyuk 2020-11-10 22:36:31 +00:00
parent f2a0bf3ea8
commit d6f1463cb3
3 changed files with 64 additions and 6 deletions

View File

@ -34,10 +34,14 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import jdk.jpackage.test.Functional.ThrowingConsumer;
import jdk.jpackage.test.Functional.ThrowingFunction;
import jdk.jpackage.test.Functional.ThrowingSupplier;
@ -225,7 +229,7 @@ public final class HelloApp {
public static Path createBundle(JavaAppDesc appDesc, Path outputDir) {
String jmodFileName = appDesc.jmodFileName();
if (jmodFileName != null) {
final Path jmodFilePath = outputDir.resolve(jmodFileName);
final Path jmodPath = outputDir.resolve(jmodFileName);
TKit.withTempDirectory("jmod-workdir", jmodWorkDir -> {
var jarAppDesc = JavaAppDesc.parse(appDesc.toString())
.setBundleFileName("tmp.jar");
@ -233,8 +237,7 @@ public final class HelloApp {
Executor exec = new Executor()
.setToolProvider(JavaTool.JMOD)
.addArguments("create", "--class-path")
.addArgument(jarPath)
.addArgument(jmodFilePath);
.addArgument(jarPath);
if (appDesc.isWithMainClass()) {
exec.addArguments("--main-class", appDesc.className());
@ -244,11 +247,50 @@ public final class HelloApp {
exec.addArguments("--module-version", appDesc.moduleVersion());
}
Files.createDirectories(jmodFilePath.getParent());
final Path jmodFilePath;
if (appDesc.isExplodedModule()) {
jmodFilePath = jmodWorkDir.resolve("tmp.jmod");
exec.addArgument(jmodFilePath);
TKit.deleteDirectoryRecursive(jmodPath);
} else {
jmodFilePath = jmodPath;
exec.addArgument(jmodFilePath);
TKit.deleteIfExists(jmodPath);
}
Files.createDirectories(jmodPath.getParent());
exec.execute();
if (appDesc.isExplodedModule()) {
TKit.trace(String.format("Explode [%s] module file...",
jmodFilePath.toAbsolutePath().normalize()));
// Explode contents of the root `classes` directory of
// temporary .jmod file
final Path jmodRootDir = Path.of("classes");
try (var archive = new ZipFile(jmodFilePath.toFile())) {
archive.stream()
.filter(Predicate.not(ZipEntry::isDirectory))
.sequential().forEachOrdered(ThrowingConsumer.toConsumer(
entry -> {
try (var in = archive.getInputStream(entry)) {
Path entryName = Path.of(entry.getName());
if (entryName.startsWith(jmodRootDir)) {
entryName = jmodRootDir.relativize(entryName);
}
final Path fileName = jmodPath.resolve(entryName);
TKit.trace(String.format(
"Save [%s] zip entry in [%s] file...",
entry.getName(),
fileName.toAbsolutePath().normalize()));
Files.createDirectories(fileName.getParent());
Files.copy(in, fileName);
}
}));
}
}
});
return jmodFilePath;
return jmodPath;
}
final JavaAppDesc jarAppDesc;

View File

@ -84,6 +84,10 @@ public final class JavaAppDesc {
}
public String jmodFileName() {
if (isExplodedModule()) {
return bundleFileName;
}
if (bundleFileName != null && bundleFileName.endsWith(".jmod")) {
return bundleFileName;
}
@ -94,6 +98,10 @@ public final class JavaAppDesc {
return bundleFileName != null;
}
public boolean isExplodedModule() {
return bundleFileName != null && bundleFileName.endsWith(".ejmod");
}
public String moduleVersion() {
return moduleVersion;
}
@ -127,7 +135,7 @@ public final class JavaAppDesc {
* Create Java application description form encoded string value.
*
* Syntax of encoded Java application description is
* [(jar_file|jmods_file):][module_name/]qualified_class_name[!][@module_version].
* [(jar_file|jmods_file|exploded_jmods_file):][module_name/]qualified_class_name[!][@module_version].
*
* E.g.: `duke.jar:com.other/com.other.foo.bar.Buz!@3.7` encodes modular
* application. Module name is `com.other`. Main class is
@ -140,6 +148,12 @@ public final class JavaAppDesc {
* `com.another.One`. Application will be
* compiled and packed in `bar.jmod` jmod file.
*
* E.g.: `bar.ejmod:com.another/com.another.One` encodes modular
* application. Module name is `com.another`. Main class is
* `com.another.One`. Application will be
* compiled and packed in temporary jmod file that will be exploded in
* `bar.ejmod` directory.
*
* E.g.: `Ciao` encodes non-modular `Ciao` class in the default package.
* jar command will not put main class attribute in the jar file.
* Default name will be picked for jar file - `hello.jar`.

View File

@ -226,6 +226,8 @@ public final class BasicTest {
@Parameter("com.other/com.other.Hello")
// Modular app in .jmod file
@Parameter("hello.jmod:com.other/com.other.Hello")
// Modular app in exploded .jmod file
@Parameter("hello.ejmod:com.other/com.other.Hello")
public void testApp(String javaAppDesc) {
JavaAppDesc appDesc = JavaAppDesc.parse(javaAppDesc);
JPackageCommand cmd = JPackageCommand.helloAppImage(appDesc);