8163116: jlink exclude VM plugin does not fully support cross platform image creation
Reviewed-by: redestad, alanb, mchung
This commit is contained in:
parent
0af4f24e45
commit
f622ccd42d
@ -38,6 +38,7 @@ import java.util.stream.Collectors;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolModule;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
|
||||
@ -98,9 +99,8 @@ public final class ExcludeVMPlugin implements Plugin {
|
||||
* e.g.: /java.base/native/amd64/server/libjvm.so
|
||||
* /java.base/native/server/libjvm.dylib
|
||||
*/
|
||||
private List<ResourcePoolEntry> getVMs(ResourcePool in) {
|
||||
String jvmlib = jvmlib();
|
||||
List<ResourcePoolEntry> ret = in.moduleView().findModule("java.base").get().entries().filter((t) -> {
|
||||
private List<ResourcePoolEntry> getVMs(ResourcePoolModule javaBase, String jvmlib) {
|
||||
List<ResourcePoolEntry> ret = javaBase.entries().filter((t) -> {
|
||||
return t.path().endsWith("/" + jvmlib);
|
||||
}).collect(Collectors.toList());
|
||||
return ret;
|
||||
@ -108,12 +108,13 @@ public final class ExcludeVMPlugin implements Plugin {
|
||||
|
||||
@Override
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
String jvmlib = jvmlib();
|
||||
ResourcePoolModule javaBase = in.moduleView().findModule("java.base").get();
|
||||
String jvmlib = jvmlib(javaBase.descriptor().osName().get());
|
||||
TreeSet<Jvm> existing = new TreeSet<>(new JvmComparator());
|
||||
TreeSet<Jvm> removed = new TreeSet<>(new JvmComparator());
|
||||
if (!keepAll) {
|
||||
// First retrieve all available VM names and removed VM
|
||||
List<ResourcePoolEntry> jvms = getVMs(in);
|
||||
List<ResourcePoolEntry> jvms = getVMs(javaBase, jvmlib);
|
||||
for (Jvm jvm : Jvm.values()) {
|
||||
for (ResourcePoolEntry md : jvms) {
|
||||
if (md.path().endsWith("/" + jvm.getName() + "/" + jvmlib)) {
|
||||
@ -247,21 +248,21 @@ public final class ExcludeVMPlugin implements Plugin {
|
||||
return orig.copyWithContent(content);
|
||||
}
|
||||
|
||||
private static String jvmlib() {
|
||||
private static String jvmlib(String osName) {
|
||||
String lib = "libjvm.so";
|
||||
if (isWindows()) {
|
||||
if (isWindows(osName)) {
|
||||
lib = "jvm.dll";
|
||||
} else if (isMac()) {
|
||||
} else if (isMac(osName)) {
|
||||
lib = "libjvm.dylib";
|
||||
}
|
||||
return lib;
|
||||
}
|
||||
|
||||
private static boolean isWindows() {
|
||||
return System.getProperty("os.name").startsWith("Windows");
|
||||
private static boolean isWindows(String osName) {
|
||||
return osName.startsWith("Windows");
|
||||
}
|
||||
|
||||
private static boolean isMac() {
|
||||
return System.getProperty("os.name").startsWith("Mac OS");
|
||||
private static boolean isMac(String osName) {
|
||||
return osName.startsWith("Mac OS");
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,9 @@
|
||||
* @run main ExcludeVMPluginTest
|
||||
*/
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager;
|
||||
@ -167,6 +170,13 @@ public class ExcludeVMPluginTest {
|
||||
poolMgr.add(
|
||||
ResourcePoolEntry.create("/java.base/native/jvm.cfg",
|
||||
ResourcePoolEntry.Type.NATIVE_LIB, jvmcfgContent));
|
||||
|
||||
// java.base/module-info.class is used by exclude vm plugin
|
||||
// to get current osName(). We read it from jrt-fs and add a
|
||||
// ResourcePoolEntry
|
||||
poolMgr.add(
|
||||
ResourcePoolEntry.create("/java.base/module-info.class",
|
||||
ResourcePoolEntry.Type.CLASS_OR_RESOURCE, getJavaBaseModuleInfo()));
|
||||
for (String in : input) {
|
||||
poolMgr.add(ResourcePoolEntry.create(in,
|
||||
ResourcePoolEntry.Type.NATIVE_LIB, new byte[0]));
|
||||
@ -187,15 +197,19 @@ public class ExcludeVMPluginTest {
|
||||
throw new Exception("Got content " + newContent + " expected " + expectdJvmCfg);
|
||||
}
|
||||
|
||||
if (out.entryCount() != (expectedOutput.length + 1)) {
|
||||
// Apart from native resources, we should find jvm.cfg and
|
||||
// java.base/module-info.class. So, we add 2 here to the
|
||||
// expected count!
|
||||
if (out.entryCount() != (expectedOutput.length + 2)) {
|
||||
out.entries().forEach(m -> {
|
||||
System.err.println(m.path());
|
||||
});
|
||||
throw new Exception("Invalid output size " + out.entryCount() + " expected " + (expectedOutput.length + 1));
|
||||
throw new Exception("Invalid output size " + out.entryCount() + " expected " + (expectedOutput.length + 2));
|
||||
}
|
||||
|
||||
out.entries().forEach(md -> {
|
||||
if (md.path().equals("/java.base/native/jvm.cfg")) {
|
||||
if (md.path().equals("/java.base/native/jvm.cfg") ||
|
||||
md.path().equals("/java.base/module-info.class")) {
|
||||
return;
|
||||
}
|
||||
boolean contained = false;
|
||||
@ -209,7 +223,11 @@ public class ExcludeVMPluginTest {
|
||||
throw new RuntimeException(md.path() + " not expected");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// read java.base/module-info.class from jrt-fs
|
||||
private static Path getJavaBaseModuleInfo() {
|
||||
return Paths.get(URI.create("jrt:/modules/java.base/module-info.class"));
|
||||
}
|
||||
|
||||
private static boolean isWindows() {
|
||||
|
@ -32,8 +32,10 @@
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -87,6 +89,12 @@ public class FileCopierPluginTest {
|
||||
conf.put(FileCopierPlugin.NAME, builder.toString());
|
||||
plug.configure(conf);
|
||||
ResourcePoolManager poolMgr = new ResourcePoolManager();
|
||||
// java.base/module-info.class is used to add "release" file
|
||||
// We read it from jrt-fs and add a ResourcePoolEntry
|
||||
poolMgr.add(
|
||||
ResourcePoolEntry.create("/java.base/module-info.class",
|
||||
ResourcePoolEntry.Type.CLASS_OR_RESOURCE, getJavaBaseModuleInfo()));
|
||||
expected++;
|
||||
ResourcePool pool = plug.transform(
|
||||
new ResourcePoolManager().resourcePool(),
|
||||
poolMgr.resourcePoolBuilder());
|
||||
@ -94,7 +102,8 @@ public class FileCopierPluginTest {
|
||||
throw new AssertionError("Wrong number of added files");
|
||||
}
|
||||
pool.entries().forEach(f -> {
|
||||
if (!f.type().equals(ResourcePoolEntry.Type.OTHER)) {
|
||||
if (!f.type().equals(ResourcePoolEntry.Type.OTHER) &&
|
||||
!f.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
|
||||
throw new AssertionError("Invalid type " + f.type()
|
||||
+ " for file " + f.path());
|
||||
}
|
||||
@ -104,18 +113,7 @@ public class FileCopierPluginTest {
|
||||
});
|
||||
Path root = new File(".").toPath();
|
||||
DefaultImageBuilder imgbuilder = new DefaultImageBuilder(root);
|
||||
try {
|
||||
imgbuilder.storeFiles(pool);
|
||||
} catch (PluginException e) {
|
||||
// We didn't add any .class resource of the java.base module!
|
||||
// This cannot happen in non-testing scenario as java.base module
|
||||
// is minimum mandatory module in a .jimage. jlink depends on java.base
|
||||
// to generate 'release' file. If the current exception came from that
|
||||
// part of the code, then it is okay.
|
||||
if (!e.getMessage().contains("No module-info for java.base module")) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
imgbuilder.storeFiles(pool);
|
||||
|
||||
if (lic.exists()) {
|
||||
File license = new File(root.toFile(), "LICENSE");
|
||||
@ -157,4 +155,9 @@ public class FileCopierPluginTest {
|
||||
throw new AssertionError("Invalid Content in src2 dir");
|
||||
}
|
||||
}
|
||||
|
||||
// read java.base/module-info.class from jrt-fs
|
||||
private static Path getJavaBaseModuleInfo() {
|
||||
return Paths.get(URI.create("jrt:/modules/java.base/module-info.class"));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user