1 /* 2 * Copyright (c) 2015, 2017, 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.module.ModuleDescriptor; 28 import java.nio.file.Files; 29 import java.nio.file.Path; 30 import java.nio.file.Paths; 31 import java.util.ArrayList; 32 import java.util.Collections; 33 import java.util.List; 34 import java.util.spi.ToolProvider; 35 import java.util.stream.Stream; 36 37 import jdk.tools.jlink.plugin.Plugin; 38 import jdk.tools.jlink.internal.PluginRepository; 39 import tests.Helper; 40 import tests.JImageGenerator; 41 42 /* 43 * @test 44 * @summary Test image creation 45 * @bug 8189777 46 * @author Jean-Francois Denise 47 * @requires (vm.compMode != "Xcomp" & os.maxMemory >= 2g) 48 * @library ../lib 49 * @modules java.base/jdk.internal.jimage 50 * jdk.jdeps/com.sun.tools.classfile 51 * jdk.jlink/jdk.tools.jlink.internal 52 * jdk.jlink/jdk.tools.jlink.plugin 53 * jdk.jlink/jdk.tools.jimage 54 * jdk.compiler 55 * @build tests.* 56 * @run main/othervm/timeout=300 -Xmx1g JLinkTest 57 */ 58 public class JLinkTest { 59 static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink") 60 .orElseThrow(() -> 61 new RuntimeException("jlink tool not found") 62 ); 63 64 // number of built-in plugins from jdk.jlink module 65 private static int getNumJlinkPlugins() { 66 ModuleDescriptor desc = Plugin.class.getModule().getDescriptor(); 67 return desc.provides().stream() 68 .filter(p -> p.service().equals(Plugin.class.getName())) 69 .map(p -> p.providers().size()) 70 .findAny() 71 .orElse(0); 72 } 73 74 private static boolean isOfJLinkModule(Plugin p) { 75 return p.getClass().getModule() == Plugin.class.getModule(); 76 } 77 78 public static void main(String[] args) throws Exception { 79 80 Helper helper = Helper.newHelper(); 81 if (helper == null) { 82 System.err.println("Test not run"); 83 return; 84 } 85 helper.generateDefaultModules(); 86 // expected num. of plugins from jdk.jlink module 87 int expectedJLinkPlugins = getNumJlinkPlugins(); 88 int totalPlugins = 0; 89 { 90 // number of built-in plugins 91 List<Plugin> builtInPlugins = new ArrayList<>(); 92 builtInPlugins.addAll(PluginRepository.getPlugins(ModuleLayer.boot())); 93 totalPlugins = builtInPlugins.size(); 94 // actual num. of plugins loaded from jdk.jlink module 95 int actualJLinkPlugins = 0; 96 for (Plugin p : builtInPlugins) { 97 p.getState(); 98 p.getType(); 99 if (isOfJLinkModule(p)) { 100 actualJLinkPlugins++; 101 } 102 } 103 if (expectedJLinkPlugins != actualJLinkPlugins) { 104 throw new AssertionError("Actual plugins loaded from jdk.jlink: " + 105 actualJLinkPlugins + " which doesn't match expected number : " + 106 expectedJLinkPlugins); 107 } 108 } 109 110 { 111 // No --module-path specified. $JAVA_HOME/jmods should be assumed. 112 // The following should succeed as it uses only system modules. 113 String imageDir = "bug818977-no-modulepath"; 114 JImageGenerator.getJLinkTask() 115 .output(helper.createNewImageDir(imageDir)) 116 .addMods("jdk.scripting.nashorn") 117 .call().assertSuccess(); 118 } 119 120 { 121 // invalid --module-path specified. java.base not found it it. 122 // $JAVA_HOME/jmods should be added automatically. 123 // The following should succeed as it uses only system modules. 124 String imageDir = "bug8189777-invalid-modulepath"; 125 JImageGenerator.getJLinkTask() 126 .modulePath("does_not_exist_path") 127 .output(helper.createNewImageDir(imageDir)) 128 .addMods("jdk.scripting.nashorn") 129 .call().assertSuccess(); 130 } 131 132 { 133 // No --module-path specified. --add-modules ALL-MODULE-PATH specified. 134 String imageDir = "bug8189777-all-module-path"; 135 JImageGenerator.getJLinkTask() 136 .output(helper.createNewImageDir(imageDir)) 137 .addMods("ALL-MODULE-PATH") 138 .call().assertSuccess(); 139 } 140 141 { 142 String moduleName = "bug8134651"; 143 JImageGenerator.getJLinkTask() 144 .modulePath(helper.defaultModulePath()) 145 .output(helper.createNewImageDir(moduleName)) 146 .addMods("leaf1") 147 .call().assertSuccess(); 148 JImageGenerator.getJLinkTask() 149 .modulePath(helper.defaultModulePath()) 150 .addMods("leaf1") 151 .option("--output") 152 .call().assertFailure("Error: no value given for --output"); 153 JImageGenerator.getJLinkTask() 154 .modulePath("") 155 .output(helper.createNewImageDir(moduleName)) 156 .addMods("leaf1") 157 .call().assertFailure("Error: no value given for --module-path"); 158 // do not include standard module path - should be added automatically 159 JImageGenerator.getJLinkTask() 160 .modulePath(helper.defaultModulePath(false)) 161 .output(helper.createNewImageDir(moduleName)) 162 .addMods("leaf1") 163 .call().assertSuccess(); 164 // no --module-path. default sys mod path is assumed - but that won't contain 'leaf1' module 165 JImageGenerator.getJLinkTask() 166 .output(helper.createNewImageDir(moduleName)) 167 .addMods("leaf1") 168 .call().assertFailure("Error: Module leaf1 not found"); 169 } 170 171 { 172 String moduleName = "m"; // 8163382 173 Path jmod = helper.generateDefaultJModule(moduleName).assertSuccess(); 174 JImageGenerator.getJLinkTask() 175 .modulePath(helper.defaultModulePath()) 176 .output(helper.createNewImageDir(moduleName)) 177 .addMods("m") 178 .call().assertSuccess(); 179 moduleName = "mod"; 180 jmod = helper.generateDefaultJModule(moduleName).assertSuccess(); 181 JImageGenerator.getJLinkTask() 182 .modulePath(helper.defaultModulePath()) 183 .output(helper.createNewImageDir(moduleName)) 184 .addMods("m") 185 .call().assertSuccess(); 186 } 187 188 { 189 String moduleName = "m_8165735"; // JDK-8165735 190 helper.generateDefaultJModule(moduleName+"dependency").assertSuccess(); 191 Path jmod = helper.generateDefaultJModule(moduleName, moduleName+"dependency").assertSuccess(); 192 JImageGenerator.getJLinkTask() 193 .modulePath(helper.defaultModulePath()) 194 .repeatedModulePath(".") // second --module-path overrides the first one 195 .output(helper.createNewImageDir(moduleName)) 196 .addMods(moduleName) 197 // second --module-path does not have that module 198 .call().assertFailure("Error: Module m_8165735 not found"); 199 200 JImageGenerator.getJLinkTask() 201 .modulePath(".") // first --module-path overridden later 202 .repeatedModulePath(helper.defaultModulePath()) 203 .output(helper.createNewImageDir(moduleName)) 204 .addMods(moduleName) 205 // second --module-path has that module 206 .call().assertSuccess(); 207 208 JImageGenerator.getJLinkTask() 209 .modulePath(helper.defaultModulePath()) 210 .output(helper.createNewImageDir(moduleName)) 211 .limitMods(moduleName) 212 .repeatedLimitMods("java.base") // second --limit-modules overrides first 213 .addMods(moduleName) 214 .call().assertFailure("Error: Module m_8165735dependency not found, required by m_8165735"); 215 216 JImageGenerator.getJLinkTask() 217 .modulePath(helper.defaultModulePath()) 218 .output(helper.createNewImageDir(moduleName)) 219 .limitMods("java.base") 220 .repeatedLimitMods(moduleName) // second --limit-modules overrides first 221 .addMods(moduleName) 222 .call().assertSuccess(); 223 } 224 225 { 226 // Help 227 StringWriter writer = new StringWriter(); 228 PrintWriter pw = new PrintWriter(writer); 229 JLINK_TOOL.run(pw, pw, "--help"); 230 String output = writer.toString(); 231 if (output.split("\n").length < 10) { 232 System.err.println(output); 233 throw new AssertionError("Help"); 234 } 235 } 236 237 { 238 // List plugins 239 StringWriter writer = new StringWriter(); 240 PrintWriter pw = new PrintWriter(writer); 241 242 JLINK_TOOL.run(pw, pw, "--list-plugins"); 243 String output = writer.toString(); 244 long number = Stream.of(output.split("\\R")) 245 .filter((s) -> s.matches("Plugin Name:.*")) 246 .count(); 247 if (number != totalPlugins) { 248 System.err.println(output); 249 throw new AssertionError("Found: " + number + " expected " + totalPlugins); 250 } 251 } 252 253 // filter out files and resources + Skip debug + compress 254 { 255 String[] userOptions = {"--compress", "2", "--strip-debug", 256 "--exclude-resources", "*.jcov, */META-INF/*", "--exclude-files", 257 "*" + Helper.getDebugSymbolsExtension()}; 258 String moduleName = "excludezipskipdebugcomposite2"; 259 helper.generateDefaultJModule(moduleName, "composite2"); 260 String[] res = {".jcov", "/META-INF/"}; 261 String[] files = {Helper.getDebugSymbolsExtension()}; 262 Path imageDir = helper.generateDefaultImage(userOptions, moduleName).assertSuccess(); 263 helper.checkImage(imageDir, moduleName, res, files); 264 } 265 266 // filter out + Skip debug + compress with filter + sort resources 267 { 268 String[] userOptions2 = {"--compress=2:compress-filter=^/java.base/*", 269 "--strip-debug", "--exclude-resources", 270 "*.jcov, */META-INF/*", "--order-resources", 271 "*/module-info.class,/sortcomposite2/*,*/javax/management/*"}; 272 String moduleName = "excludezipfilterskipdebugcomposite2"; 273 helper.generateDefaultJModule(moduleName, "composite2"); 274 String[] res = {".jcov", "/META-INF/"}; 275 Path imageDir = helper.generateDefaultImage(userOptions2, moduleName).assertSuccess(); 276 helper.checkImage(imageDir, moduleName, res, null); 277 } 278 279 // default compress 280 { 281 testCompress(helper, "compresscmdcomposite2", "--compress", "2"); 282 } 283 284 { 285 testCompress(helper, "compressfiltercmdcomposite2", 286 "--compress=2:filter=^/java.base/java/lang/*"); 287 } 288 289 // compress 0 290 { 291 testCompress(helper, "compress0filtercmdcomposite2", 292 "--compress=0:filter=^/java.base/java/lang/*"); 293 } 294 295 // compress 1 296 { 297 testCompress(helper, "compress1filtercmdcomposite2", 298 "--compress=1:filter=^/java.base/java/lang/*"); 299 } 300 301 // compress 2 302 { 303 testCompress(helper, "compress2filtercmdcomposite2", 304 "--compress=2:filter=^/java.base/java/lang/*"); 305 } 306 307 // invalid compress level 308 { 309 String[] userOptions = {"--compress", "invalid"}; 310 String moduleName = "invalidCompressLevel"; 311 helper.generateDefaultJModule(moduleName, "composite2"); 312 helper.generateDefaultImage(userOptions, moduleName).assertFailure("Error: Invalid compression level invalid"); 313 } 314 315 // orphan argument - JDK-8166810 316 { 317 String[] userOptions = {"--compress", "2", "foo" }; 318 String moduleName = "orphanarg1"; 319 helper.generateDefaultJModule(moduleName, "composite2"); 320 helper.generateDefaultImage(userOptions, moduleName).assertFailure("Error: invalid argument: foo"); 321 } 322 323 // orphan argument - JDK-8166810 324 { 325 String[] userOptions = {"--output", "foo", "bar" }; 326 String moduleName = "orphanarg2"; 327 helper.generateDefaultJModule(moduleName, "composite2"); 328 helper.generateDefaultImage(userOptions, moduleName).assertFailure("Error: invalid argument: bar"); 329 } 330 331 // basic check for --help - JDK-8173717 332 { 333 JImageGenerator.getJLinkTask() 334 .option("--help") 335 .call().assertSuccess(); 336 } 337 } 338 339 private static void testCompress(Helper helper, String moduleName, String... userOptions) throws IOException { 340 helper.generateDefaultJModule(moduleName, "composite2"); 341 Path imageDir = helper.generateDefaultImage(userOptions, moduleName).assertSuccess(); 342 helper.checkImage(imageDir, moduleName, null, null); 343 } 344 }