1 /* 2 * Copyright (c) 2015, 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 * @summary Test image creation 27 * @author Jean-Francois Denise 28 * @library ../lib 29 * @modules java.base/jdk.internal.jimage 30 * jdk.jdeps/com.sun.tools.classfile 31 * jdk.jlink/jdk.tools.jlink 32 * jdk.jlink/jdk.tools.jlink.internal 33 * jdk.jlink/jdk.tools.jmod 34 * jdk.jlink/jdk.tools.jimage 35 * jdk.compiler 36 * @build tests.* 37 * @run main/othervm -verbose:gc -Xmx1g JLink2Test 38 */ 39 40 import java.io.File; 41 import java.io.FileOutputStream; 42 import java.io.IOException; 43 import java.nio.file.Files; 44 import java.nio.file.Path; 45 import java.util.ArrayList; 46 import java.util.Arrays; 47 import java.util.Collections; 48 import java.util.List; 49 import java.util.jar.JarEntry; 50 import java.util.jar.JarOutputStream; 51 52 import jdk.tools.jlink.plugins.DefaultImageBuilderProvider; 53 import jdk.tools.jlink.internal.ImagePluginConfiguration; 54 import tests.Helper; 55 import tests.JImageGenerator; 56 import tests.JImageValidator; 57 58 public class JLink2Test { 59 60 public static void main(String[] args) throws Exception { 61 Helper helper = Helper.newHelper(); 62 if (helper == null) { 63 System.err.println("Test not run"); 64 return; 65 } 66 helper.generateDefaultModules(); 67 68 testSameNames(helper); 69 testBomFile(helper); 70 testFileReplacement(helper); 71 testModulePath(helper); 72 } 73 74 private static void testModulePath(Helper helper) throws IOException { 75 Path unknownDir = helper.createNewImageDir("jar"); 76 Path jar = helper.getJarDir().resolve("bad.jar"); 77 JImageGenerator.getJLinkTask() 78 .pluginModulePath(unknownDir) 79 .option("--help") 80 .call().assertFailure("(\n|\r|.)*Error: java.nio.file.NoSuchFileException: .*jar.image(\n|\r|.)*"); 81 Files.createFile(jar); 82 JImageGenerator.getJLinkTask() 83 .pluginModulePath(jar) 84 .option("--help") 85 .call().assertFailure("(\n|\r|.)*Error: java.nio.file.NotDirectoryException: .*bad.jar(\n|\r|.)*"); 86 JImageGenerator.getJLinkTask() 87 .pluginModulePath(jar.getParent()) 88 .option("--help") 89 .call().assertFailure("Error: java.util.zip.ZipException: zip file is empty"); 90 try (JarOutputStream out = new JarOutputStream(new FileOutputStream(jar.toFile()))) { 91 JarEntry entry = new JarEntry("class"); 92 out.putNextEntry(entry); 93 out.write("AAAA".getBytes()); 94 out.closeEntry(); 95 } 96 JImageGenerator.getJLinkTask() 97 .pluginModulePath(jar.getParent()) 98 .output(helper.createNewImageDir("crash")) 99 .addJmods(helper.getStdJmodsDir()) 100 .addJmods(jar.getParent()) 101 .addMods("bad") 102 .call().assertFailure("Error: java.io.IOException: module-info not found for bad"); 103 try (JarOutputStream out = new JarOutputStream(new FileOutputStream(jar.toFile()))) { 104 JarEntry entry = new JarEntry("classes"); 105 out.putNextEntry(entry); 106 out.closeEntry(); 107 108 entry = new JarEntry("classes/class"); 109 out.putNextEntry(entry); 110 out.write("AAAA".getBytes()); 111 out.closeEntry(); 112 } 113 JImageGenerator.getJLinkTask() 114 .pluginModulePath(jar.getParent()) 115 .output(helper.createNewImageDir("bad")) 116 .addJmods(jar.getParent()) 117 .addJars(helper.getStdJmodsDir()) 118 .addMods("bad") 119 .call().assertFailure("Error: java.io.IOException: module-info not found for bad"); 120 } 121 122 private static void testSameNames(Helper helper) throws Exception { 123 // Multiple modules with the same name in modulepath, take the first one in the path. 124 // First jmods then jars. So jmods are found, jars are hidden. 125 String[] jarClasses = {"amodule.jar.Main"}; 126 String[] jmodsClasses = {"amodule.jmods.Main"}; 127 helper.generateDefaultJarModule("amodule", Arrays.asList(jarClasses)); 128 helper.generateDefaultJModule("amodule", Arrays.asList(jmodsClasses)); 129 List<String> okLocations = new ArrayList<>(); 130 okLocations.addAll(Helper.toLocation("amodule", Arrays.asList(jmodsClasses))); 131 Path image = helper.generateDefaultImage(new String[0], "amodule").assertSuccess(); 132 JImageValidator validator = new JImageValidator("amodule", okLocations, 133 image.toFile(), Collections.emptyList(), Collections.emptyList()); 134 validator.validate(); 135 } 136 137 private static void testBomFile(Helper helper) throws Exception { 138 File defaults = new File("embedded.properties"); 139 Files.write(defaults.toPath(), ("jdk.jlink.defaults=--genbom --exclude-resources *.jcov,*/META-INF/*" + 140 " --addmods UNKNOWN\n").getBytes()); 141 String[] userOptions = {"--zip", 142 "*", "--strip-java-debug", "on", 143 "--configuration", defaults.getAbsolutePath()}; 144 String moduleName = "bomzip"; 145 helper.generateDefaultJModule(moduleName, "composite2"); 146 Path imgDir = helper.generateDefaultImage(userOptions, moduleName).assertSuccess(); 147 helper.checkImage(imgDir, moduleName, userOptions, null, null); 148 File bom = new File(imgDir.toFile(), "bom"); 149 if (!bom.exists()) { 150 throw new RuntimeException(bom.getAbsolutePath() + " not generated"); 151 } 152 String bomcontent = new String(Files.readAllBytes(bom.toPath())); 153 if (!bomcontent.contains("--strip-java-debug") 154 || !bomcontent.contains("--zip") 155 || !bomcontent.contains("*") 156 || !bomcontent.contains("--genbom") 157 || !bomcontent.contains("zip") 158 || !bomcontent.contains("--exclude-resources *.jcov," 159 + "*/META-INF/*") 160 || !bomcontent.contains("--configuration") 161 || !bomcontent.contains(defaults.getAbsolutePath()) 162 || !bomcontent.contains("--addmods UNKNOWN")) { 163 throw new Exception("Not expected content in " + bom); 164 } 165 } 166 167 private static void testFileReplacement(Helper helper) throws Exception { 168 // Replace jvm.cfg and jvm.hprof.txt with some content 169 // having an header to check against 170 String header = "# YOU SHOULD FIND ME\n"; 171 File jvmcfg = new File(System.getProperty("java.home") 172 + File.separator + "lib" + File.separator + "jvm.cfg"); 173 File jvmhprof = new File(System.getProperty("java.home") 174 + File.separator + "lib" + File.separator + "jvm.hprof.txt"); 175 if (jvmcfg.exists() && jvmhprof.exists()) { 176 String cfgcontent = header + new String(Files.readAllBytes(jvmcfg.toPath())); 177 File cfgNewContent = File.createTempFile("jvmcfgtest", null); 178 cfgNewContent.deleteOnExit(); 179 Files.write(cfgNewContent.toPath(), cfgcontent.getBytes()); 180 181 String hprofcontent = header + new String(Files.readAllBytes(jvmhprof.toPath())); 182 File hprofNewContent = File.createTempFile("hproftest", null); 183 hprofNewContent.deleteOnExit(); 184 Files.write(hprofNewContent.toPath(), hprofcontent.getBytes()); 185 186 String[] userOptions = {"--replace-file", 187 "/java.base/native/jvm.cfg," 188 + cfgNewContent.getAbsolutePath() 189 + ",/jdk.hprof.agent/native/jvm.hprof.txt," 190 + hprofNewContent.getAbsolutePath()}; 191 String moduleName = "jvmcfg"; 192 helper.generateDefaultJModule(moduleName, "composite2", "jdk.hprof.agent"); 193 Path imageDir = helper.generateDefaultImage(userOptions, moduleName).assertSuccess(); 194 helper.checkImage(imageDir, moduleName, null, null); 195 Path jvmcfg2 = imageDir.resolve("lib").resolve("jvm.cfg"); 196 checkFile(header, jvmcfg2); 197 198 Path hprof2 = imageDir.resolve("lib").resolve("jvm.hprof.txt"); 199 checkFile(header, hprof2); 200 } else { 201 System.err.println("Warning, jvm.cfg or jvm.hprof.txt files not found, " 202 + "file replacement not checked"); 203 } 204 } 205 206 private static void checkFile(String header, Path file) throws IOException { 207 if (!Files.exists(file)) { 208 throw new RuntimeException(file.toAbsolutePath() +" not generated"); 209 } 210 String content = new String(Files.readAllBytes(file)); 211 if (!content.startsWith(header)) { 212 throw new AssertionError("jvm.cfg not replaced with " 213 + "expected content"); 214 } 215 } 216 217 }