Adding test for multi release jars.
diff --git a/platform/o.n.bootstrap/test/unit/src/org/netbeans/JarClassLoaderTest.java b/platform/o.n.bootstrap/test/unit/src/org/netbeans/JarClassLoaderTest.java
index 2306cba..0ab726a 100644
--- a/platform/o.n.bootstrap/test/unit/src/org/netbeans/JarClassLoaderTest.java
+++ b/platform/o.n.bootstrap/test/unit/src/org/netbeans/JarClassLoaderTest.java
@@ -20,13 +20,20 @@
import java.io.DataInputStream;
import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.io.Serializable;
+import java.lang.reflect.Method;
import java.net.JarURLConnection;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
@@ -37,7 +44,11 @@
import java.util.logging.Level;
import java.util.logging.Logger;
import java.security.Permission;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
import java.util.Map;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
import junit.framework.AssertionFailedError;
import org.netbeans.junit.NbTestCase;
import org.openide.util.Utilities;
@@ -414,4 +425,65 @@
public @Override void checkPermission(Permission perm, Object ctx) {}
}
+
+ public void testMultiReleaseJar() throws Exception {
+ clearWorkDir();
+ File classes = new File(getWorkDir(), "classes");
+ classes.mkdirs();
+ ToolProvider.getSystemJavaCompiler()
+ .getTask(null, null, d -> { throw new IllegalStateException(d.toString()); }, Arrays.asList("-d", classes.getAbsolutePath()), null,
+ Arrays.asList(new SourceFileObject("test/Impl.java", "package test; public class Impl { public static String get() { return \"base\"; } }"),
+ new SourceFileObject("api/API.java", "package api; public class API { public static String run() { return test.Impl.get(); } }")))
+ .call();
+ File classes9 = new File(new File(new File(classes, "META-INF"), "versions"), "9");
+ classes9.mkdirs();
+ ToolProvider.getSystemJavaCompiler()
+ .getTask(null, null, d -> { throw new IllegalStateException(d.toString()); }, Arrays.asList("-d", classes9.getAbsolutePath(), "-classpath", classes.getAbsolutePath()), null,
+ Arrays.asList(new SourceFileObject("test/Impl.java", "package test; public class Impl { public static String get() { return \"9\"; } }")))
+ .call();
+ Map<String, byte[]> jarContent = new LinkedHashMap<>();
+ jarContent.put("META-INF/MANIFEST.MF", "Manifest-Version: 1.0\nMulti-Release: true\n\n".getBytes());
+ Path classesPath = classes.toPath();
+ Files.walk(classesPath)
+ .filter(p -> Files.isRegularFile(p))
+ .forEach(p -> {
+ try {
+ jarContent.put(classesPath.relativize(p).toString(), TestFileUtils.readFileBin(p.toFile()));
+ } catch (IOException ex) {
+ throw new IllegalStateException(ex);
+ }
+ });
+ File jar = new File(getWorkDir(), "multi-release.jar");
+ try (OutputStream out = new FileOutputStream(jar)) {
+ TestFileUtils.writeZipFile(out, jarContent);
+ }
+ JarClassLoader jcl = new JarClassLoader(Arrays.asList(jar), new ProxyClassLoader[0]);
+ Class<?> api = jcl.loadClass("api.API");
+ Method run = api.getDeclaredMethod("run");
+ String output = (String) run.invoke(null);
+ String expected;
+ try {
+ Class.forName("java.lang.Runtime$Version");
+ expected = "9";
+ } catch (ClassNotFoundException ex) {
+ expected = "base";
+ }
+ assertEquals(expected, output);
+ }
+
+ private static final class SourceFileObject extends SimpleJavaFileObject {
+
+ private final String content;
+
+ public SourceFileObject(String path, String content) throws URISyntaxException {
+ super(new URI("mem://" + path), Kind.SOURCE);
+ this.content = content;
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+ return content;
+ }
+
+ }
}