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 import java.io.IOException; 25 import java.io.PrintWriter; 26 import java.io.StringWriter; 27 import java.lang.reflect.Layer; 28 import java.nio.file.Files; 29 import java.nio.file.Path; 30 import java.nio.file.Paths; 31 import java.util.Arrays; 32 import java.util.Collections; 33 import java.util.List; 34 import java.util.stream.Stream; 35 36 import jdk.tools.jlink.TaskHelper; 37 import jdk.tools.jlink.plugins.PluginProvider; 38 import jdk.tools.jlink.internal.ImagePluginProviderRepository; 39 import tests.Helper; 40 import tests.JImageGenerator; 41 import tests.JImageGenerator.InMemoryFile; 42 43 /* 44 * @test 45 * @summary Test image creation 46 * @author Jean-Francois Denise 47 * @library ../lib 48 * @modules java.base/jdk.internal.jimage 49 * jdk.jdeps/com.sun.tools.classfile 50 * jdk.jlink/jdk.tools.jlink 51 * jdk.jlink/jdk.tools.jlink.internal 52 * jdk.jlink/jdk.tools.jmod 53 * jdk.jlink/jdk.tools.jimage 54 * jdk.compiler 55 * @build tests.* 56 * @run main/othervm -verbose:gc -Xmx1g JLinkTest 57 */ 58 public class JLinkTest { 59 60 public static void main(String[] args) throws Exception { 61 62 Helper helper = Helper.newHelper(); 63 if (helper == null) { 64 System.err.println("Test not run"); 65 return; 66 } 67 helper.generateDefaultModules(); 68 int numPlugins = 11; 69 { 70 // number of built-in plugins 71 List<PluginProvider> builtInPluginsProviders = ImagePluginProviderRepository.getPluginProviders(Layer.boot()); 72 for (PluginProvider p : builtInPluginsProviders) { 73 p.isExposed(); 74 p.isFunctional(); 75 } 76 if (builtInPluginsProviders.size() != numPlugins) { 77 throw new AssertionError("Plugins not found: " + builtInPluginsProviders.size()); 78 } 79 } 80 81 { 82 String moduleName = "bug8134651"; 83 JImageGenerator.getJLinkTask() 84 .modulePath(helper.defaultModulePath()) 85 .output(helper.createNewImageDir(moduleName)) 86 .addMods("leaf1") 87 .option("") 88 .call().assertSuccess(); 89 JImageGenerator.getJLinkTask() 90 .modulePath(helper.defaultModulePath()) 91 .addMods("leaf1") 92 .option("--output") 93 .option("") 94 .call().assertFailure("Error: no value given for --output"); 95 JImageGenerator.getJLinkTask() 96 .modulePath("") 97 .output(helper.createNewImageDir(moduleName)) 98 .addMods("leaf1") 99 .option("") 100 .call().assertFailure("Error: no value given for --modulepath"); 101 } 102 103 { 104 String moduleName = "filter"; 105 Path jmod = helper.generateDefaultJModule(moduleName).assertSuccess(); 106 String className = "_A.class"; 107 JImageGenerator.addFiles(jmod, new InMemoryFile(className, new byte[0])); 108 Path image = helper.generateDefaultImage(moduleName).assertSuccess(); 109 helper.checkImage(image, moduleName, new String[] {"/" + moduleName + "/" + className}, null); 110 } 111 112 { 113 // Help 114 StringWriter writer = new StringWriter(); 115 jdk.tools.jlink.Main.run(new String[]{"--help"}, new PrintWriter(writer)); 116 String output = writer.toString(); 117 if (output.split("\n").length < 30) { 118 System.err.println(output); 119 throw new AssertionError("Help"); 120 } 121 } 122 123 { 124 // License files 125 String copied = "LICENSE"; 126 String[] arr = copied.split(","); 127 String[] copyFiles = new String[2]; 128 copyFiles[0] = "--copy-files"; 129 copyFiles[1] = copied; 130 Path imageDir = helper.generateDefaultImage(copyFiles, "composite2").assertSuccess(); 131 helper.checkImage(imageDir, "composite2", null, null, arr); 132 } 133 134 { 135 // List plugins 136 StringWriter writer = new StringWriter(); 137 jdk.tools.jlink.Main.run(new String[]{"--list-plugins"}, new PrintWriter(writer)); 138 String output = writer.toString(); 139 long number = Stream.of(output.split("\n")) 140 .filter((s) -> s.matches("Plugin Name:.*")) 141 .count(); 142 if (number != numPlugins) { 143 System.err.println(output); 144 throw new AssertionError("Plugins not found: " + number); 145 } 146 } 147 148 // filter out files and resources + Skip debug + compress 149 { 150 String[] userOptions = {"--compress-resources", "on", "--strip-java-debug", "on", 151 "--exclude-resources", "*.jcov, */META-INF/*", "--exclude-files", 152 "*" + Helper.getDebugSymbolsExtension()}; 153 String moduleName = "excludezipskipdebugcomposite2"; 154 helper.generateDefaultJModule(moduleName, "composite2"); 155 String[] res = {".jcov", "/META-INF/"}; 156 String[] files = {Helper.getDebugSymbolsExtension()}; 157 Path imageDir = helper.generateDefaultImage(userOptions, moduleName).assertSuccess(); 158 helper.checkImage(imageDir, moduleName, res, files); 159 } 160 161 // filter out + Skip debug + compress with filter + sort resources 162 { 163 String[] userOptions2 = {"--compress-resources", "on", "--compress-resources-filter", 164 "^/java.base/*", "--strip-java-debug", "on", "--exclude-resources", 165 "*.jcov, */META-INF/*", "--sort-resources", 166 "*/module-info.class,/sortcomposite2/*,*/javax/management/*"}; 167 String moduleName = "excludezipfilterskipdebugcomposite2"; 168 helper.generateDefaultJModule(moduleName, "composite2"); 169 String[] res = {".jcov", "/META-INF/"}; 170 Path imageDir = helper.generateDefaultImage(userOptions2, moduleName).assertSuccess(); 171 helper.checkImage(imageDir, moduleName, res, null); 172 } 173 174 // default compress 175 { 176 testCompress(helper, "compresscmdcomposite2", "--compress-resources", "on"); 177 } 178 179 { 180 testCompress(helper, "compressfiltercmdcomposite2", 181 "--compress-resources", "on", "--compress-resources-filter", 182 "^/java.base/java/lang/*"); 183 } 184 185 // compress 0 186 { 187 testCompress(helper, "compress0filtercmdcomposite2", 188 "--compress-resources", "on", "--compress-resources-level", "0", 189 "--compress-resources-filter", "^/java.base/java/lang/*"); 190 } 191 192 // compress 1 193 { 194 testCompress(helper, "compress1filtercmdcomposite2", 195 "--compress-resources", "on", "--compress-resources-level", "1", 196 "--compress-resources-filter", "^/java.base/java/lang/*"); 197 } 198 199 // compress 2 200 { 201 testCompress(helper, "compress2filtercmdcomposite2", 202 "--compress-resources", "on", "--compress-resources-level", "2", 203 "--compress-resources-filter", "^/java.base/java/lang/*"); 204 } 205 206 // invalid compress level 207 { 208 String[] userOptions = {"--compress-resources", "on", "--compress-resources-level", "invalid"}; 209 String moduleName = "invalidCompressLevel"; 210 helper.generateDefaultJModule(moduleName, "composite2"); 211 helper.generateDefaultImage(userOptions, moduleName).assertFailure("Error: Invalid level invalid"); 212 } 213 214 // configuration 215 { 216 Path path = Paths.get("embedded.properties"); 217 Files.write(path, Collections.singletonList("jdk.jlink.defaults=--strip-java-debug on --addmods " + 218 "toto.unknown --compress-resources UNKNOWN\n")); 219 String[] userOptions = {"--configuration", path.toAbsolutePath().toString(), 220 "--compress-resources", "off"}; 221 String moduleName = "configembeddednocompresscomposite2"; 222 helper.generateDefaultJModule(moduleName, "composite2"); 223 Path imageDir = helper.generateDefaultImage(userOptions, moduleName).assertSuccess(); 224 helper.checkImage(imageDir, moduleName, null, null); 225 } 226 227 { 228 // Defaults configuration unit parsing 229 List<String> lst = Arrays.asList("--aaaa", "a,b,c,d", "--koko", "--bbbbb", 230 "x,y,z", "--xxx", "-x", "--ddd", "ddd", "--compress", "--doit"); 231 String sample = " --aaaa a, b, c, d --koko --bbbbb x,y,z --xxx -x --ddd ddd --compress --doit"; 232 233 checkDefaults(sample, lst); 234 checkDefaults(sample + " ", lst); 235 } 236 237 } 238 239 private static void testCompress(Helper helper, String moduleName, String... userOptions) throws IOException { 240 helper.generateDefaultJModule(moduleName, "composite2"); 241 Path imageDir = helper.generateDefaultImage(userOptions, moduleName).assertSuccess(); 242 helper.checkImage(imageDir, moduleName, null, null); 243 } 244 245 private static void checkDefaults(String value, List<String> expected) 246 throws Exception { 247 List<String> arguments = TaskHelper.parseDefaults(value); 248 if (!expected.equals(arguments)) { 249 throw new Exception("Lists are not equal. Expected: " + expected 250 + " Actual: " + arguments); 251 } 252 } 253 }