--- old/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java 2016-08-29 18:59:42.000000000 +0530 +++ new/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java 2016-08-29 18:59:42.000000000 +0530 @@ -90,11 +90,9 @@ private static List createArgs(Path home) { Objects.requireNonNull(home); - List javaArgs = new ArrayList<>(); Path binDir = home.resolve("bin"); String java = Files.exists(binDir.resolve("java"))? "java" : "java.exe"; - javaArgs.add(binDir.resolve(java).toString()); - return Collections.unmodifiableList(javaArgs); + return List.of(binDir.resolve(java).toString()); } @Override @@ -170,6 +168,7 @@ // populate release properties up-front. targetOsName // field is assigned from there and used elsewhere. Properties release = releaseProperties(files); + Path bin = root.resolve("bin"); files.entries().forEach(f -> { if (!f.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) { @@ -191,7 +190,6 @@ if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) { // launchers in the bin directory need execute permission - Path bin = root.resolve("bin"); if (Files.isDirectory(bin)) { Files.list(bin) .filter(f -> !f.toString().endsWith(".diz")) @@ -209,7 +207,11 @@ } } - prepareApplicationFiles(files, modules); + // If native files are stripped completely, /bin dir won't exist! + // So, don't bother generating launcher scripts. + if (Files.isDirectory(bin)) { + prepareApplicationFiles(files, modules); + } } catch (IOException ex) { throw new PluginException(ex); } @@ -229,7 +231,7 @@ this.targetOsName = props.getProperty("OS_NAME"); if (this.targetOsName == null) { - throw new RuntimeException("can't determine target OS from java.base descriptor"); + throw new PluginException("TargetPlatform attribute is missing for java.base module"); } Optional release = pool.findEntry("/java.base/release");