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