1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 8156499 27 * @summary Test image creation from Multi-Release JAR 28 * @author Steve Drach 29 * @library /lib/testlibrary 30 * @modules java.base/jdk.internal.jimage 31 * jdk.jartool/sun.tools.jar 32 * jdk.jlink/jdk.tools.jlink.internal 33 * @build CompilerUtils 34 * @run testng JLinkMultiReleaseJarTest 35 */ 36 37 import java.io.IOException; 38 import java.io.PrintWriter; 39 import java.lang.invoke.MethodHandle; 40 import java.lang.invoke.MethodHandles; 41 import java.lang.invoke.MethodType; 42 import java.nio.file.FileVisitResult; 43 import java.nio.file.Files; 44 import java.nio.file.Path; 45 import java.nio.file.Paths; 46 import java.nio.file.SimpleFileVisitor; 47 import java.nio.file.attribute.BasicFileAttributes; 48 import java.util.jar.JarFile; 49 50 import jdk.internal.jimage.BasicImageReader; 51 52 import org.testng.Assert; 53 import org.testng.annotations.AfterClass; 54 import org.testng.annotations.BeforeClass; 55 import org.testng.annotations.Test; 56 57 public class JLinkMultiReleaseJarTest { 58 private Path userdir; 59 private Path javahome; 60 61 @BeforeClass 62 public void initialize() throws IOException { 63 Path srcdir = Paths.get(System.getProperty("test.src")); 64 userdir = Paths.get(System.getProperty("user.dir", ".")); 65 javahome = Paths.get(System.getProperty("java.home")); 66 67 // create class files from source 68 Path base = srcdir.resolve("base"); 69 Path basemods = userdir.resolve("basemods"); 70 CompilerUtils.compile(base, basemods, "-modulesourcepath", base.toString()); 71 72 Path rt = srcdir.resolve("rt"); 73 Path rtmods = userdir.resolve("rtmods"); 74 CompilerUtils.compile(rt, rtmods, "-modulesourcepath", rt.toString()); 75 76 // build multi-release jar file 77 sun.tools.jar.Main jartool = new sun.tools.jar.Main(System.out, System.err, "jar"); 78 String args = "-cf m1.jar -C basemods/m1 . --release " 79 + JarFile.runtimeVersion().major() + " -C rtmods/m1 ."; 80 jartool.run(args.split(" +")); 81 } 82 83 @AfterClass 84 public void close() throws IOException { 85 Files.walkFileTree(userdir, new SimpleFileVisitor<>() { 86 @Override 87 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 88 throws IOException 89 { 90 Files.delete(file); 91 return FileVisitResult.CONTINUE; 92 } 93 @Override 94 public FileVisitResult postVisitDirectory(Path dir, IOException e) 95 throws IOException 96 { 97 if (dir.equals(userdir)) { 98 return FileVisitResult.CONTINUE; 99 } 100 if (e == null) { 101 Files.delete(dir); 102 return FileVisitResult.CONTINUE; 103 } else { 104 // directory iteration failed 105 throw e; 106 } 107 } 108 }); 109 } 110 111 @Test 112 public void test() throws Throwable { 113 // use jlink to build image from multi-release jar 114 String args = "--output myimage --addmods m1 --modulepath m1.jar:" 115 + javahome + "/jmods"; 116 int exitCode = jdk.tools.jlink.internal.Main.run(args.split(" +"), 117 new PrintWriter(System.out)); 118 Assert.assertEquals(exitCode, 0); 119 120 // validate image 121 Path jimage = userdir.resolve("myimage").resolve("lib").resolve("modules"); 122 BasicImageReader reader = BasicImageReader.open(jimage); 123 byte[] b = reader.getResource("/m1/p/Main.class"); 124 Class<?> clazz = (new ByteArrayClassLoader()).loadClass("p.Main", b); 125 MethodHandle getVersion = MethodHandles.lookup() 126 .findVirtual(clazz, "getVersion", MethodType.methodType(int.class)); 127 int version = (int)getVersion.invoke(clazz.getConstructor().newInstance()); 128 Assert.assertEquals(version, JarFile.runtimeVersion().major()); 129 } 130 131 private static class ByteArrayClassLoader extends ClassLoader { 132 public Class<?> loadClass(String name, byte[] bytes) { 133 return defineClass(name, bytes, 0, bytes.length); 134 } 135 } 136 }