--- old/modules/jdk.packager/src/main/java/com/oracle/tools/packager/AbstractImageBundler.java 2017-08-15 12:38:03.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/com/oracle/tools/packager/AbstractImageBundler.java 2017-08-15 12:38:03.000000000 -0700 @@ -37,7 +37,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import jdk.packager.internal.JLinkBundlerHelper; +import jdk.packager.internal.legacy.JLinkBundlerHelper; import static com.oracle.tools.packager.StandardBundlerParam.*; --- old/modules/jdk.packager/src/main/java/com/oracle/tools/packager/StandardBundlerParam.java 2017-08-15 12:38:04.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/com/oracle/tools/packager/StandardBundlerParam.java 2017-08-15 12:38:04.000000000 -0700 @@ -25,7 +25,7 @@ package com.oracle.tools.packager; -import jdk.packager.internal.JLinkBundlerHelper; +import jdk.packager.internal.legacy.JLinkBundlerHelper; import com.sun.javafx.tools.packager.bundlers.BundleParams; @@ -56,8 +56,8 @@ import java.util.jar.Manifest; import java.util.regex.Pattern; import java.util.stream.Collectors; -import static jdk.packager.internal.JLinkBundlerHelper.findPathOfModule; -import static jdk.packager.internal.JLinkBundlerHelper.listOfPathToString; +import static jdk.packager.internal.legacy.JLinkBundlerHelper.findPathOfModule; +import static jdk.packager.internal.legacy.JLinkBundlerHelper.listOfPathToString; public class StandardBundlerParam extends BundlerParamInfo { --- old/modules/jdk.packager/src/main/java/com/oracle/tools/packager/jnlp/JNLPBundler.java 2017-08-15 12:38:06.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/com/oracle/tools/packager/jnlp/JNLPBundler.java 2017-08-15 12:38:06.000000000 -0700 @@ -72,7 +72,7 @@ import java.util.regex.Pattern; import static com.oracle.tools.packager.StandardBundlerParam.*; -import jdk.packager.internal.JLinkBundlerHelper; +import jdk.packager.internal.legacy.JLinkBundlerHelper; public class JNLPBundler extends AbstractBundler { --- old/modules/jdk.packager/src/main/java/com/oracle/tools/packager/linux/LinuxAppBundler.java 2017-08-15 12:38:07.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/com/oracle/tools/packager/linux/LinuxAppBundler.java 2017-08-15 12:38:07.000000000 -0700 @@ -37,9 +37,9 @@ import com.oracle.tools.packager.StandardBundlerParam; import com.oracle.tools.packager.UnsupportedPlatformException; import com.sun.javafx.tools.packager.bundlers.BundleParams; -import jdk.packager.builders.linux.LinuxAppImageBuilder; +import jdk.packager.internal.legacy.builders.linux.LinuxAppImageBuilder; -import jdk.packager.internal.JLinkBundlerHelper; +import jdk.packager.internal.legacy.JLinkBundlerHelper; import java.io.File; import java.io.IOException; @@ -52,7 +52,7 @@ import java.util.ResourceBundle; import static com.oracle.tools.packager.StandardBundlerParam.*; -import jdk.packager.builders.AbstractAppImageBuilder; +import jdk.packager.internal.legacy.builders.AbstractAppImageBuilder; public class LinuxAppBundler extends AbstractImageBundler { --- old/modules/jdk.packager/src/main/java/com/oracle/tools/packager/mac/MacAppBundler.java 2017-08-15 12:38:08.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/com/oracle/tools/packager/mac/MacAppBundler.java 2017-08-15 12:38:08.000000000 -0700 @@ -33,9 +33,9 @@ import com.oracle.tools.packager.Platform; import com.oracle.tools.packager.StandardBundlerParam; import com.oracle.tools.packager.UnsupportedPlatformException; -import jdk.packager.builders.mac.MacAppImageBuilder; +import jdk.packager.internal.legacy.builders.mac.MacAppImageBuilder; -import jdk.packager.internal.JLinkBundlerHelper; +import jdk.packager.internal.legacy.JLinkBundlerHelper; import java.io.File; import java.io.IOException; @@ -50,8 +50,8 @@ import static com.oracle.tools.packager.StandardBundlerParam.*; import static com.oracle.tools.packager.mac.MacBaseInstallerBundler.*; -import jdk.packager.builders.AbstractAppImageBuilder; -import jdk.packager.internal.mac.MacCertificate; +import jdk.packager.internal.legacy.builders.AbstractAppImageBuilder; +import jdk.packager.internal.legacy.mac.MacCertificate; public class MacAppBundler extends AbstractImageBundler { --- old/modules/jdk.packager/src/main/java/com/oracle/tools/packager/mac/MacAppStoreBundler.java 2017-08-15 12:38:10.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/com/oracle/tools/packager/mac/MacAppStoreBundler.java 2017-08-15 12:38:09.000000000 -0700 @@ -32,7 +32,7 @@ import com.oracle.tools.packager.IOUtils; import com.oracle.tools.packager.Platform; import com.oracle.tools.packager.UnsupportedPlatformException; -import jdk.packager.builders.mac.MacAppImageBuilder; +import jdk.packager.internal.legacy.builders.mac.MacAppImageBuilder; import java.io.File; import java.io.FileNotFoundException; @@ -49,7 +49,7 @@ import static com.oracle.tools.packager.StandardBundlerParam.*; import static com.oracle.tools.packager.mac.MacAppBundler.*; -import jdk.packager.internal.mac.MacCertificate; +import jdk.packager.internal.legacy.mac.MacCertificate; public class MacAppStoreBundler extends MacBaseInstallerBundler { --- old/modules/jdk.packager/src/main/java/com/oracle/tools/packager/mac/MacPkgBundler.java 2017-08-15 12:38:11.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/com/oracle/tools/packager/mac/MacPkgBundler.java 2017-08-15 12:38:11.000000000 -0700 @@ -55,7 +55,7 @@ import static com.oracle.tools.packager.StandardBundlerParam.*; import static com.oracle.tools.packager.mac.MacBaseInstallerBundler.SIGNING_KEYCHAIN; import static com.oracle.tools.packager.mac.MacBaseInstallerBundler.SIGNING_KEY_USER; -import jdk.packager.internal.mac.MacCertificate; +import jdk.packager.internal.legacy.mac.MacCertificate; public class MacPkgBundler extends MacBaseInstallerBundler { --- old/modules/jdk.packager/src/main/java/com/oracle/tools/packager/windows/WinAppBundler.java 2017-08-15 12:38:12.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/com/oracle/tools/packager/windows/WinAppBundler.java 2017-08-15 12:38:12.000000000 -0700 @@ -34,9 +34,9 @@ import com.oracle.tools.packager.RelativeFileSet; import com.oracle.tools.packager.StandardBundlerParam; import com.oracle.tools.packager.UnsupportedPlatformException; -import jdk.packager.builders.windows.WindowsAppImageBuilder; +import jdk.packager.internal.legacy.builders.windows.WindowsAppImageBuilder; -import jdk.packager.internal.JLinkBundlerHelper; +import jdk.packager.internal.legacy.JLinkBundlerHelper; import java.io.ByteArrayOutputStream; import java.io.File; @@ -50,7 +50,7 @@ import static com.oracle.tools.packager.StandardBundlerParam.*; import static com.oracle.tools.packager.windows.WindowsBundlerParam.*; -import jdk.packager.builders.AbstractAppImageBuilder; +import jdk.packager.internal.legacy.builders.AbstractAppImageBuilder; public class WinAppBundler extends AbstractImageBundler { --- old/modules/jdk.packager/src/main/java/com/oracle/tools/packager/windows/WinExeBundler.java 2017-08-15 12:38:14.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/com/oracle/tools/packager/windows/WinExeBundler.java 2017-08-15 12:38:14.000000000 -0700 @@ -38,7 +38,7 @@ import static com.oracle.tools.packager.StandardBundlerParam.SERVICE_HINT; import static com.oracle.tools.packager.StandardBundlerParam.VERBOSE; import static com.oracle.tools.packager.windows.WindowsBundlerParam.*; -import jdk.packager.internal.windows.WindowsDefender; +import jdk.packager.internal.legacy.windows.WindowsDefender; public class WinExeBundler extends AbstractBundler { --- old/modules/jdk.packager/src/main/java/com/sun/javafx/tools/packager/DeployParams.java 2017-08-15 12:38:16.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/com/sun/javafx/tools/packager/DeployParams.java 2017-08-15 12:38:16.000000000 -0700 @@ -43,7 +43,7 @@ import java.util.TreeMap; import java.util.TreeSet; -import jdk.packager.internal.JLinkBundlerHelper; +import jdk.packager.internal.legacy.JLinkBundlerHelper; import static com.oracle.tools.packager.jnlp.JNLPBundler.*; --- old/modules/jdk.packager/src/main/java/com/sun/javafx/tools/packager/Main.java 2017-08-15 12:38:17.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/com/sun/javafx/tools/packager/Main.java 2017-08-15 12:38:17.000000000 -0700 @@ -40,7 +40,7 @@ import java.nio.file.Files; import java.nio.file.Path; -import jdk.packager.internal.JLinkBundlerHelper; +import jdk.packager.internal.legacy.JLinkBundlerHelper; public class Main { --- old/modules/jdk.packager/src/main/java/com/sun/javafx/tools/packager/bundlers/BundleParams.java 2017-08-15 12:38:19.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/com/sun/javafx/tools/packager/bundlers/BundleParams.java 2017-08-15 12:38:19.000000000 -0700 @@ -37,7 +37,7 @@ import static com.oracle.tools.packager.StandardBundlerParam.*; -import jdk.packager.internal.JLinkBundlerHelper; +import jdk.packager.internal.legacy.JLinkBundlerHelper; public class BundleParams { --- /dev/null 2017-08-15 12:38:20.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/jdk/packager/internal/legacy/JDepHelper.java 2017-08-15 12:38:20.000000000 -0700 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.packager.internal.legacy; + + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.spi.ToolProvider; +import java.util.Optional; +import java.io.PrintWriter; +import java.util.Collection; + +import com.oracle.tools.packager.Log; + + +public final class JDepHelper { + + private JDepHelper() {} + + private static int execute(String[] args, PrintWriter out) { + Optional jdeps = ToolProvider.findFirst("jdeps"); + if (jdeps.isPresent()) { + return jdeps.get().run(out, null, args); + } else throw new RuntimeException("jdeps not found"); + } + + public static Set calculateModules(Collection Files, List modulePath) { + Set result = null; + + if (!Files.isEmpty()) { + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintWriter writer = new PrintWriter(baos)) { + + List arguments = new ArrayList<>(); + arguments.add("-s"); + + // Uncomment out once JDK-8151729 is fixed + /*if (modulePath != null || !modulePath.isEmpty()) { + arguments.add("-modulepath"); + arguments.add(ListOfPathToString(modulePath)); + }*/ + + arguments.addAll(Files); + + execute(arguments.toArray(new String[arguments.size()]), writer); + + // Output format is multiple lines of "this.jar -> that.module.name" + // we only care about what is to the right of the arrow. + result = Arrays.stream(baos.toString().split("\\s*\\S+\\s+->\\s+")) + .map(String::trim) + .filter(s -> !s.isEmpty() && !arguments.contains(s) && !"not found".equals(s)) + .collect(Collectors.toSet()); + } catch (IOException exception) { + Log.verbose(exception); + } + } + + if (result == null) { + result = new LinkedHashSet(); + } + + return result; + } + + private static String ListOfPathToString(List Value) { + String result = ""; + + for (Path path : Value) { + if (result.isEmpty()) { + result = path.toString(); + } + else { + result = File.pathSeparator + path.toString(); + } + } + + return result; + } +} --- /dev/null 2017-08-15 12:38:21.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/jdk/packager/internal/legacy/JLinkBundlerHelper.java 2017-08-15 12:38:21.000000000 -0700 @@ -0,0 +1,498 @@ +/* + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.packager.internal.legacy; + + +import com.oracle.tools.packager.StandardBundlerParam; +import com.oracle.tools.packager.BundlerParamInfo; +import com.oracle.tools.packager.RelativeFileSet; +import com.oracle.tools.packager.Log; +import com.oracle.tools.packager.Platform; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.StringReader; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Properties; +import java.util.ResourceBundle; +import java.util.Set; +import java.util.TreeSet; +import java.util.function.Supplier; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import jdk.packager.internal.legacy.builders.AbstractAppImageBuilder; +import jdk.packager.internal.legacy.Module; +import jdk.tools.jlink.internal.packager.AppRuntimeImageBuilder; + + +public final class JLinkBundlerHelper { + + private static final ResourceBundle I18N = + ResourceBundle.getBundle(JLinkBundlerHelper.class.getName()); + + private JLinkBundlerHelper() {} + + @SuppressWarnings("unchecked") + public static final BundlerParamInfo DETECT_MODULES = + new StandardBundlerParam<>( + I18N.getString("param.detect-modules.name"), + I18N.getString("param.detect-modules.description"), + "detect-modules", + Boolean.class, + p -> Boolean.FALSE, + (s, p) -> Boolean.valueOf(s)); + + @SuppressWarnings("unchecked") + public static final BundlerParamInfo> JLINK_OPTIONS = + new StandardBundlerParam<>( + I18N.getString("param.jlink-options.name"), + I18N.getString("param.jlink-options.description"), + "jlinkOptions", + (Class>) (Object) Map.class, + p -> Collections.emptyMap(), + (s, p) -> { + try { + Properties props = new Properties(); + props.load(new StringReader(s)); + return new LinkedHashMap<>((Map)props); + } catch (IOException e) { + return new LinkedHashMap<>(); + } + }); + + @SuppressWarnings("unchecked") + public static final BundlerParamInfo JLINK_BUILDER = + new StandardBundlerParam<>( + I18N.getString("param.jlink-builder.name"), + I18N.getString("param.jlink-builder.description"), + "jlink.builder", + String.class, + null, + (s, p) -> s); + + @SuppressWarnings("unchecked") + public static final BundlerParamInfo DEBUG = + new StandardBundlerParam<>( + "", + "", + "-J-Xdebug", + Integer.class, + p -> null, + (s, p) -> { + return Integer.valueOf(s); + }); + + public static String listOfPathToString(List value) { + String result = ""; + + for (Path path : value) { + if (result.length() > 0) { + result += File.pathSeparator; + } + + result += path.toString(); + } + + return result; + } + + public static String setOfStringToString(Set value) { + String result = ""; + + for (String element : value) { + if (result.length() > 0) { + result += ","; + } + + result += element; + } + + return result; + } + + public static File getMainJar(Map params) { + File result = null; + RelativeFileSet fileset = StandardBundlerParam.MAIN_JAR.fetchFrom(params); + + if (fileset != null) { + String filename = fileset.getIncludedFiles().iterator().next(); + result = fileset.getBaseDirectory().toPath().resolve(filename).toFile(); + + if (result == null || !result.exists()) { + String srcdir = StandardBundlerParam.SOURCE_DIR.fetchFrom(params); + + if (srcdir != null) { + result = new File(srcdir + File.separator + filename); + } + } + } + + return result; + } + + public static String getMainClass(Map params) { + String result = ""; + File mainJar = getMainJar(params); + + if (mainJar != null) { + result = StandardBundlerParam.MAIN_CLASS.fetchFrom(params); + } + else { + String mainModule = StandardBundlerParam.MODULE.fetchFrom(params); + + if (mainModule != null) { + int index = mainModule.indexOf("/"); + + if (index > 0) { + result = mainModule.substring(index + 1); + } + } + } + + return result; + } + + public static String getMainModule(Map params) { + String result = ""; + String mainModule = StandardBundlerParam.MODULE.fetchFrom(params); + + if (mainModule != null) { + int index = mainModule.indexOf("/"); + + if (index > 0) { + result = mainModule.substring(0, index); + } + else { + result = mainModule; + } + } + + return result; + } + + public static String getJDKVersion(Map params) { + String result = ""; + List modulePath = StandardBundlerParam.MODULE_PATH.fetchFrom(params); + Set limitModules = StandardBundlerParam.LIMIT_MODULES.fetchFrom(params); + Path javaBasePath = findPathOfModule(modulePath, "java.base.jmod"); + Set addModules = getRedistributableModules(modulePath, StandardBundlerParam.ADD_MODULES.fetchFrom(params), limitModules); + + if (javaBasePath != null && javaBasePath.toFile().exists()) { + result = RedistributableModules.getModuleVersion(javaBasePath.toFile(), + modulePath, addModules, limitModules); + } + + return result; + } + + public static Path getJDKHome(Map params) { + Path result = null; + List modulePath = StandardBundlerParam.MODULE_PATH.fetchFrom(params); + Path javaBasePath = findPathOfModule(modulePath, "java.base.jmod"); + + if (javaBasePath != null && javaBasePath.toFile().exists()) { + result = javaBasePath.getParent(); + + // On a developer build the JDK Home isn't where we expect it + // relative to the jmods directory. Do some extra + // processing to find it. + if (result != null) { + boolean found = false; + Path bin = result.resolve("bin"); + + if (Files.exists(bin)) { + final String exe = (Platform.getPlatform() == Platform.WINDOWS) ? ".exe" : ""; + Path javaExe = bin.resolve("java" + exe); + + if (Files.exists(javaExe)) { + found = true; + } + } + + if (!found) { + result = result.resolve(".." + File.separator + "jdk"); + } + } + } + + return result; + } + + private static Set getRedistributableModules(List modulePath, Set addModules, Set limitModules) { + ModuleHelper moduleHelper = new ModuleHelper(modulePath, addModules, limitModules); + return removeInvalidModules(modulePath, moduleHelper.modules()); + } + + public static void execute(Map params, AbstractAppImageBuilder imageBuilder) throws IOException, Exception { + List modulePath = StandardBundlerParam.MODULE_PATH.fetchFrom(params); + Set addModules = StandardBundlerParam.ADD_MODULES.fetchFrom(params); + Set limitModules = StandardBundlerParam.LIMIT_MODULES.fetchFrom(params); + boolean stripNativeCommands = StandardBundlerParam.STRIP_NATIVE_COMMANDS.fetchFrom(params); + Map userArguments = JLINK_OPTIONS.fetchFrom(params); + Path outputDir = imageBuilder.getRoot(); + String excludeFileList = imageBuilder.getExcludeFileList(); + Set jars = getResourceFileJarList(params, Module.JarType.UnnamedJar); + File mainJar = getMainJar(params); + Module.ModuleType mainJarType = Module.ModuleType.Unknown; + + if (mainJar != null) { + mainJarType = new Module(mainJar).getModuleType(); + } + + //-------------------------------------------------------------------- + // Modules + + boolean detectModules = DETECT_MODULES.fetchFrom(params); + + // The default for an unnamed jar is ALL_DEFAULT with the + // non-redistributable modules removed. + if (mainJarType == Module.ModuleType.UnnamedJar && !detectModules) { + addModules.add(ModuleHelper.ALL_RUNTIME); + } + else if (mainJarType == Module.ModuleType.Unknown || mainJarType == Module.ModuleType.ModularJar) { + String mainModule = getMainModule(params); + addModules.add(mainModule); + + // Error if any of the srcfiles are modular jars. + Set modularJars = getResourceFileJarList(params, Module.JarType.ModularJar); + + if (!modularJars.isEmpty()) { + throw new Exception(MessageFormat.format(I18N.getString("error.srcfiles.contain.modules"), modularJars.toString())); + } + } + + Set redistModules = getRedistributableModules(modulePath, addModules, limitModules); + addModules.addAll(redistModules); + + //-------------------------------------------------------------------- + // Jars + + // Bundle with minimum dependencies that unnamed jars depend on. + if (detectModules && !jars.isEmpty()) { + Log.info(MessageFormat.format(I18N.getString("using.experimental.feature"), "--" + DETECT_MODULES.getID())); + Collection detectedModules = JDepHelper.calculateModules(jars, modulePath); + + if (!detectedModules.isEmpty()) { + addModules.addAll(detectedModules); + } + } + + Log.info(MessageFormat.format(I18N.getString("message.modules"), addModules.toString())); + + if (StandardBundlerParam.VERBOSE.fetchFrom(params)) { + Log.info("outputDir = " + outputDir.toString()); + Log.info("modulePath = " + modulePath.toString()); + Log.info("addModules = " + addModules.toString()); + Log.info("limitModules = " + limitModules.toString()); + Log.info("excludeFileList = " + excludeFileList); + Log.info("stripNativeCommands = " + stripNativeCommands); + Log.info("userArguments = " + userArguments.toString()); + } + + AppRuntimeImageBuilder appRuntimeBuilder = new AppRuntimeImageBuilder(); + appRuntimeBuilder.setOutputDir(outputDir); + appRuntimeBuilder.setModulePath(modulePath); + appRuntimeBuilder.setAddModules(addModules); + appRuntimeBuilder.setLimitModules(limitModules); + appRuntimeBuilder.setExcludeFileList(excludeFileList); + appRuntimeBuilder.setStripNativeCommands(stripNativeCommands); + appRuntimeBuilder.setUserArguments(userArguments); + + appRuntimeBuilder.build(); + imageBuilder.prepareApplicationFiles(); + } + + // Returns the path to the JDK modules in the user defined module path. + public static Path findPathOfModule(List modulePath, String moduleName) { + Path result = null; + + for (Path path : modulePath) { + Path moduleNamePath = path.resolve(moduleName); + + if (Files.exists(moduleNamePath)) { + result = path; + break; + } + } + + return result; + } + + private static Set getResourceFileJarList(Map params, Module.JarType Query) { + Set files = new LinkedHashSet(); + + String srcdir = StandardBundlerParam.SOURCE_DIR.fetchFrom(params); + + for (RelativeFileSet appResources : StandardBundlerParam.APP_RESOURCES_LIST.fetchFrom(params)) { + for (String resource : appResources.getIncludedFiles()) { + if (resource.endsWith(".jar")) { + String filename = srcdir + File.separator + resource; + + switch (Query) { + case All: { + files.add(filename); + break; + } + case ModularJar: { + Module module = new Module(new File(filename)); + + if (module.getModuleType() == Module.ModuleType.ModularJar) { + files.add(filename); + } + break; + } + case UnnamedJar: { + Module module = new Module(new File(filename)); + + if (module.getModuleType() == Module.ModuleType.UnnamedJar) { + files.add(filename); + } + break; + } + } + } + } + } + + return files; + } + + private static Set removeInvalidModules(List modulePath, Set modules) { + Set result = new LinkedHashSet(); + ModuleManager mm = new ModuleManager(modulePath); + List lmodules = mm.getModules(EnumSet.of(ModuleManager.SearchType.ModularJar, + ModuleManager.SearchType.Jmod, + ModuleManager.SearchType.ExplodedModule)); + + HashMap validModules = new HashMap<>(); + + for (Module module : lmodules) { + validModules.put(module.getModuleName(), module); + } + + for (String name : modules) { + if (validModules.containsKey(name)) { + result.add(name); + } + else { + Log.info(MessageFormat.format(I18N.getString("warning.module.does.not.exist"), name)); + } + } + + return result; + } + + private static class ModuleHelper { + // The token for "all modules on the module path". + private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH"; + + // The token for "all redistributable runtime modules". + public static final String ALL_RUNTIME = "ALL-RUNTIME"; + + private final Set modules = new HashSet<>(); + private enum Macros {None, AllModulePath, AllRuntime} + + public ModuleHelper(List paths, Set roots, Set limitMods) { + Macros macro = Macros.None; + + for (Iterator iterator = roots.iterator(); iterator.hasNext();) { + String module = iterator.next(); + + switch (module) { + case ALL_MODULE_PATH: + iterator.remove(); + macro = Macros.AllModulePath; + break; + case ALL_RUNTIME: + iterator.remove(); + macro = Macros.AllRuntime; + break; + default: + this.modules.add(module); + } + } + + switch (macro) { + case AllModulePath: + this.modules.addAll(getModuleNamesFromPath(paths)); + break; + case AllRuntime: + Set m = RedistributableModules.getRedistributableModules(paths); + + if (m != null) { + this.modules.addAll(m); + } + + break; + } + } + + public Set modules() { + return modules; + } + + private static Set getModuleNamesFromPath(List Value) { + Set result = new LinkedHashSet(); + ModuleManager mm = new ModuleManager(Value); + List modules = mm.getModules(EnumSet.of(ModuleManager.SearchType.ModularJar, + ModuleManager.SearchType.Jmod, + ModuleManager.SearchType.ExplodedModule)); + + for (Module module : modules) { + result.add(module.getModuleName()); + } + + return result; + } + } +} --- /dev/null 2017-08-15 12:38:23.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/jdk/packager/internal/legacy/Module.java 2017-08-15 12:38:22.000000000 -0700 @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.packager.internal.legacy; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + + +public final class Module { + private String filename; + private ModuleType moduleType; + + public enum JarType {All, UnnamedJar, ModularJar} + public enum ModuleType {Unknown, UnnamedJar, ModularJar, Jmod, ExplodedModule} + + public Module(File AFile) { + super(); + filename = AFile.getPath(); + moduleType = getModuleType(AFile); + } + + public String getModuleName() { + File file = new File(getFileName()); + return getFileWithoutExtension(file.getName()); + } + + public String getFileName() { + return filename; + } + + public ModuleType getModuleType() { + return moduleType; + } + + private static ModuleType getModuleType(File AFile) { + ModuleType result = ModuleType.Unknown; + String filename = AFile.getAbsolutePath(); + + if (AFile.isFile()) { + if (filename.endsWith(".jmod")) { + result = ModuleType.Jmod; + } + else if (filename.endsWith(".jar")) { + JarType status = isModularJar(filename); + + if (status == JarType.ModularJar) { + result = ModuleType.ModularJar; + } + else if (status == JarType.UnnamedJar) { + result = ModuleType.UnnamedJar; + } + } + } + else if (AFile.isDirectory()) { + File moduleInfo = new File(filename + File.separator + "module-info.class"); + + if (moduleInfo.exists()) { + result = ModuleType.ExplodedModule; + } + } + + return result; + } + + private static JarType isModularJar(String FileName) { + JarType result = JarType.All; + List classNames = new ArrayList(); + + try { + ZipInputStream zip = new ZipInputStream(new FileInputStream(FileName)); + result = JarType.UnnamedJar; + + try { + for (ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip.getNextEntry()) { + if (entry.getName().matches("module-info.class")) { + result = JarType.ModularJar; + break; + } + } + + zip.close(); + } catch (IOException ex) { + } + } catch (FileNotFoundException e) { + } + + return result; + } + + private static String getFileWithoutExtension(String FileName) { + return FileName.replaceFirst("[.][^.]+$", ""); + } +} --- /dev/null 2017-08-15 12:38:24.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/jdk/packager/internal/legacy/ModuleManager.java 2017-08-15 12:38:23.000000000 -0700 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.packager.internal.legacy; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + + +public final class ModuleManager { + private List folders = new ArrayList(); + + public enum SearchType {UnnamedJar, ModularJar, Jmod, ExplodedModule} + + public ModuleManager(String folders) { + super(); + String lfolders = folders.replaceAll("^\"|\"$", ""); + List paths = new ArrayList(); + + for (String folder : Arrays.asList(lfolders.split(File.pathSeparator))) { + File file = new File(folder); + paths.add(file.toPath()); + } + + initialize(paths); + } + + public ModuleManager(List Paths) { + super(); + initialize(Paths); + } + + private void initialize(List Paths) { + for (Path path : Paths) { + folders.add(path.toString().replaceAll("^\"|\"$", "")); + } + } + + public List getModules() { + return getModules(EnumSet.of(SearchType.UnnamedJar, + SearchType.ModularJar, SearchType.Jmod, SearchType.ExplodedModule)); + } + + public List getModules(EnumSet Search) { + List result = new ArrayList(); + + for (String folder : folders) { + result.addAll(getAllModulesInDirectory(folder, Search)); + } + + return result; + } + + private static List getAllModulesInDirectory(String Folder, EnumSet Search) { + List result = new ArrayList(); + File lfolder = new File(Folder); + File[] files = lfolder.listFiles(); + + for (File file : files) { + Module module = new Module(file); + + switch (module.getModuleType()) { + case Unknown: + break; + case UnnamedJar: + if (Search.contains(SearchType.UnnamedJar)) { + result.add(module); + } + break; + case ModularJar: + if (Search.contains(SearchType.ModularJar)) { + result.add(module); + } + break; + case Jmod: + if (Search.contains(SearchType.Jmod)) { + result.add(module); + } + break; + case ExplodedModule: + if (Search.contains(SearchType.ExplodedModule)) { + result.add(module); + } + break; + } + } + + return result; + } +} \ No newline at end of file --- /dev/null 2017-08-15 12:38:25.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/jdk/packager/internal/legacy/RedistributableModules.java 2017-08-15 12:38:25.000000000 -0700 @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.packager.internal.legacy; + + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.util.Optional; + +import jdk.tools.jlink.internal.packager.AppRuntimeImageBuilder; + +import java.lang.module.ModuleDescriptor; +import java.lang.module.ModuleFinder; +import java.lang.module.ModuleReference; +import java.lang.module.ModuleReader; + +import java.nio.file.Path; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Set; + + +public final class RedistributableModules { + private static final String JDK_PACKAGER_MODULE = "jdk.packager"; + private static final String LEGACY_JRE_MODULES_FILENAME = "jdk/packager/internal/resources/tools/legacy/jre.list"; + + private RedistributableModules() {} + + public static String stripComments(String line) { + String result = line.trim(); + int i = result.indexOf(";"); + + if (i >= 0) { + result = result.substring(0, i); + result = result.trim(); + } + + return result; + } + + public static Set getRedistributableModules(List modulePath) { + Set result = null; + + Set addModules = new HashSet<>(); + Set limitModules = new HashSet<>(); + ModuleFinder finder = AppRuntimeImageBuilder.moduleFinder(modulePath, addModules, limitModules); + Optional mref = finder.find(JDK_PACKAGER_MODULE); + + if (mref.isPresent()) { + ModuleReader reader = null; + + try { + reader = mref.get().open(); + } catch (NoSuchElementException | IOException ex) { + } + + if (reader != null) { + Optional stream = null; + + try { + stream = reader.open(LEGACY_JRE_MODULES_FILENAME); + } catch (IOException ex) { + } + + if (stream != null) { + if (stream.isPresent()) { + BufferedReader br = null; + + try { + br = new BufferedReader(new InputStreamReader(stream.get(), "UTF-8")); + } catch (UnsupportedEncodingException ex) { + } + + if (br != null) { + result = new LinkedHashSet(); + String line; + + try { + while ((line = br.readLine()) != null) { + String module = stripComments(line); + + if (!module.isEmpty()) { + result.add(module); + } + } + } catch (IOException ex) { + } + } + } + } + } + } + + return result; + } + + public static String getModuleVersion(File moduleFile, List modulePath, Set addModules, Set limitModules) { + String result = ""; + + Module module = new Module(moduleFile); + ModuleFinder finder = AppRuntimeImageBuilder.moduleFinder(modulePath, addModules, limitModules); + Optional mref = finder.find(module.getModuleName()); + + if (mref.isPresent()) { + ModuleDescriptor descriptor = mref.get().descriptor(); + + if (descriptor != null) { + Optional version = descriptor.version(); + + if (version.isPresent()) { + result = version.get().toString(); + } + } + } + + return result; + } +} --- /dev/null 2017-08-15 12:38:26.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/jdk/packager/internal/legacy/builders/AbstractAppImageBuilder.java 2017-08-15 12:38:26.000000000 -0700 @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.packager.internal.legacy.builders; + + +import com.oracle.tools.packager.RelativeFileSet; + +import com.oracle.tools.packager.Log; +import com.oracle.tools.packager.StandardBundlerParam; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.ResourceBundle; +import java.util.Set; + +import static com.oracle.tools.packager.StandardBundlerParam.*; +import static com.oracle.tools.packager.StandardBundlerParam.ARGUMENTS; +import static com.oracle.tools.packager.StandardBundlerParam.USER_JVM_OPTIONS; +import java.util.ArrayList; +import jdk.packager.internal.legacy.JLinkBundlerHelper; +import jdk.packager.internal.legacy.Module; + + +public abstract class AbstractAppImageBuilder { + + private static final ResourceBundle I18N = + ResourceBundle.getBundle(AbstractAppImageBuilder.class.getName()); + + //do not use file separator - + // we use it for classpath lookup and there / are not platform specific + public final static String BUNDLER_PREFIX = "package/"; + + private Map properties; + private Path root; + protected List excludeFileList = new ArrayList<>(); + + public AbstractAppImageBuilder(Map properties, Path root) throws IOException { + this.properties = properties; + this.root = root; + excludeFileList.add(".*\\.diz"); + } + + public abstract InputStream getResourceAsStream(String name); + public abstract void prepareApplicationFiles() throws IOException; + + public Map getProperties() { + return this.properties; + } + + public Path getRoot() { + return this.root; + } + + public String getExcludeFileList() { + String result = ""; + + for (String item : excludeFileList) { + if (!result.isEmpty()) { + result += ","; + } + + result += item; + } + + return result; + } + + protected InputStream locateResource(String publicName, String category, + String defaultName, File customFile, + boolean verbose, File publicRoot) throws IOException { + InputStream is = null; + boolean customFromClasspath = false; + boolean customFromFile = false; + if (publicName != null) { + if (publicRoot != null) { + File publicResource = new File(publicRoot, publicName); + if (publicResource.exists() && publicResource.isFile()) { + is = new FileInputStream(publicResource); + } + } else { + is = getResourceAsStream(publicName); + } + customFromClasspath = (is != null); + } + if (is == null && customFile != null) { + is = new FileInputStream(customFile); + customFromFile = (is != null); + } + if (is == null && defaultName != null) { + is = getResourceAsStream(defaultName); + } + String msg = null; + if (customFromClasspath) { + msg = MessageFormat.format(I18N.getString("message.using-custom-resource-from-classpath"), category == null ? "" : "[" + category + "] ", publicName); + } else if (customFromFile) { + msg = MessageFormat.format(I18N.getString("message.using-custom-resource-from-file"), category == null ? "" : "[" + category + "] ", customFile.getAbsoluteFile()); + } else if (is != null) { + msg = MessageFormat.format(I18N.getString("message.using-default-resource-from-classpath"), category == null ? "" : "[" + category + "] ", publicName); + } else { + msg = MessageFormat.format(I18N.getString("message.using-default-resource"), category == null ? "" : "[" + category + "] ", publicName); + } + if (verbose) { + Log.info(msg); + } + return is; + } + + + protected String preprocessTextResource(String publicName, String category, + String defaultName, Map pairs, + boolean verbose, File publicRoot) throws IOException { + InputStream inp = locateResource(publicName, category, defaultName, null, verbose, publicRoot); + if (inp == null) { + throw new RuntimeException("Module corrupt? No "+defaultName+" resource!"); + } + + try (InputStream is = inp) { + //read fully into memory + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length; + while ((length = is.read(buffer)) != -1) { + baos.write(buffer, 0, length); + } + + //substitute + String result = new String(baos.toByteArray()); + for (Map.Entry e : pairs.entrySet()) { + if (e.getValue() != null) { + result = result.replace(e.getKey(), e.getValue()); + } + } + return result; + } + } + + public void writeCfgFile(Map params, File cfgFileName, String runtimeLocation) throws IOException { + cfgFileName.delete(); + + boolean appCDEnabled = UNLOCK_COMMERCIAL_FEATURES.fetchFrom(params) && ENABLE_APP_CDS.fetchFrom(params); + String appCDSCacheMode = APP_CDS_CACHE_MODE.fetchFrom(params); + File mainJar = JLinkBundlerHelper.getMainJar(params); + Module.ModuleType mainJarType = Module.ModuleType.Unknown; + + if (mainJar != null) { + mainJarType = new Module(mainJar).getModuleType(); + } + + String mainModule = StandardBundlerParam.MODULE.fetchFrom(params); + + PrintStream out = new PrintStream(cfgFileName); + + out.println("[Application]"); + out.println("app.name=" + APP_NAME.fetchFrom(params)); + out.println("app.version=" + VERSION.fetchFrom(params)); + out.println("app.preferences.id=" + PREFERENCES_ID.fetchFrom(params)); + out.println("app.runtime=" + runtimeLocation); + out.println("app.identifier=" + IDENTIFIER.fetchFrom(params)); + out.println("app.classpath=" + String.join(File.pathSeparator, CLASSPATH.fetchFrom(params).split("[ :;]"))); + out.println("app.application.instance=" + (SINGLETON.fetchFrom(params) ? "single" : "multiple")); + + // The main app is required to be a jar, modular or unnamed. + if (mainJarType == Module.ModuleType.Unknown || mainJarType == Module.ModuleType.ModularJar) { + if (mainModule != null) { + out.println("app.mainmodule=" + mainModule); // TODO get app class from main module mainifest. + } + } + else { + String mainClass = JLinkBundlerHelper.getMainClass(params); + + if (mainJar != null && mainClass != null) { + // If the app is contained in an unnamed jar then launch it the + // legacy way and the main class string must be of the format com/foo/Main + out.println("app.mainclass=" + mainClass.replaceAll("\\.", "/")); + out.println("app.mainjar=" + mainJar.toPath().getFileName().toString()); + } + } + + String version = JLinkBundlerHelper.getJDKVersion(params); + + if (!version.isEmpty()) { + out.println("app.java.version=" + version); + } + + out.println("packager.java.version=" + System.getProperty("java.version")); + + Integer port = JLinkBundlerHelper.DEBUG.fetchFrom(params); + + if (port != null) { + out.println("app.debug=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=localhost:" + port); + } + + if (appCDEnabled) { + out.println("app.appcds.cache=" + appCDSCacheMode.split("\\+")[0]); + } + + + out.println(); + out.println("[JVMOptions]"); + List jvmargs = JVM_OPTIONS.fetchFrom(params); + for (String arg : jvmargs) { + out.println(arg); + } + Map jvmProps = JVM_PROPERTIES.fetchFrom(params); + for (Map.Entry property : jvmProps.entrySet()) { + out.println("-D" + property.getKey() + "=" + property.getValue()); + } + String preloader = PRELOADER_CLASS.fetchFrom(params); + if (preloader != null) { + out.println("-Djavafx.preloader="+preloader); + } + + + out.println(); + out.println("[JVMUserOptions]"); + Map overridableJVMOptions = USER_JVM_OPTIONS.fetchFrom(params); + for (Map.Entry arg: overridableJVMOptions.entrySet()) { + if (arg.getKey() == null || arg.getValue() == null) { + Log.info(I18N.getString("message.jvm-user-arg-is-null")); + } else { + out.println(arg.getKey().replaceAll("([\\=])", "\\\\$1") + "=" + arg.getValue()); + } + } + + if (appCDEnabled) { + prepareAppCDS(params, out); + } + + out.println(); + out.println("[ArgOptions]"); + List args = ARGUMENTS.fetchFrom(params); + for (String arg : args) { + if (arg.endsWith("=") && (arg.indexOf("=") == arg.lastIndexOf("="))) { + out.print(arg.substring(0, arg.length() - 1)); + out.println("\\="); + } else { + out.println(arg); + } + } + + + out.close(); + } + + protected abstract String getCacheLocation(Map params); + + void prepareAppCDS(Map params, PrintStream out) throws IOException { + File tempDir = Files.createTempDirectory("javapackager").toFile(); + tempDir.deleteOnExit(); + File classList = new File(tempDir, APP_FS_NAME.fetchFrom(params) + ".classlist"); + + try (FileOutputStream fos = new FileOutputStream(classList); + PrintStream ps = new PrintStream(fos)) { + for (String className : APP_CDS_CLASS_ROOTS.fetchFrom(params)) { + String slashyName = className.replace(".", "/"); + ps.println(slashyName); + } + } + APP_RESOURCES_LIST.fetchFrom(params).add(new RelativeFileSet(classList.getParentFile(), Arrays.asList(classList))); + + out.println(); + out.println("[AppCDSJVMOptions]"); + out.println("-XX:+UnlockCommercialFeatures"); + out.print("-XX:SharedArchiveFile="); + out.print(getCacheLocation(params)); + out.print(APP_FS_NAME.fetchFrom(params)); + out.println(".jpa"); + out.println("-Xshare:auto"); + out.println("-XX:+UseAppCDS"); + if (Log.isDebug()) { + out.println("-verbose:class"); + out.println("-XX:+TraceClassPaths"); + out.println("-XX:+UnlockDiagnosticVMOptions"); + } + out.println(""); + + out.println("[AppCDSGenerateCacheJVMOptions]"); + out.println("-XX:+UnlockCommercialFeatures"); + out.println("-Xshare:dump"); + out.println("-XX:+UseAppCDS"); + out.print("-XX:SharedArchiveFile="); + out.print(getCacheLocation(params)); + out.print(APP_FS_NAME.fetchFrom(params)); + out.println(".jpa"); + out.println("-XX:SharedClassListFile=$PACKAGEDIR/" + APP_FS_NAME.fetchFrom(params) + ".classlist"); + if (Log.isDebug()) { + out.println("-XX:+UnlockDiagnosticVMOptions"); + } + } +} --- /dev/null 2017-08-15 12:38:28.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/jdk/packager/internal/legacy/builders/linux/LinuxAppImageBuilder.java 2017-08-15 12:38:27.000000000 -0700 @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.packager.internal.legacy.builders.linux; + + +import com.oracle.tools.packager.BundlerParamInfo; +import com.oracle.tools.packager.IOUtils; +import com.oracle.tools.packager.Log; +import com.oracle.tools.packager.RelativeFileSet; +import com.oracle.tools.packager.StandardBundlerParam; +import com.oracle.tools.packager.linux.LinuxResources; +import jdk.packager.internal.legacy.builders.AbstractAppImageBuilder; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.UncheckedIOException; +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.PosixFilePermission; +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.ResourceBundle; +import java.util.Set; + +import static com.oracle.tools.packager.StandardBundlerParam.*; + + +public class LinuxAppImageBuilder extends AbstractAppImageBuilder { + + private static final ResourceBundle I18N = + ResourceBundle.getBundle(LinuxAppImageBuilder.class.getName()); + + protected static final String LINUX_BUNDLER_PREFIX = + BUNDLER_PREFIX + "linux" + File.separator; + private static final String EXECUTABLE_NAME = "JavaAppLauncher"; + private static final String LIBRARY_NAME = "libpackager.so"; + + private final Path root; + private final Path appDir; + private final Path runtimeDir; + private final Path resourcesDir; + private final Path mdir; + + private final Map params; + + public static final BundlerParamInfo ICON_PNG = new StandardBundlerParam<>( + I18N.getString("param.icon-png.name"), + I18N.getString("param.icon-png.description"), + "icon.png", + File.class, + params -> { + File f = ICON.fetchFrom(params); + if (f != null && !f.getName().toLowerCase().endsWith(".png")) { + Log.info(MessageFormat.format(I18N.getString("message.icon-not-png"), f)); + return null; + } + return f; + }, + (s, p) -> new File(s)); + + public LinuxAppImageBuilder(Map config, Path imageOutDir) throws IOException { + super(config, imageOutDir.resolve(APP_NAME.fetchFrom(config) + "/runtime")); + + Objects.requireNonNull(imageOutDir); + + this.root = imageOutDir.resolve(APP_NAME.fetchFrom(config)); + this.appDir = root.resolve("app"); + this.runtimeDir = root.resolve("runtime"); + this.resourcesDir = root.resolve("resources"); + this.mdir = runtimeDir.resolve("lib"); + this.params = new HashMap(); + config.entrySet().stream().forEach(e -> params.put(e.getKey().toString(), e.getValue())); + Files.createDirectories(appDir); + Files.createDirectories(runtimeDir); + Files.createDirectories(resourcesDir); + } + + private Path destFile(String dir, String filename) { + return runtimeDir.resolve(dir).resolve(filename); + } + + private void writeEntry(InputStream in, Path dstFile) throws IOException { + Files.createDirectories(dstFile.getParent()); + Files.copy(in, dstFile); + } + + private void writeSymEntry(Path dstFile, Path target) throws IOException { + Files.createDirectories(dstFile.getParent()); + Files.createLink(dstFile, target); + } + + /** + * chmod ugo+x file + */ + private void setExecutable(Path file) { + try { + Set perms = Files.getPosixFilePermissions(file); + perms.add(PosixFilePermission.OWNER_EXECUTE); + perms.add(PosixFilePermission.GROUP_EXECUTE); + perms.add(PosixFilePermission.OTHERS_EXECUTE); + Files.setPosixFilePermissions(file, perms); + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } + } + + private static void createUtf8File(File file, String content) throws IOException { + try (OutputStream fout = new FileOutputStream(file); + Writer output = new OutputStreamWriter(fout, "UTF-8")) { + output.write(content); + } + } + + + //it is static for the sake of sharing with "installer" bundlers + // that may skip calls to validate/bundle in this class! + public static File getRootDir(File outDir, Map p) { + return new File(outDir, APP_FS_NAME.fetchFrom(p)); + } + + public static String getLauncherName(Map p) { + return APP_FS_NAME.fetchFrom(p); + } + + public static String getLauncherCfgName(Map p) { + return "app/" + APP_FS_NAME.fetchFrom(p) + ".cfg"; + } + + @Override + public InputStream getResourceAsStream(String name) { + return LinuxResources.class.getResourceAsStream(name); + } + + @Override + public void prepareApplicationFiles() throws IOException { + Map originalParams = new HashMap<>(params); + + try { + // create the primary launcher + createLauncherForEntryPoint(params, root); + + // Copy library to the launcher folder + writeEntry(LinuxResources.class.getResourceAsStream(LIBRARY_NAME), root.resolve(LIBRARY_NAME)); + + // create the secondary launchers, if any + List> entryPoints = StandardBundlerParam.SECONDARY_LAUNCHERS.fetchFrom(params); + for (Map entryPoint : entryPoints) { + Map tmp = new HashMap<>(originalParams); + tmp.putAll(entryPoint); + // remove name.fs that was calculated for main launcher. + // otherwise, wrong launcher name will be selected. + tmp.remove(APP_FS_NAME.getID()); + createLauncherForEntryPoint(tmp, root); + } + + // Copy class path entries to Java folder + copyApplication(); + + // Copy icon to Resources folder + copyIcon(); + + } catch (IOException ex) { + Log.info("Exception: " + ex); + Log.debug(ex); + } + } + + private void createLauncherForEntryPoint(Map p, Path rootDir) throws IOException { + // Copy executable to Linux folder + Path executableFile = root.resolve(getLauncherName(p)); + + writeEntry(LinuxResources.class.getResourceAsStream(EXECUTABLE_NAME), executableFile); + + executableFile.toFile().setExecutable(true, false); + executableFile.toFile().setWritable(true, true); + + writeCfgFile(p, root.resolve(getLauncherCfgName(p)).toFile(), "$APPDIR/runtime"); + } + + private void copyIcon() throws IOException { + File icon = ICON_PNG.fetchFrom(params); + File iconTarget = new File(resourcesDir.toFile(), APP_FS_NAME.fetchFrom(params) + ".png"); + IOUtils.copyFile(icon, iconTarget); + } + + private void copyApplication() throws IOException { + List appResourcesList = APP_RESOURCES_LIST.fetchFrom(params); + if (appResourcesList == null) { + throw new RuntimeException("Null app resources?"); + } + for (RelativeFileSet appResources : appResourcesList) { + if (appResources == null) { + throw new RuntimeException("Null app resources?"); + } + File srcdir = appResources.getBaseDirectory(); + for (String fname : appResources.getIncludedFiles()) { + writeEntry( + new FileInputStream(new File(srcdir, fname)), + new File(appDir.toFile(), fname).toPath() + ); + } + } + } + + @Override + protected String getCacheLocation(Map params) { + return "$CACHEDIR/"; + } + +} --- /dev/null 2017-08-15 12:38:29.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/jdk/packager/internal/legacy/builders/mac/MacAppImageBuilder.java 2017-08-15 12:38:28.000000000 -0700 @@ -0,0 +1,874 @@ +/* + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.packager.internal.legacy.builders.mac; + + +import com.oracle.tools.packager.BundlerParamInfo; +import com.oracle.tools.packager.IOUtils; +import com.oracle.tools.packager.Log; +import com.oracle.tools.packager.RelativeFileSet; +import com.oracle.tools.packager.StandardBundlerParam; +import com.oracle.tools.packager.mac.MacResources; + +import jdk.packager.internal.legacy.builders.AbstractAppImageBuilder; +import jdk.packager.internal.legacy.JLinkBundlerHelper; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.UncheckedIOException; +import java.io.Writer; +import java.math.BigInteger; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.PosixFilePermission; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.ResourceBundle; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; + +import static com.oracle.tools.packager.StandardBundlerParam.*; +import static com.oracle.tools.packager.mac.MacBaseInstallerBundler.*; +import static com.oracle.tools.packager.mac.MacAppBundler.*; + + +public class MacAppImageBuilder extends AbstractAppImageBuilder { + + private static final ResourceBundle I18N = + ResourceBundle.getBundle(MacAppImageBuilder.class.getName()); + + private static final String EXECUTABLE_NAME = "JavaAppLauncher"; + private static final String LIBRARY_NAME = "libpackager.dylib"; + private static final String TEMPLATE_BUNDLE_ICON = "GenericApp.icns"; + private static final String OS_TYPE_CODE = "APPL"; + private static final String TEMPLATE_INFO_PLIST_LITE = "Info-lite.plist.template"; + private static final String TEMPLATE_RUNTIME_INFO_PLIST = "Runtime-Info.plist.template"; + + private final Path root; + private final Path contentsDir; + private final Path javaDir; + private final Path resourcesDir; + private final Path macOSDir; + private final Path runtimeDir; + private final Path runtimeRoot; + private final Path mdir; + + private final Map params; + + private static Map getMacCategories() { + Map map = new HashMap<>(); + map.put("Business", "public.app-category.business"); + map.put("Developer Tools", "public.app-category.developer-tools"); + map.put("Education", "public.app-category.education"); + map.put("Entertainment", "public.app-category.entertainment"); + map.put("Finance", "public.app-category.finance"); + map.put("Games", "public.app-category.games"); + map.put("Graphics & Design", "public.app-category.graphics-design"); + map.put("Healthcare & Fitness", "public.app-category.healthcare-fitness"); + map.put("Lifestyle", "public.app-category.lifestyle"); + map.put("Medical", "public.app-category.medical"); + map.put("Music", "public.app-category.music"); + map.put("News", "public.app-category.news"); + map.put("Photography", "public.app-category.photography"); + map.put("Productivity", "public.app-category.productivity"); + map.put("Reference", "public.app-category.reference"); + map.put("Social Networking", "public.app-category.social-networking"); + map.put("Sports", "public.app-category.sports"); + map.put("Travel", "public.app-category.travel"); + map.put("Utilities", "public.app-category.utilities"); + map.put("Video", "public.app-category.video"); + map.put("Weather", "public.app-category.weather"); + + map.put("Action Games", "public.app-category.action-games"); + map.put("Adventure Games", "public.app-category.adventure-games"); + map.put("Arcade Games", "public.app-category.arcade-games"); + map.put("Board Games", "public.app-category.board-games"); + map.put("Card Games", "public.app-category.card-games"); + map.put("Casino Games", "public.app-category.casino-games"); + map.put("Dice Games", "public.app-category.dice-games"); + map.put("Educational Games", "public.app-category.educational-games"); + map.put("Family Games", "public.app-category.family-games"); + map.put("Kids Games", "public.app-category.kids-games"); + map.put("Music Games", "public.app-category.music-games"); + map.put("Puzzle Games", "public.app-category.puzzle-games"); + map.put("Racing Games", "public.app-category.racing-games"); + map.put("Role Playing Games", "public.app-category.role-playing-games"); + map.put("Simulation Games", "public.app-category.simulation-games"); + map.put("Sports Games", "public.app-category.sports-games"); + map.put("Strategy Games", "public.app-category.strategy-games"); + map.put("Trivia Games", "public.app-category.trivia-games"); + map.put("Word Games", "public.app-category.word-games"); + + return map; + } + + public static final BundlerParamInfo MAC_CONFIGURE_LAUNCHER_IN_PLIST = + new StandardBundlerParam<>( + I18N.getString("param.configure-launcher-in-plist"), + I18N.getString("param.configure-launcher-in-plist.description"), + "mac.configure-launcher-in-plist", + Boolean.class, + params -> Boolean.FALSE, + (s, p) -> Boolean.valueOf(s)); + + public static final BundlerParamInfo MAC_CATEGORY = + new StandardBundlerParam<>( + I18N.getString("param.category-name"), + I18N.getString("param.category-name.description"), + "mac.category", + String.class, + CATEGORY::fetchFrom, + (s, p) -> s + ); + + public static final BundlerParamInfo MAC_CF_BUNDLE_NAME = + new StandardBundlerParam<>( + I18N.getString("param.cfbundle-name.name"), + I18N.getString("param.cfbundle-name.description"), + "mac.CFBundleName", + String.class, + params -> null, + (s, p) -> s); + + public static final BundlerParamInfo MAC_CF_BUNDLE_IDENTIFIER = + new StandardBundlerParam<>( + I18N.getString("param.cfbundle-identifier.name"), + I18N.getString("param.cfbundle-identifier.description"), + "mac.CFBundleIdentifier", + String.class, + IDENTIFIER::fetchFrom, + (s, p) -> s); + + public static final BundlerParamInfo MAC_CF_BUNDLE_VERSION = + new StandardBundlerParam<>( + I18N.getString("param.cfbundle-version.name"), + I18N.getString("param.cfbundle-version.description"), + "mac.CFBundleVersion", + String.class, + p -> { + String s = VERSION.fetchFrom(p); + if (validCFBundleVersion(s)) { + return s; + } else { + return "100"; + } + }, + (s, p) -> s); + + public static final BundlerParamInfo CONFIG_ROOT = new StandardBundlerParam<>( + I18N.getString("param.config-root.name"), + I18N.getString("param.config-root.description"), + "configRoot", + File.class, + params -> { + File configRoot = new File(BUILD_ROOT.fetchFrom(params), "macosx"); + configRoot.mkdirs(); + return configRoot; + }, + (s, p) -> new File(s)); + + public static final BundlerParamInfo DEFAULT_ICNS_ICON = new StandardBundlerParam<>( + I18N.getString("param.default-icon-icns"), + I18N.getString("param.default-icon-icns.description"), + ".mac.default.icns", + String.class, + params -> TEMPLATE_BUNDLE_ICON, + (s, p) -> s); + +// public static final BundlerParamInfo DEVELOPER_ID_APP_SIGNING_KEY = new StandardBundlerParam<>( +// I18N.getString("param.signing-key-developer-id-app.name"), +// I18N.getString("param.signing-key-developer-id-app.description"), +// "mac.signing-key-developer-id-app", +// String.class, +// params -> MacBaseInstallerBundler.findKey("Developer ID Application: " + SIGNING_KEY_USER.fetchFrom(params), SIGNING_KEYCHAIN.fetchFrom(params), VERBOSE.fetchFrom(params)), +// (s, p) -> s); + + // public static final BundlerParamInfo BUNDLE_ID_SIGNING_PREFIX = new StandardBundlerParam<>( +// I18N.getString("param.bundle-id-signing-prefix.name"), +// I18N.getString("param.bundle-id-signing-prefix.description"), +// "mac.bundle-id-signing-prefix", +// String.class, +// params -> IDENTIFIER.fetchFrom(params) + ".", +// (s, p) -> s); +// + public static final BundlerParamInfo ICON_ICNS = new StandardBundlerParam<>( + I18N.getString("param.icon-icns.name"), + I18N.getString("param.icon-icns.description"), + "icon.icns", + File.class, + params -> { + File f = ICON.fetchFrom(params); + if (f != null && !f.getName().toLowerCase().endsWith(".icns")) { + Log.info(MessageFormat.format(I18N.getString("message.icon-not-icns"), f)); + return null; + } + return f; + }, + (s, p) -> new File(s)); + + public MacAppImageBuilder(Map config, Path imageOutDir) throws IOException { + super(config, imageOutDir.resolve(APP_NAME.fetchFrom(config) + ".app/Contents/PlugIns/Java.runtime/Contents/Home")); + + Objects.requireNonNull(imageOutDir); + + this.params = config; + this.root = imageOutDir.resolve(APP_NAME.fetchFrom(params) + ".app"); + this.contentsDir = root.resolve("Contents"); + this.javaDir = contentsDir.resolve("Java"); + this.resourcesDir = contentsDir.resolve("Resources"); + this.macOSDir = contentsDir.resolve("MacOS"); + this.runtimeDir = contentsDir.resolve("PlugIns/Java.runtime"); + this.runtimeRoot = runtimeDir.resolve("Contents/Home"); + this.mdir = runtimeRoot.resolve("lib"); + Files.createDirectories(javaDir); + Files.createDirectories(resourcesDir); + Files.createDirectories(macOSDir); + Files.createDirectories(runtimeDir); + } + + private static String extractAppName() { + return ""; + } + + private void writeEntry(InputStream in, Path dstFile) throws IOException { + Files.createDirectories(dstFile.getParent()); + Files.copy(in, dstFile); + } + + /** + * chmod ugo+x file + */ + private void setExecutable(Path file) { + try { + Set perms = Files.getPosixFilePermissions(file); + perms.add(PosixFilePermission.OWNER_EXECUTE); + perms.add(PosixFilePermission.GROUP_EXECUTE); + perms.add(PosixFilePermission.OTHERS_EXECUTE); + Files.setPosixFilePermissions(file, perms); + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } + } + + private static void createUtf8File(File file, String content) throws IOException { + try (OutputStream fout = new FileOutputStream(file); + Writer output = new OutputStreamWriter(fout, "UTF-8")) { + output.write(content); + } + } + + @Override + protected String getCacheLocation(Map params) { + return "$CACHEDIR/"; + } + + public static boolean validCFBundleVersion(String v) { + // CFBundleVersion (String - iOS, OS X) specifies the build version + // number of the bundle, which identifies an iteration (released or + // unreleased) of the bundle. The build version number should be a + // string comprised of three non-negative, period-separated integers + // with the first integer being greater than zero. The string should + // only contain numeric (0-9) and period (.) characters. Leading zeros + // are truncated from each integer and will be ignored (that is, + // 1.02.3 is equivalent to 1.2.3). This key is not localizable. + + if (v == null) { + return false; + } + + String p[] = v.split("\\."); + if (p.length > 3 || p.length < 1) { + Log.verbose(I18N.getString("message.version-string-too-many-components")); + return false; + } + + try { + BigInteger n = new BigInteger(p[0]); + if (BigInteger.ONE.compareTo(n) > 0) { + Log.verbose(I18N.getString("message.version-string-first-number-not-zero")); + return false; + } + if (p.length > 1) { + n = new BigInteger(p[1]); + if (BigInteger.ZERO.compareTo(n) > 0) { + Log.verbose(I18N.getString("message.version-string-no-negative-numbers")); + return false; + } + } + if (p.length > 2) { + n = new BigInteger(p[2]); + if (BigInteger.ZERO.compareTo(n) > 0) { + Log.verbose(I18N.getString("message.version-string-no-negative-numbers")); + return false; + } + } + } catch (NumberFormatException ne) { + Log.verbose(I18N.getString("message.version-string-numbers-only")); + Log.verbose(ne); + return false; + } + + return true; + } + + @Override + public InputStream getResourceAsStream(String name) { + return MacResources.class.getResourceAsStream(name); + } + + @Override + public void prepareApplicationFiles() throws IOException { + File f; + + // Generate PkgInfo + File pkgInfoFile = new File(contentsDir.toFile(), "PkgInfo"); + pkgInfoFile.createNewFile(); + writePkgInfo(pkgInfoFile); + + + // Copy executable to MacOS folder + Path executable = macOSDir.resolve(getLauncherName(params)); + writeEntry(MacResources.class.getResourceAsStream(EXECUTABLE_NAME), executable); + executable.toFile().setExecutable(true, false); + + // Copy library to the MacOS folder + writeEntry( + MacResources.class.getResourceAsStream(LIBRARY_NAME), + macOSDir.resolve(LIBRARY_NAME) + ); + + // generate launcher config + + writeCfgFile(params, new File(root.toFile(), getLauncherCfgName(params)), "$APPDIR/PlugIns/Java.runtime"); + + // Copy class path entries to Java folder + copyClassPathEntries(javaDir); + + /*********** Take care of "config" files *******/ + // Copy icon to Resources folder + File icon = ICON_ICNS.fetchFrom(params); + InputStream in = locateResource("package/macosx/" + APP_NAME.fetchFrom(params) + ".icns", + "icon", + DEFAULT_ICNS_ICON.fetchFrom(params), + icon, + VERBOSE.fetchFrom(params), + DROP_IN_RESOURCES_ROOT.fetchFrom(params)); + Files.copy(in, resourcesDir.resolve(APP_NAME.fetchFrom(params) + ".icns")); + + // copy file association icons + for (Map fa : FILE_ASSOCIATIONS.fetchFrom(params)) { + f = FA_ICON.fetchFrom(fa); + if (f != null && f.exists()) { + try (InputStream in2 = new FileInputStream(f)) { + Files.copy(in2, resourcesDir.resolve(f.getName())); + } + + } + } + + // Generate Info.plist + writeInfoPlist(contentsDir.resolve("Info.plist").toFile()); + + // generate java runtime info.plist + writeRuntimeInfoPlist(runtimeDir.resolve("Contents/Info.plist").toFile()); + + // copy library + Path runtimeMacOSDir = Files.createDirectories(runtimeDir.resolve("Contents/MacOS")); + Files.copy(runtimeRoot.resolve("lib/jli/libjli.dylib"), runtimeMacOSDir.resolve("libjli.dylib")); + + // maybe sign + if (Optional.ofNullable(SIGN_BUNDLE.fetchFrom(params)).orElse(Boolean.TRUE)) { + String signingIdentity = DEVELOPER_ID_APP_SIGNING_KEY.fetchFrom(params); + if (signingIdentity != null) { + signAppBundle(params, root, signingIdentity, BUNDLE_ID_SIGNING_PREFIX.fetchFrom(params), null, null); + } + } + } + + + private String getLauncherName(Map params) { + if (APP_NAME.fetchFrom(params) != null) { + return APP_NAME.fetchFrom(params); + } else { + return MAIN_CLASS.fetchFrom(params); + } + } + + public static String getLauncherCfgName(Map p) { + return "Contents/Java/" + APP_NAME.fetchFrom(p) + ".cfg"; + } + + private void copyClassPathEntries(Path javaDirectory) throws IOException { + List resourcesList = APP_RESOURCES_LIST.fetchFrom(params); + if (resourcesList == null) { + throw new RuntimeException(I18N.getString("message.null-classpath")); + } + + for (RelativeFileSet classPath : resourcesList) { + File srcdir = classPath.getBaseDirectory(); + for (String fname : classPath.getIncludedFiles()) { + // use new File since fname can have file separators + Files.copy(new File(srcdir, fname).toPath(), new File(javaDirectory.toFile(), fname).toPath()); + } + } + } + + private String getBundleName(Map params) { + if (MAC_CF_BUNDLE_NAME.fetchFrom(params) != null) { + String bn = MAC_CF_BUNDLE_NAME.fetchFrom(params); + if (bn.length() > 16) { + Log.info(MessageFormat.format(I18N.getString("message.bundle-name-too-long-warning"), MAC_CF_BUNDLE_NAME.getID(), bn)); + } + return MAC_CF_BUNDLE_NAME.fetchFrom(params); + } else if (APP_NAME.fetchFrom(params) != null) { + return APP_NAME.fetchFrom(params); + } else { + String nm = MAIN_CLASS.fetchFrom(params); + if (nm.length() > 16) { + nm = nm.substring(0, 16); + } + return nm; + } + } + + private void writeRuntimeInfoPlist(File file) throws IOException { + Map data = new HashMap<>(); + data.put("CF_BUNDLE_IDENTIFIER", "com.oracle.java." + MAC_CF_BUNDLE_IDENTIFIER.fetchFrom(params)); + data.put("CF_BUNDLE_NAME", "Java Runtime Image"); + data.put("CF_BUNDLE_VERSION", VERSION.fetchFrom(params)); + data.put("CF_BUDNEL_SHORT_VERSION_STRING", VERSION.fetchFrom(params)); + + Writer w = new BufferedWriter(new FileWriter(file)); + w.write(preprocessTextResource( + "package/macosx/Runtime-Info.plist", + I18N.getString("resource.runtime-info-plist"), + TEMPLATE_RUNTIME_INFO_PLIST, + data, + VERBOSE.fetchFrom(params), + DROP_IN_RESOURCES_ROOT.fetchFrom(params))); + w.close(); + } + + private void writeInfoPlist(File file) throws IOException { + Log.verbose(MessageFormat.format(I18N.getString("message.preparing-info-plist"), file.getAbsolutePath())); + + //prepare config for exe + //Note: do not need CFBundleDisplayName if we do not support localization + Map data = new HashMap<>(); + data.put("DEPLOY_ICON_FILE", APP_NAME.fetchFrom(params) + ".icns"); + data.put("DEPLOY_BUNDLE_IDENTIFIER", + MAC_CF_BUNDLE_IDENTIFIER.fetchFrom(params)); + data.put("DEPLOY_BUNDLE_NAME", + getBundleName(params)); + data.put("DEPLOY_BUNDLE_COPYRIGHT", + COPYRIGHT.fetchFrom(params) != null ? COPYRIGHT.fetchFrom(params) : "Unknown"); + data.put("DEPLOY_LAUNCHER_NAME", getLauncherName(params)); + data.put("DEPLOY_JAVA_RUNTIME_NAME", "$APPDIR/PlugIns/Java.runtime"); + data.put("DEPLOY_BUNDLE_SHORT_VERSION", + VERSION.fetchFrom(params) != null ? VERSION.fetchFrom(params) : "1.0.0"); + data.put("DEPLOY_BUNDLE_CFBUNDLE_VERSION", + MAC_CF_BUNDLE_VERSION.fetchFrom(params) != null ? MAC_CF_BUNDLE_VERSION.fetchFrom(params) : "100"); + data.put("DEPLOY_BUNDLE_CATEGORY", MAC_CATEGORY.fetchFrom(params)); + + boolean hasMainJar = MAIN_JAR.fetchFrom(params) != null; + boolean hasMainModule = StandardBundlerParam.MODULE.fetchFrom(params) != null; + + if (hasMainJar) { + data.put("DEPLOY_MAIN_JAR_NAME", MAIN_JAR.fetchFrom(params).getIncludedFiles().iterator().next()); + } + else if (hasMainModule) { + data.put("DEPLOY_MODULE_NAME", StandardBundlerParam.MODULE.fetchFrom(params)); + } + + data.put("DEPLOY_PREFERENCES_ID", PREFERENCES_ID.fetchFrom(params).toLowerCase()); + + StringBuilder sb = new StringBuilder(); + List jvmOptions = JVM_OPTIONS.fetchFrom(params); + + String newline = ""; //So we don't add unneccessary extra line after last append + for (String o : jvmOptions) { + sb.append(newline).append(" ").append(o).append(""); + newline = "\n"; + } + + Map jvmProps = JVM_PROPERTIES.fetchFrom(params); + for (Map.Entry entry : jvmProps.entrySet()) { + sb.append(newline) + .append(" -D") + .append(entry.getKey()) + .append("=") + .append(entry.getValue()) + .append(""); + newline = "\n"; + } + + String preloader = PRELOADER_CLASS.fetchFrom(params); + if (preloader != null) { + sb.append(newline) + .append(" -Djavafx.preloader=") + .append(preloader) + .append(""); + } + + data.put("DEPLOY_JVM_OPTIONS", sb.toString()); + + sb = new StringBuilder(); + List args = ARGUMENTS.fetchFrom(params); + newline = ""; //So we don't add unneccessary extra line after last append + for (String o : args) { + sb.append(newline).append(" ").append(o).append(""); + newline = "\n"; + } + data.put("DEPLOY_ARGUMENTS", sb.toString()); + + newline = ""; + sb = new StringBuilder(); + Map overridableJVMOptions = USER_JVM_OPTIONS.fetchFrom(params); + for (Map.Entry arg : overridableJVMOptions.entrySet()) { + sb.append(newline) + .append(" ").append(arg.getKey()).append("\n") + .append(" ").append(arg.getValue()).append(""); + newline = "\n"; + } + data.put("DEPLOY_JVM_USER_OPTIONS", sb.toString()); + + + data.put("DEPLOY_LAUNCHER_CLASS", MAIN_CLASS.fetchFrom(params)); + + StringBuilder macroedPath = new StringBuilder(); + for (String s : CLASSPATH.fetchFrom(params).split("[ ;:]+")) { + macroedPath.append(s); + macroedPath.append(":"); + } + macroedPath.deleteCharAt(macroedPath.length() - 1); + + data.put("DEPLOY_APP_CLASSPATH", macroedPath.toString()); + + StringBuilder bundleDocumentTypes = new StringBuilder(); + StringBuilder exportedTypes = new StringBuilder(); + for (Map fileAssociation : FILE_ASSOCIATIONS.fetchFrom(params)) { + + List extensions = FA_EXTENSIONS.fetchFrom(fileAssociation); + + if (extensions == null) { + Log.info(I18N.getString("message.creating-association-with-null-extension")); + } + + List mimeTypes = FA_CONTENT_TYPE.fetchFrom(fileAssociation); + String itemContentType = MAC_CF_BUNDLE_IDENTIFIER.fetchFrom(params) + "." + ((extensions == null || extensions.isEmpty()) + ? "mime" + : extensions.get(0)); + String description = FA_DESCRIPTION.fetchFrom(fileAssociation); + File icon = FA_ICON.fetchFrom(fileAssociation); //TODO FA_ICON_ICNS + + bundleDocumentTypes.append(" \n") + .append(" LSItemContentTypes\n") + .append(" \n") + .append(" ") + .append(itemContentType) + .append("\n") + .append(" \n") + .append("\n") + .append(" CFBundleTypeName\n") + .append(" ") + .append(description) + .append("\n") + .append("\n") + .append(" LSHandlerRank\n") + .append(" Owner\n") //TODO make a bundler arg + .append("\n") + .append(" CFBundleTypeRole\n") + .append(" Editor\n") // TODO make a bundler arg + .append("\n") + .append(" LSIsAppleDefaultForType\n") + .append(" \n") // TODO make a bundler arg + .append("\n"); + + if (icon != null && icon.exists()) { + //? + bundleDocumentTypes.append(" CFBundleTypeIconFile\n") + .append(" ") + .append(icon.getName()) + .append("\n"); + } + bundleDocumentTypes.append(" \n"); + + exportedTypes.append(" \n") + .append(" UTTypeIdentifier\n") + .append(" ") + .append(itemContentType) + .append("\n") + .append("\n") + .append(" UTTypeDescription\n") + .append(" ") + .append(description) + .append("\n") + .append(" UTTypeConformsTo\n") + .append(" \n") + .append(" public.data\n") //TODO expose this? + .append(" \n") + .append("\n"); + + if (icon != null && icon.exists()) { + exportedTypes.append(" UTTypeIconFile\n") + .append(" ") + .append(icon.getName()) + .append("\n") + .append("\n"); + } + + exportedTypes.append("\n") + .append(" UTTypeTagSpecification\n") + .append(" \n") + //TODO expose via param? .append(" com.apple.ostype\n"); + //TODO expose via param? .append(" ABCD\n") + .append("\n"); + + if (extensions != null && !extensions.isEmpty()) { + exportedTypes.append(" public.filename-extension\n") + .append(" \n"); + + for (String ext : extensions) { + exportedTypes.append(" ") + .append(ext) + .append("\n"); + } + exportedTypes.append(" \n"); + } + if (mimeTypes != null && !mimeTypes.isEmpty()) { + exportedTypes.append(" public.mime-type\n") + .append(" \n"); + + for (String mime : mimeTypes) { + exportedTypes.append(" ") + .append(mime) + .append("\n"); + } + exportedTypes.append(" \n"); + } + exportedTypes.append(" \n") + .append(" \n"); + } + String associationData; + if (bundleDocumentTypes.length() > 0) { + associationData = "\n CFBundleDocumentTypes\n \n" + + bundleDocumentTypes.toString() + + " \n\n UTExportedTypeDeclarations\n \n" + + exportedTypes.toString() + + " \n"; + } else { + associationData = ""; + } + data.put("DEPLOY_FILE_ASSOCIATIONS", associationData); + + + Writer w = new BufferedWriter(new FileWriter(file)); + w.write(preprocessTextResource( + //MAC_BUNDLER_PREFIX + getConfig_InfoPlist(params).getName(), + "package/macosx/Info.plist", + I18N.getString("resource.app-info-plist"), + TEMPLATE_INFO_PLIST_LITE, + data, VERBOSE.fetchFrom(params), + DROP_IN_RESOURCES_ROOT.fetchFrom(params))); + w.close(); + } + + private void writePkgInfo(File file) throws IOException { + //hardcoded as it does not seem we need to change it ever + String signature = "????"; + + try (Writer out = new BufferedWriter(new FileWriter(file))) { + out.write(OS_TYPE_CODE + signature); + out.flush(); + } + } + + public static void signAppBundle(Map params, Path appLocation, String signingIdentity, String identifierPrefix, String entitlementsFile, String inheritedEntitlements) throws IOException { + AtomicReference toThrow = new AtomicReference<>(); + String appExecutable = "/Contents/MacOS/" + APP_NAME.fetchFrom(params); + String keyChain = SIGNING_KEYCHAIN.fetchFrom(params); + + // sign all dylibs and jars + Files.walk(appLocation) + // fix permissions + .peek(path -> { + try { + Set pfp = Files.getPosixFilePermissions(path); + if (!pfp.contains(PosixFilePermission.OWNER_WRITE)) { + pfp = EnumSet.copyOf(pfp); + pfp.add(PosixFilePermission.OWNER_WRITE); + Files.setPosixFilePermissions(path, pfp); + } + } catch (IOException e) { + Log.debug(e); + } + }) + .filter(p -> Files.isRegularFile(p) && + !(p.toString().contains("/Contents/MacOS/libjli.dylib") + || p.toString().contains("/Contents/MacOS/JavaAppletPlugin") + || p.toString().endsWith(appExecutable)) + ).forEach(p -> { + //noinspection ThrowableResultOfMethodCallIgnored + if (toThrow.get() != null) return; + + // If p is a symlink then skip the signing process. + if (Files.isSymbolicLink(p)) { + if (VERBOSE.fetchFrom(params)) { + Log.verbose(MessageFormat.format(I18N.getString("message.ignoring.symlink"), p.toString())); + } + } + else { + List args = new ArrayList<>(); + args.addAll(Arrays.asList("codesign", + "-s", signingIdentity, // sign with this key + "--prefix", identifierPrefix, // use the identifier as a prefix + "-vvvv")); + if (entitlementsFile != null && + (p.toString().endsWith(".jar") + || p.toString().endsWith(".dylib"))) { + args.add("--entitlements"); + args.add(entitlementsFile); // entitlements + } else if (inheritedEntitlements != null && Files.isExecutable(p)) { + args.add("--entitlements"); + args.add(inheritedEntitlements); // inherited entitlements for executable processes + } + if (keyChain != null && !keyChain.isEmpty()) { + args.add("--keychain"); + args.add(keyChain); + } + args.add(p.toString()); + + try { + Set oldPermissions = Files.getPosixFilePermissions(p); + File f = p.toFile(); + f.setWritable(true, true); + + ProcessBuilder pb = new ProcessBuilder(args); + IOUtils.exec(pb, VERBOSE.fetchFrom(params)); + + Files.setPosixFilePermissions(p, oldPermissions); + } catch (IOException ioe) { + toThrow.set(ioe); + } + } + }); + + IOException ioe = toThrow.get(); + if (ioe != null) { + throw ioe; + } + + // sign all plugins and frameworks + Consumer signIdentifiedByPList = path -> { + //noinspection ThrowableResultOfMethodCallIgnored + if (toThrow.get() != null) return; + + try { + List args = new ArrayList<>(); + args.addAll(Arrays.asList("codesign", + "-s", signingIdentity, // sign with this key + "--prefix", identifierPrefix, // use the identifier as a prefix + "-vvvv")); + if (keyChain != null && !keyChain.isEmpty()) { + args.add("--keychain"); + args.add(keyChain); + } + args.add(path.toString()); + ProcessBuilder pb = new ProcessBuilder(args); + IOUtils.exec(pb, VERBOSE.fetchFrom(params)); + + args = new ArrayList<>(); + args.addAll(Arrays.asList("codesign", + "-s", signingIdentity, // sign with this key + "--prefix", identifierPrefix, // use the identifier as a prefix + "-vvvv")); + if (keyChain != null && !keyChain.isEmpty()) { + args.add("--keychain"); + args.add(keyChain); + } + args.add(path.toString() + "/Contents/_CodeSignature/CodeResources"); + pb = new ProcessBuilder(args); + IOUtils.exec(pb, VERBOSE.fetchFrom(params)); + } catch (IOException e) { + toThrow.set(e); + } + }; + + Path pluginsPath = appLocation.resolve("Contents/PlugIns"); + if (Files.isDirectory(pluginsPath)) { + Files.list(pluginsPath) + .forEach(signIdentifiedByPList); + + ioe = toThrow.get(); + if (ioe != null) { + throw ioe; + } + } + Path frameworkPath = appLocation.resolve("Contents/Frameworks"); + if (Files.isDirectory(frameworkPath)) { + Files.list(frameworkPath) + .forEach(signIdentifiedByPList); + + ioe = toThrow.get(); + if (ioe != null) { + throw ioe; + } + } + + // sign the app itself + List args = new ArrayList<>(); + args.addAll(Arrays.asList("codesign", + "-s", signingIdentity, // sign with this key + "-vvvv")); // super verbose output + if (entitlementsFile != null) { + args.add("--entitlements"); + args.add(entitlementsFile); // entitlements + } + if (keyChain != null && !keyChain.isEmpty()) { + args.add("--keychain"); + args.add(keyChain); + } + args.add(appLocation.toString()); + + ProcessBuilder pb = new ProcessBuilder(args.toArray(new String[args.size()])); + IOUtils.exec(pb, VERBOSE.fetchFrom(params)); + } + +} --- /dev/null 2017-08-15 12:38:30.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/jdk/packager/internal/legacy/builders/windows/WindowsAppImageBuilder.java 2017-08-15 12:38:30.000000000 -0700 @@ -0,0 +1,446 @@ +/* + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.packager.internal.legacy.builders.windows; + + +import com.oracle.tools.packager.BundlerParamInfo; +import com.oracle.tools.packager.Log; +import com.oracle.tools.packager.RelativeFileSet; +import com.oracle.tools.packager.IOUtils; +import com.oracle.tools.packager.StandardBundlerParam; +import com.oracle.tools.packager.windows.WinResources; +import com.oracle.tools.packager.windows.WindowsBundlerParam; +import jdk.packager.internal.legacy.builders.AbstractAppImageBuilder; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.UncheckedIOException; +import java.io.Writer; +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.PosixFilePermission; +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.ResourceBundle; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; +import java.util.regex.Pattern; +import java.util.stream.Stream; + +import static com.oracle.tools.packager.StandardBundlerParam.*; +import jdk.packager.internal.legacy.windows.WindowsDefender; + +/** + * + */ +public class WindowsAppImageBuilder extends AbstractAppImageBuilder { + + private static final ResourceBundle I18N = + ResourceBundle.getBundle(WindowsAppImageBuilder.class.getName()); + + protected static final String WINDOWS_BUNDLER_PREFIX = + BUNDLER_PREFIX + "windows" + File.separator; + + private final static String EXECUTABLE_NAME = "WinLauncher.exe"; + private final static String LIBRARY_NAME = "packager.dll"; + + private final static String[] VS_VERS = {"100", "110", "120", "140"}; + private final static String REDIST_MSVCR = "vcruntimeVS_VER.dll"; + private final static String REDIST_MSVCP = "msvcpVS_VER.dll"; + + private final static String TEMPLATE_APP_ICON ="javalogo_white_48.ico"; + + private static final String EXECUTABLE_PROPERTIES_TEMPLATE = "WinLauncher.properties"; + + private final Path root; + private final Path appDir; + private final Path runtimeDir; + private final Path mdir; + + private final Map params; + + public static final BundlerParamInfo CONFIG_ROOT = new WindowsBundlerParam<>( + I18N.getString("param.config-root.name"), + I18N.getString("param.config-root.description"), + "configRoot", + File.class, + params -> { + File imagesRoot = new File(BUILD_ROOT.fetchFrom(params), "windows"); + imagesRoot.mkdirs(); + return imagesRoot; + }, + (s, p) -> null); + + public static final BundlerParamInfo REBRAND_EXECUTABLE = new WindowsBundlerParam<>( + I18N.getString("param.rebrand-executable.name"), + I18N.getString("param.rebrand-executable.description"), + "win.launcher.rebrand", + Boolean.class, + params -> Boolean.TRUE, + (s, p) -> Boolean.valueOf(s)); + + public static final BundlerParamInfo ICON_ICO = new StandardBundlerParam<>( + I18N.getString("param.icon-ico.name"), + I18N.getString("param.icon-ico.description"), + "icon.ico", + File.class, + params -> { + File f = ICON.fetchFrom(params); + if (f != null && !f.getName().toLowerCase().endsWith(".ico")) { + Log.info(MessageFormat.format(I18N.getString("message.icon-not-ico"), f)); + return null; + } + return f; + }, + (s, p) -> new File(s)); + + + + public WindowsAppImageBuilder(Map config, Path imageOutDir) throws IOException { + super(config, imageOutDir.resolve(APP_NAME.fetchFrom(config) + "/runtime")); + + Objects.requireNonNull(imageOutDir); + + this.params = config; + + this.root = imageOutDir.resolve(APP_NAME.fetchFrom(params)); + this.appDir = root.resolve("app"); + this.runtimeDir = root.resolve("runtime"); + this.mdir = runtimeDir.resolve("lib"); + Files.createDirectories(appDir); + Files.createDirectories(runtimeDir); + } + + private Path destFile(String dir, String filename) { + return runtimeDir.resolve(dir).resolve(filename); + } + + private void writeEntry(InputStream in, Path dstFile) throws IOException { + Files.createDirectories(dstFile.getParent()); + Files.copy(in, dstFile); + } + + private void writeSymEntry(Path dstFile, Path target) throws IOException { + Files.createDirectories(dstFile.getParent()); + Files.createLink(dstFile, target); + } + + /** + * chmod ugo+x file + */ + private void setExecutable(Path file) { + try { + Set perms = Files.getPosixFilePermissions(file); + perms.add(PosixFilePermission.OWNER_EXECUTE); + perms.add(PosixFilePermission.GROUP_EXECUTE); + perms.add(PosixFilePermission.OTHERS_EXECUTE); + Files.setPosixFilePermissions(file, perms); + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } + } + + private static void createUtf8File(File file, String content) throws IOException { + try (OutputStream fout = new FileOutputStream(file); + Writer output = new OutputStreamWriter(fout, "UTF-8")) { + output.write(content); + } + } + + // This method is static for the sake of sharing with "installer" bundlers + // that may skip calls to validate/bundle in this class! + public static File getRootDir(File outDir, Map p) { + return new File(outDir, APP_FS_NAME.fetchFrom(p)); + } + + public static String getLauncherName(Map p) { + return APP_FS_NAME.fetchFrom(p) + ".exe"; + } + + public static String getLauncherCfgName(Map p) { + return "app/" + APP_FS_NAME.fetchFrom(p) +".cfg"; + } + + private File getConfig_AppIcon(Map params) { + return new File(getConfigRoot(params), APP_FS_NAME.fetchFrom(params) + ".ico"); + } + + private File getConfig_ExecutableProperties(Map params) { + return new File(getConfigRoot(params), APP_FS_NAME.fetchFrom(params) + ".properties"); + } + + File getConfigRoot(Map params) { + return CONFIG_ROOT.fetchFrom(params); + } + + protected void cleanupConfigFiles(Map params) { + getConfig_AppIcon(params).delete(); + getConfig_ExecutableProperties(params).delete(); + } + + @Override + public InputStream getResourceAsStream(String name) { + return WinResources.class.getResourceAsStream(name); + } + + @Override + public void prepareApplicationFiles() throws IOException { + Map originalParams = new HashMap<>(params); + File rootFile = root.toFile(); + if (!rootFile.isDirectory() && !rootFile.mkdirs()) { + throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-create-output-dir"), rootFile.getAbsolutePath())); + } + if (!rootFile.canWrite()) { + throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-write-to-output-dir"), rootFile.getAbsolutePath())); + } + try { +// if (!dependentTask) { +// Log.info(MessageFormat.format(I18N.getString("message.creating-app-bundle"), APP_NAME.fetchFrom(p), outputDirectory.getAbsolutePath())); +// } + + // Create directory structure +// IOUtils.deleteRecursive(rootDirectory); +// rootDirectory.mkdirs(); + + + // create the .exe launchers + createLauncherForEntryPoint(params); + + // copy the jars + copyApplication(params); + + // copy in the needed libraries + Files.copy(WinResources.class.getResourceAsStream(LIBRARY_NAME), + root.resolve(LIBRARY_NAME)); + + copyMSVCDLLs(); + + // create the secondary launchers, if any + List> entryPoints = StandardBundlerParam.SECONDARY_LAUNCHERS.fetchFrom(params); + for (Map entryPoint : entryPoints) { + Map tmp = new HashMap<>(originalParams); + tmp.putAll(entryPoint); + createLauncherForEntryPoint(tmp); + } + + } catch (IOException ex) { + Log.info("Exception: "+ex); + Log.debug(ex); + } finally { + + if (VERBOSE.fetchFrom(params)) { + Log.info(MessageFormat.format(I18N.getString("message.config-save-location"), getConfigRoot(params).getAbsolutePath())); + } else { + cleanupConfigFiles(params); + } + } + } + + private void copyMSVCDLLs() throws IOException { + String vsVer = null; + + // first copy the ones needed for the launcher + for (String thisVer : VS_VERS) { + if (copyMSVCDLLs(thisVer)) { + vsVer = thisVer; + break; + } + } + if (vsVer == null) { + throw new RuntimeException("Not found MSVC dlls"); + } + + AtomicReference ioe = new AtomicReference<>(); + final String finalVsVer = vsVer; + try (Stream files = Files.list(runtimeDir.resolve("bin"))) { + files.filter(p -> Pattern.matches("(vcruntime|msvcp)\\d\\d\\d.dll", p.toFile().getName().toLowerCase())) + .filter(p -> !p.toString().toLowerCase().endsWith(finalVsVer + ".dll")) + .forEach(p -> { + try { + Files.copy(p, root.resolve((p.toFile().getName()))); + } catch (IOException e) { + ioe.set(e); + } + }); + } + + IOException e = ioe.get(); + if (e != null) { + throw e; + } + } + + private boolean copyMSVCDLLs(String VS_VER) throws IOException { + final InputStream REDIST_MSVCR_URL = WinResources.class.getResourceAsStream( + REDIST_MSVCR.replaceAll("VS_VER", VS_VER)); + final InputStream REDIST_MSVCP_URL = WinResources.class.getResourceAsStream( + REDIST_MSVCP.replaceAll("VS_VER", VS_VER)); + + if (REDIST_MSVCR_URL != null && REDIST_MSVCP_URL != null) { + Files.copy( + REDIST_MSVCR_URL, + root.resolve(REDIST_MSVCR.replaceAll("VS_VER", VS_VER))); + Files.copy( + REDIST_MSVCP_URL, + root.resolve(REDIST_MSVCP.replaceAll("VS_VER", VS_VER))); + return true; + } + + return false; // not found + } + + private void validateValueAndPut(Map data, String key, + BundlerParamInfo param, Map params) { + String value = param.fetchFrom(params); + if (value.contains("\r") || value.contains("\n")) { + Log.info("Configuration Parameter " + param.getID() + " contains multiple lines of text, ignore it"); + data.put(key, ""); + return; + } + data.put(key, value); + } + + protected void prepareExecutableProperties(Map params) + throws IOException { + Map data = new HashMap<>(); + + // mapping Java parameters in strings for version resource + data.put("COMMENTS", ""); + validateValueAndPut(data, "COMPANY_NAME", VENDOR, params); + validateValueAndPut(data, "FILE_DESCRIPTION", DESCRIPTION, params); + validateValueAndPut(data, "FILE_VERSION", VERSION, params); + data.put("INTERNAL_NAME", getLauncherName(params)); + validateValueAndPut(data, "LEGAL_COPYRIGHT", COPYRIGHT, params); + data.put("LEGAL_TRADEMARK", ""); + data.put("ORIGINAL_FILENAME", getLauncherName(params)); + data.put("PRIVATE_BUILD", ""); + validateValueAndPut(data, "PRODUCT_NAME", APP_NAME, params); + validateValueAndPut(data, "PRODUCT_VERSION", VERSION, params); + data.put("SPECIAL_BUILD", ""); + + Writer w = new BufferedWriter(new FileWriter(getConfig_ExecutableProperties(params))); + String content = preprocessTextResource( + WINDOWS_BUNDLER_PREFIX + getConfig_ExecutableProperties(params).getName(), + I18N.getString("resource.executable-properties-template"), EXECUTABLE_PROPERTIES_TEMPLATE, data, + VERBOSE.fetchFrom(params), + DROP_IN_RESOURCES_ROOT.fetchFrom(params)); + w.write(content); + w.close(); + } + + private void createLauncherForEntryPoint(Map p) throws IOException { + + File launcherIcon = ICON_ICO.fetchFrom(p); + File icon = launcherIcon != null ? launcherIcon : ICON_ICO.fetchFrom(params); + File iconTarget = getConfig_AppIcon(p); + + InputStream in = locateResource("package/windows/" + APP_NAME.fetchFrom(params) + ".ico", + "icon", + TEMPLATE_APP_ICON, + icon, + VERBOSE.fetchFrom(params), + DROP_IN_RESOURCES_ROOT.fetchFrom(params)); + Files.copy(in, iconTarget.toPath()); + + writeCfgFile(p, root.resolve(getLauncherCfgName(p)).toFile(), "$APPDIR\\runtime"); + + prepareExecutableProperties(p); + + // Copy executable root folder + Path executableFile = root.resolve(getLauncherName(p)); + writeEntry(WinResources.class.getResourceAsStream(EXECUTABLE_NAME), executableFile); + File launcher = executableFile.toFile(); + launcher.setWritable(true, true); + + // Update branding of EXE file + if (REBRAND_EXECUTABLE.fetchFrom(p)) { + File tool = new File(System.getProperty("java.home") + "\\bin\\javapackager.exe"); + + // Run tool on launcher file to change the icon and the metadata. + try { + if (WindowsDefender.isThereAPotentialWindowsDefenderIssue()) { + Log.info(MessageFormat.format(I18N.getString("message.potential.windows.defender.issue"), WindowsDefender.getUserTempDirectory())); + } + + launcher.setWritable(true); + + if (iconTarget.exists()) { + ProcessBuilder pb = new ProcessBuilder( + tool.getAbsolutePath(), + "--icon-swap", + iconTarget.getAbsolutePath(), + launcher.getAbsolutePath()); + IOUtils.exec(pb, VERBOSE.fetchFrom(p)); + } + + File executableProperties = getConfig_ExecutableProperties(p); + + if (executableProperties.exists()) { + ProcessBuilder pb = new ProcessBuilder( + tool.getAbsolutePath(), + "--version-swap", + executableProperties.getAbsolutePath(), + launcher.getAbsolutePath()); + IOUtils.exec(pb, VERBOSE.fetchFrom(p)); + } + } + finally { + executableFile.toFile().setReadOnly(); + } + } + + Files.copy(iconTarget.toPath(), root.resolve(APP_NAME.fetchFrom(p) + ".ico")); + } + + private void copyApplication(Map params) throws IOException { + List appResourcesList = APP_RESOURCES_LIST.fetchFrom(params); + if (appResourcesList == null) { + throw new RuntimeException("Null app resources?"); + } + for (RelativeFileSet appResources : appResourcesList) { + if (appResources == null) { + throw new RuntimeException("Null app resources?"); + } + File srcdir = appResources.getBaseDirectory(); + for (String fname : appResources.getIncludedFiles()) { + Files.copy(new File(srcdir, fname).toPath(), new File(appDir.toFile(), fname).toPath()); + } + } + } + + @Override + protected String getCacheLocation(Map params) { + return "$CACHEDIR/"; + } +} --- /dev/null 2017-08-15 12:38:31.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/jdk/packager/internal/legacy/mac/MacCertificate.java 2017-08-15 12:38:31.000000000 -0700 @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.packager.internal.legacy.mac; + +import com.oracle.tools.packager.IOUtils; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +final public class MacCertificate { + private String certificate; + private boolean verbose; + + public MacCertificate(String certificate) { + this.certificate = certificate; + this.verbose = false; + } + + public MacCertificate(String certificate, boolean verbose) { + this.certificate = certificate; + this.verbose = verbose; + } + + public boolean isValid() { + return verifyCertificate(this.certificate, verbose); + } + + private static File findCertificate(String certificate, boolean verbose) { + File result = null; + + List args = new ArrayList<>(); + args.add("security"); + args.add("find-certificate"); + args.add("-c"); + args.add(certificate); + args.add("-a"); + args.add("-p"); + + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos)) { + ProcessBuilder security = new ProcessBuilder(args); + IOUtils.exec(security, verbose, false, ps); + + File output = File.createTempFile("tempfile", ".tmp"); + PrintStream p = new PrintStream(new BufferedOutputStream(new FileOutputStream(output, true))); + BufferedReader bfReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(baos.toByteArray()))); + String line = null; + + while((line = bfReader.readLine()) != null){ + p.println(line); + } + + p.close(); + result = output; + } + catch (IOException ioe) { + } + + return result; + } + + private static Date findCertificateDate(String filename, boolean verbose) { + Date result = null; + + List args = new ArrayList<>(); + args.add("/usr/bin/openssl"); + args.add("x509"); + args.add("-noout"); + args.add("-enddate"); + args.add("-in"); + args.add(filename); + + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos)) { + ProcessBuilder security = new ProcessBuilder(args); + IOUtils.exec(security, verbose, false, ps); + String output = baos.toString(); + output = output.substring(output.indexOf("=") + 1); + DateFormat df = new SimpleDateFormat("MMM dd kk:mm:ss yyyy z", Locale.ENGLISH); + result = df.parse(output); + } + catch (IOException ioe) { + } + catch (ParseException ex) { + } + + return result; + } + + private static boolean verifyCertificate(String certificate, boolean verbose) { + boolean result = false; + + try { + File file = null; + Date certificateDate = null; + + try { + file = findCertificate(certificate, verbose); + + if (file != null) { + certificateDate = findCertificateDate(file.getCanonicalPath(), verbose); + } + } + finally { + if (file != null) { + file.delete(); + } + } + + if (certificateDate != null) { + Calendar c = Calendar.getInstance(); + Date today = c.getTime(); + + if (certificateDate.after(today)) { + result = true; + } + } + } + catch (IOException ex) { + } + + return result; + } +} \ No newline at end of file --- /dev/null 2017-08-15 12:38:32.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/jdk/packager/internal/legacy/windows/WindowsDefender.java 2017-08-15 12:38:32.000000000 -0700 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.packager.internal.legacy.windows; + +import com.oracle.tools.packager.Platform; +import java.util.List; + +public final class WindowsDefender { + + private WindowsDefender() {} + + public static final boolean isThereAPotentialWindowsDefenderIssue() { + boolean result = false; + + if (Platform.getPlatform() == Platform.WINDOWS && + Platform.getMajorVersion() == 10) { + + // If DisableRealtimeMonitoring is not enabled then there + // may be a problem. + if (!WindowsRegistry.readDisableRealtimeMonitoring() && + !isTempDirectoryInExclusionPath()) { + result = true; + } + } + + return result; + } + + private static final boolean isTempDirectoryInExclusionPath() { + boolean result = false; + // If the user temp directory is not found in the exclusion + // list then there may be a problem. + List paths = WindowsRegistry.readExclusionsPaths(); + String tempDirectory = getUserTempDirectory(); + + for (String s : paths) { + if (s.equals(tempDirectory)) { + result = true; + break; + } + } + + return result; + } + + public static final String getUserTempDirectory() { + String tempDirectory = System.getProperty("java.io.tmpdir"); + return tempDirectory; + } +} --- /dev/null 2017-08-15 12:38:34.000000000 -0700 +++ new/modules/jdk.packager/src/main/java/jdk/packager/internal/legacy/windows/WindowsRegistry.java 2017-08-15 12:38:33.000000000 -0700 @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.packager.internal.legacy.windows; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; + +import static com.oracle.tools.packager.IOUtils.exec; + +public final class WindowsRegistry { + + private WindowsRegistry() {} + + /** + * Reads the registry value for DisableRealtimeMonitoring. + * @return true if DisableRealtimeMonitoring is set to 0x1, false otherwise. + */ + public static final boolean readDisableRealtimeMonitoring() { + boolean result = false; + final String key = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows Defender\\Real-Time Protection"; + final String subkey = "DisableRealtimeMonitoring"; + String value = readRegistry(key, subkey); + + if (!value.isEmpty()) { + // This code could be written better but this works. It validates + // that the result of readRegistry returned what we expect and then + // checks for a 0x0 or 0x1. 0x0 means real time monitoring is + // on, 0x1 means it is off. So this function returns true if + // real-time-monitoring is disabled. + int index = value.indexOf(subkey); + value = value.substring(index + subkey.length()); + String reg = "REG_DWORD"; + index = value.indexOf(reg); + value = value.substring(index + reg.length()); + String hex = "0x"; + index = value.indexOf(hex); + value = value.substring(index + hex.length()); + + if (value.equals("1")) { + result = true; + } + } + + return result; + } + + public static final List readExclusionsPaths() { + List result = new ArrayList(); + final String key = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows Defender\\Exclusions\\Paths"; + String value = readRegistry(key, ""); + + if (!value.isEmpty()) { + final String reg = "REG_DWORD"; + final String hex = "0x0"; + + int index = value.indexOf(key); + if (index == 0) { + value = value.substring(index + key.length()); + + while (value.length() > 0) { + index = value.indexOf(reg); + String name = value.substring(0, index); + value = value.substring(index + reg.length()); + index = value.indexOf(hex); + value = value.substring(index + hex.length()); + + if (index > 0) { + name = name.trim(); + result.add(name); + } + } + } + } + + return result; + } + /** + * @param key in the registry + * @param subkey in the registry key + * @return registry value or null if not found + */ + public static final String readRegistry(String key, String subkey){ + String result = ""; + + try { + List buildOptions = new ArrayList<>(); + buildOptions.add("reg"); + buildOptions.add("query"); + buildOptions.add("\"" + key + "\""); + + if (!subkey.isEmpty()) { + buildOptions.add("/v"); + buildOptions.add(subkey); + } + + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos)) { + ProcessBuilder security = new ProcessBuilder(buildOptions); + exec(security, false, false, ps); + BufferedReader bfReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(baos.toByteArray()))); + String line = null; + + while((line = bfReader.readLine()) != null){ + result += line; + } + } + catch (IOException e) { + } + } + catch (Exception e) { + } + + return result; + } +} --- /dev/null 2017-08-15 12:38:35.000000000 -0700 +++ new/modules/jdk.packager/src/main/resources/jdk/packager/internal/legacy/JLinkBundlerHelper.properties 2017-08-15 12:38:34.000000000 -0700 @@ -0,0 +1,17 @@ +param.detect-modules.name=Auto Modules +param.detect-modules.description=Automatically calculate modules to Limit JImage creation to. + +param.jlink-options.name=JLink Options +param.jlink-options.description=Options to be added to JLink invocation. + +param.jlink-builder.name=JLink Builder +param.jlink-builder.description=Name of the JLink Builder to build the applicaiton image with. + +error.srcfiles.contain.modules=Error: Modules are not allowed in srcfiles: {0}. + +warning.module.does.not.exist=Module {0} does not exist. + +message.detected.modules="Automatically adding detected modules: {0}." +message.modules="Adding modules: {0} to runtime image." + +using.experimental.feature="Using experimental feature: {0}." \ No newline at end of file --- /dev/null 2017-08-15 12:38:36.000000000 -0700 +++ new/modules/jdk.packager/src/main/resources/jdk/packager/internal/legacy/JLinkBundlerHelper_ja.properties 2017-08-15 12:38:35.000000000 -0700 @@ -0,0 +1,17 @@ +param.detect-modules.name=\u81EA\u52D5\u30E2\u30B8\u30E5\u30FC\u30EB +param.detect-modules.description=JImage\u306E\u4F5C\u6210\u3092\u5236\u9650\u3059\u308B\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u81EA\u52D5\u7684\u306B\u8A08\u7B97\u3057\u307E\u3059\u3002 + +param.jlink-options.name=JLink\u30AA\u30D7\u30B7\u30E7\u30F3 +param.jlink-options.description=JLink\u306E\u8D77\u52D5\u306B\u8FFD\u52A0\u3055\u308C\u308B\u30AA\u30D7\u30B7\u30E7\u30F3 + +param.jlink-builder.name=JLink\u30D3\u30EB\u30C0\u30FC +param.jlink-builder.description=\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30A4\u30E1\u30FC\u30B8\u3092\u4F5C\u6210\u3059\u308BJLink\u30D3\u30EB\u30C0\u30FC\u306E\u540D\u524D + +error.srcfiles.contain.modules=\u30A8\u30E9\u30FC: \u30E2\u30B8\u30E5\u30FC\u30EB\u306Fsrcfiles\u3067\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093: {0}\u3002 + +warning.module.does.not.exist=\u30E2\u30B8\u30E5\u30FC\u30EB{0}\u306F\u5B58\u5728\u3057\u307E\u305B\u3093\u3002 + +message.detected.modules="\u691C\u51FA\u3055\u308C\u305F\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u81EA\u52D5\u7684\u306B\u8FFD\u52A0\u3057\u3066\u3044\u307E\u3059: {0}." +message.modules="\u30E2\u30B8\u30E5\u30FC\u30EB: {0}\u3092\u30E9\u30F3\u30BF\u30A4\u30E0\u30FB\u30A4\u30E1\u30FC\u30B8\u306B\u8FFD\u52A0\u3057\u3066\u3044\u307E\u3059\u3002" + +using.experimental.feature="\u8A66\u9A13\u7684\u306A\u6A5F\u80FD\u3092\u4F7F\u7528\u3057\u3066\u3044\u307E\u3059: {0}\u3002" --- /dev/null 2017-08-15 12:38:37.000000000 -0700 +++ new/modules/jdk.packager/src/main/resources/jdk/packager/internal/legacy/JLinkBundlerHelper_zh_CN.properties 2017-08-15 12:38:37.000000000 -0700 @@ -0,0 +1,17 @@ +param.detect-modules.name=\u81EA\u52A8\u6A21\u5757 +param.detect-modules.description=\u81EA\u52A8\u8BA1\u7B97\u6A21\u5757\u4EE5\u5C06 JImage \u521B\u5EFA\u64CD\u4F5C\u9650\u5236\u4E3A\u8FD9\u4E9B\u6A21\u5757\u3002 + +param.jlink-options.name=JLink \u9009\u9879 +param.jlink-options.description=\u8981\u6DFB\u52A0\u5230 JLink \u8C03\u7528\u7684\u9009\u9879\u3002 + +param.jlink-builder.name=JLink Builder +param.jlink-builder.description=\u7528\u4E8E\u6784\u5EFA\u5E94\u7528\u7A0B\u5E8F\u6620\u50CF\u7684 JLink Builder \u7684\u540D\u79F0\u3002 + +error.srcfiles.contain.modules=\u9519\u8BEF: srcfile \u4E2D\u4E0D\u5141\u8BB8\u6A21\u5757: {0}\u3002 + +warning.module.does.not.exist=\u6A21\u5757 {0} \u4E0D\u5B58\u5728\u3002 + +message.detected.modules="\u6B63\u5728\u81EA\u52A8\u6DFB\u52A0\u68C0\u6D4B\u5230\u7684\u6A21\u5757: {0}\u3002" +message.modules="\u6B63\u5728\u5C06\u6A21\u5757 {0} \u6DFB\u52A0\u5230\u8FD0\u884C\u65F6\u6620\u50CF\u3002" + +using.experimental.feature="\u6B63\u5728\u4F7F\u7528\u8BD5\u9A8C\u529F\u80FD: {0}\u3002" --- /dev/null 2017-08-15 12:38:38.000000000 -0700 +++ new/modules/jdk.packager/src/main/resources/jdk/packager/internal/legacy/builders/AbstractAppImageBuilder.properties 2017-08-15 12:38:38.000000000 -0700 @@ -0,0 +1,5 @@ +message.using-default-resource=Using default package resource {0} (add {1} to the class path to customize) +message.using-custom-resource-from-file=Using custom package resource {0} (loaded from file {1}) +message.using-custom-resource-from-classpath=Using custom package resource {0} (loaded from {1}) +message.using-default-resource-from-classpath=Using default package resource {0} (add {1} to the class path to customize) +message.jvm-user-arg-is-null=WARNING\: a jvmuserarg has a null name or value. --- /dev/null 2017-08-15 12:38:40.000000000 -0700 +++ new/modules/jdk.packager/src/main/resources/jdk/packager/internal/legacy/builders/AbstractAppImageBuilder_ja.properties 2017-08-15 12:38:39.000000000 -0700 @@ -0,0 +1,5 @@ +message.using-default-resource=\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30BD\u30FC\u30B9{0}\u306E\u4F7F\u7528({1}\u3092\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306B\u8FFD\u52A0\u3057\u3066\u30AB\u30B9\u30BF\u30DE\u30A4\u30BA) +message.using-custom-resource-from-file=\u30AB\u30B9\u30BF\u30E0\u30FB\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30BD\u30FC\u30B9{0}\u306E\u4F7F\u7528(\u30D5\u30A1\u30A4\u30EB{1}\u304B\u3089\u30ED\u30FC\u30C9\u6E08) +message.using-custom-resource-from-classpath=\u30AB\u30B9\u30BF\u30E0\u30FB\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30BD\u30FC\u30B9{0}\u306E\u4F7F\u7528({1}\u304B\u3089\u30ED\u30FC\u30C9\u6E08) +message.using-default-resource-from-classpath=\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30BD\u30FC\u30B9{0}\u306E\u4F7F\u7528({1}\u3092\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306B\u8FFD\u52A0\u3057\u3066\u30AB\u30B9\u30BF\u30DE\u30A4\u30BA) +message.jvm-user-arg-is-null=\u8B66\u544A: jvmuserarg\u306Bnull\u306E\u540D\u524D\u307E\u305F\u306F\u5024\u304C\u3042\u308A\u307E\u3059\u3002 --- /dev/null 2017-08-15 12:38:43.000000000 -0700 +++ new/modules/jdk.packager/src/main/resources/jdk/packager/internal/legacy/builders/AbstractAppImageBuilder_zh_CN.properties 2017-08-15 12:38:43.000000000 -0700 @@ -0,0 +1,5 @@ +message.using-default-resource=\u4F7F\u7528\u9ED8\u8BA4\u7A0B\u5E8F\u5305\u8D44\u6E90 {0} (\u5C06 {1} \u6DFB\u52A0\u5230\u7C7B\u8DEF\u5F84\u4EE5\u5B9A\u5236) +message.using-custom-resource-from-file=\u4F7F\u7528\u5B9A\u5236\u7A0B\u5E8F\u5305\u8D44\u6E90 {0} (\u4ECE\u6587\u4EF6 {1} \u52A0\u8F7D) +message.using-custom-resource-from-classpath=\u4F7F\u7528\u5B9A\u5236\u7A0B\u5E8F\u5305\u8D44\u6E90 {0} (\u4ECE {1} \u52A0\u8F7D) +message.using-default-resource-from-classpath=\u4F7F\u7528\u9ED8\u8BA4\u7A0B\u5E8F\u5305\u8D44\u6E90 {0} (\u5C06 {1} \u6DFB\u52A0\u5230\u7C7B\u8DEF\u5F84\u4EE5\u5B9A\u5236) +message.jvm-user-arg-is-null=\u8B66\u544A: jvmuserarg \u7684\u540D\u79F0\u6216\u503C\u4E3A\u7A7A\u503C\u3002 --- /dev/null 2017-08-15 12:38:45.000000000 -0700 +++ new/modules/jdk.packager/src/main/resources/jdk/packager/internal/legacy/builders/linux/LinuxAppImageBuilder.properties 2017-08-15 12:38:45.000000000 -0700 @@ -0,0 +1,4 @@ +param.icon-png.name=.png Icon +param.icon-png.description=Icon for the application, in PNG format. + +message.icon-not-png=The specified icon "{0}" is not a PNG file and will not be used. The default icon will be used in it's place. --- /dev/null 2017-08-15 12:38:47.000000000 -0700 +++ new/modules/jdk.packager/src/main/resources/jdk/packager/internal/legacy/builders/linux/LinuxAppImageBuilder_ja.properties 2017-08-15 12:38:46.000000000 -0700 @@ -0,0 +1,4 @@ +param.icon-png.name=.png\u30A2\u30A4\u30B3\u30F3 +param.icon-png.description=PNG\u5F62\u5F0F\u3067\u306E\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u30A2\u30A4\u30B3\u30F3\u3002 + +message.icon-not-png=\u6307\u5B9A\u3057\u305F\u30A2\u30A4\u30B3\u30F3"{0}"\u306FPNG\u30D5\u30A1\u30A4\u30EB\u3067\u306F\u306A\u304F\u3001\u4F7F\u7528\u3055\u308C\u307E\u305B\u3093\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30A2\u30A4\u30B3\u30F3\u304C\u305D\u306E\u4F4D\u7F6E\u306B\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002 --- /dev/null 2017-08-15 12:38:48.000000000 -0700 +++ new/modules/jdk.packager/src/main/resources/jdk/packager/internal/legacy/builders/linux/LinuxAppImageBuilder_zh_CN.properties 2017-08-15 12:38:48.000000000 -0700 @@ -0,0 +1,4 @@ +param.icon-png.name=.png \u56FE\u6807 +param.icon-png.description=\u5E94\u7528\u7A0B\u5E8F\u7684\u56FE\u6807, \u91C7\u7528 PNG \u683C\u5F0F\u3002 + +message.icon-not-png=\u6307\u5B9A\u7684\u56FE\u6807 "{0}" \u4E0D\u662F PNG \u6587\u4EF6, \u4E0D\u4F1A\u4F7F\u7528\u3002\u5C06\u4F7F\u7528\u9ED8\u8BA4\u56FE\u6807\u4EE3\u66FF\u3002 --- /dev/null 2017-08-15 12:38:50.000000000 -0700 +++ new/modules/jdk.packager/src/main/resources/jdk/packager/internal/legacy/builders/mac/MacAppImageBuilder.properties 2017-08-15 12:38:49.000000000 -0700 @@ -0,0 +1,73 @@ +bundler.name=Mac Application Image +bundler.description=A Directory based image of a mac Application with an optionally co-bundled JRE. Used as a base for the Installer bundlers + +param.signing-key-developer-id-app.name=Apple Developer ID Application Signing Key +param.signing-key-developer-id-app.description=The full name of the Apple Developer ID Application signing key. + +param.icon-icns.name=.icns Icon +param.icon-icns.description= Icon for the application, in ICNS format. + +param.config-root.name= +param.config-root.description= + +param.configure-launcher-in-plist=Configure Launcher in Info.plist +param.configure-launcher-in-plist.description=Should the legacy method of configuring hte launcher in the Info.plist be used. + +param.category-name=Category +param.category-name.description=Mac App Store Categories. Note that the key is the string to display to the user and the value is the id of the category. + +param.cfbundle-name.name=CFBundleName +param.cfbundle-name.description=The name of the app as it appears in the Menu Bar. This can be different from the application name. This name should be less than 16 characters long and be suitable for displaying in the menu bar and the app's Info window. + +param.cfbundle-identifier.name=CFBundleIdentifier +param.cfbundle-identifier.description=An identifier that uniquely identifies the application for MacOSX (and on the Mac App Store). May only use alphanumeric (A-Z,a-z,0-9), hyphen (-), and period (.) characters. + +param.cfbundle-version.name=CFBundleVersion +param.cfbundle-version.description=An computer readable version for the CFBundle. May contain only digits and from zero to two dots, such as "1.8.1" or "100". + +param.bundle-id-signing-prefix.name=Bundle Signing Prefix +param.bundle-id-signing-prefix.description=When signing the application bundle this value is prefixed to all components that need to be signed that don't have an existing CFBundleIdentifier. + +param.raw-executable-url.name=Launcher URL +param.raw-executable-url.description=Override the packager default launcher with a custom launcher. + +param.default-icon-icns=Default Icon +param.default-icon-icns.description=The Default Icon for when a user does not specify an icns file. + +param.runtime.name=JRE +param.runtime.description=The Java Runtime to co-bundle. The default value is the current JRE running the bundler. A value of null will cause no JRE to be co-bundled and the system JRE will be used to launch the application. + +param.images-root.name= +param.images-root.description= + +error.cannot-create-output-dir=Output directory {0} cannot be created. +error.cannot-write-to-output-dir=Output directory {0} is not writable. +error.invalid-cfbundle-version=Invalid CFBundleVersion - ''{0}'' +error.invalid-cfbundle-version.advice=Set a compatible 'appVersion' or set a 'mac.CFBundleVersion'. Valid versions are one to three integers separated by dots. +error.explicit-sign-no-cert=Signature explicitly requested but no signing certificate specified. +error.explicit-sign-no-cert.advice=Either specify a valid cert in 'mac.signing-key-developer-id-app' or unset 'signBundle' or set 'signBundle' to false. +error.non-existent-runtime=The file for the Runtime/JRE directory does not exist. +error.non-existent-runtime.advice=Point the runtime parameter to a directory that containes the JRE. +error.cannot-detect-runtime-in-directory=Cannot determine which JRE/JDK exists in the specified runtime directory. +error.cannot-detect-runtime-in-directory.advice=Point the runtime directory to one of the JDK/JRE root, the Contents/Home directory of that root, or the Contents/Home/jre directory of the JDK. +resource.app-info-plist=Application Info.plist +resource.runtime-info-plist=Java Runtime Info.plist + +message.config-save-location=Config files are saved to {0}. Use them to customize package. +message.bundle-name-too-long-warning={0} is set to ''{1}'', which is longer than 16 characters. For a better Mac experience consider shortening it. +message.no-mac-jre-support=Currently Macs require a JDK to package +message.creating-app-bundle=Creating app bundle\: {0} +message.null-classpath=Null app resources? +message.preparing-info-plist=Preparing Info.plist\: {0} +message.icon-not-icns= The specified icon "{0}" is not an ICNS file and will not be used. The default icon will be used in it's place. +message.version-string-too-many-components=Version sting may have between 1 and 3 numbers: 1, 1.2, 1.2.3. +message.version-string-first-number-not-zero=The first number in a CFBundleVersion cannot be zero or negative. +message.version-string-no-negative-numbers=Negative numbers are not allowed in version strings. +message.version-string-numbers-only=Version strings can consist of only numbers and up to two dots. +message.creating-association-with-null-extension=Creating association with null extension. + +message.using-default-resource=Using default package resource {0} (add {1} to the class path to customize) +message.using-custom-resource-from-file=Using custom package resource {0} (loaded from file {1}) +message.using-custom-resource-from-classpath=Using custom package resource {0} (loaded from {1}) +message.using-default-resource-from-classpath=Using default package resource {0} (add {1} to the class path to customize) +message.ignoring.symlink=Warning: codesign is skipping the symlink {0} \ No newline at end of file --- /dev/null 2017-08-15 12:38:51.000000000 -0700 +++ new/modules/jdk.packager/src/main/resources/jdk/packager/internal/legacy/builders/mac/MacAppImageBuilder_ja.properties 2017-08-15 12:38:51.000000000 -0700 @@ -0,0 +1,73 @@ +bundler.name=Mac\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30A4\u30E1\u30FC\u30B8 +bundler.description=\u30AA\u30D7\u30B7\u30E7\u30F3\u3067JRE\u304C\u30D0\u30F3\u30C9\u30EB\u3055\u308C\u3066\u3044\u308BMac\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u30FB\u30D9\u30FC\u30B9\u306E\u30A4\u30E1\u30FC\u30B8\u3002\u30A4\u30F3\u30B9\u30C8\u30FC\u30E9\u30FB\u30D0\u30F3\u30C9\u30EB\u306E\u30D9\u30FC\u30B9\u3068\u3057\u3066\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002 + +param.signing-key-developer-id-app.name=Apple Developer ID\u306E\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u7F72\u540D\u30AD\u30FC +param.signing-key-developer-id-app.description=Apple Developer ID\u306E\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u7F72\u540D\u30AD\u30FC\u306E\u30D5\u30EB\u30FB\u30CD\u30FC\u30E0\u3002 + +param.icon-icns.name=.icns\u30A2\u30A4\u30B3\u30F3 +param.icon-icns.description= ICNS\u5F62\u5F0F\u3067\u306E\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u30A2\u30A4\u30B3\u30F3\u3002 + +param.config-root.name= +param.config-root.description= + +param.configure-launcher-in-plist=Info.plist\u3067\u306E\u30E9\u30F3\u30C1\u30E3\u306E\u69CB\u6210 +param.configure-launcher-in-plist.description=Info.plist\u3067\u306E\u30E9\u30F3\u30C1\u30E3\u306E\u69CB\u6210\u306B\u306F\u30EC\u30AC\u30B7\u30FC\u30FB\u30E1\u30BD\u30C3\u30C9\u3092\u4F7F\u7528\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002 + +param.category-name=\u30AB\u30C6\u30B4\u30EA +param.category-name.description=Mac App Store\u306E\u30AB\u30C6\u30B4\u30EA\u3002\u30AD\u30FC\u306F\u30E6\u30FC\u30B6\u30FC\u306B\u8868\u793A\u3055\u308C\u308B\u6587\u5B57\u5217\u3067\u3001\u5024\u306F\u30AB\u30C6\u30B4\u30EA\u306EID\u3067\u3059\u3002 + +param.cfbundle-name.name=CFBundleName +param.cfbundle-name.description=\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u304C\u30E1\u30CB\u30E5\u30FC\u30FB\u30D0\u30FC\u306B\u8868\u793A\u3055\u308C\u308B\u969B\u306E\u540D\u524D\u3002\u3053\u308C\u306F\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u540D\u3068\u306F\u7570\u306A\u308B\u5834\u5408\u304C\u3042\u308A\u307E\u3059\u3002\u3053\u306E\u540D\u524D\u306F16\u6587\u5B57\u672A\u6E80\u3068\u3057\u3001\u30E1\u30CB\u30E5\u30FC\u30FB\u30D0\u30FC\u3068\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u60C5\u5831\u30A6\u30A3\u30F3\u30C9\u30A6\u3067\u306E\u8868\u793A\u306B\u9069\u3057\u305F\u3082\u306E\u306B\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002 + +param.cfbundle-identifier.name=CFBundleIdentifier +param.cfbundle-identifier.description=MacOSX(\u304A\u3088\u3073Mac App Store)\u306E\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u3092\u4E00\u610F\u306B\u8B58\u5225\u3059\u308B\u8B58\u5225\u5B50\u3002\u82F1\u6570\u5B57(A-Z\u3001a-z\u30010-9)\u3001\u30CF\u30A4\u30D5\u30F3(-)\u304A\u3088\u3073\u30D4\u30EA\u30AA\u30C9(.)\u306E\u307F\u3092\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002 + +param.cfbundle-version.name=CFBundleVersion +param.cfbundle-version.description=\u30B3\u30F3\u30D4\u30E5\u30FC\u30BF\u3067\u8AAD\u53D6\u308A\u53EF\u80FD\u306ACFBundle\u306E\u30D0\u30FC\u30B8\u30E7\u30F3\u3002\u6570\u5B57\u304A\u3088\u3073\u30BC\u30ED\u304B\u30892\u3064\u307E\u3067\u306E\u30C9\u30C3\u30C8\u306E\u307F\u3092\u542B\u3081\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u3059("1.8.1"\u3001"100"\u306A\u3069)\u3002 + +param.bundle-id-signing-prefix.name=\u30D0\u30F3\u30C9\u30EB\u7F72\u540D\u63A5\u982D\u8F9E +param.bundle-id-signing-prefix.description=\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30D0\u30F3\u30C9\u30EB\u306B\u7F72\u540D\u3059\u308B\u969B\u3001\u7F72\u540D\u3059\u308B\u5FC5\u8981\u306E\u3042\u308B\u3001\u65E2\u5B58\u306ECFBundleIdentifier\u3092\u6301\u305F\u306A\u3044\u3059\u3079\u3066\u306E\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8\u306B\u3053\u306E\u5024\u304C\u63A5\u982D\u8F9E\u3068\u3057\u3066\u4ED8\u3051\u3089\u308C\u307E\u3059\u3002 + +param.raw-executable-url.name=\u30E9\u30F3\u30C1\u30E3URL +param.raw-executable-url.description=\u30D1\u30C3\u30B1\u30FC\u30B8\u30E3\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30E9\u30F3\u30C1\u30E3\u3092\u30AB\u30B9\u30BF\u30E0\u30FB\u30E9\u30F3\u30C1\u30E3\u3067\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3057\u307E\u3059\u3002 + +param.default-icon-icns=\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30A2\u30A4\u30B3\u30F3 +param.default-icon-icns.description=\u30E6\u30FC\u30B6\u30FC\u304C\u30A2\u30A4\u30B3\u30F3\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u6307\u5B9A\u3057\u306A\u3044\u5834\u5408\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30A2\u30A4\u30B3\u30F3\u3002 + +param.runtime.name=JRE +param.runtime.description=\u30D0\u30F3\u30C9\u30EB\u3059\u308BJava\u30E9\u30F3\u30BF\u30A4\u30E0\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u5024\u306F\u3001\u30D0\u30F3\u30C9\u30E9\u3092\u5B9F\u884C\u3057\u3066\u3044\u308B\u73FE\u5728\u306EJRE\u3067\u3059\u3002\u5024\u304Cnull\u306E\u5834\u5408\u3001JRE\u306F\u30D0\u30F3\u30C9\u30EB\u3055\u308C\u305A\u3001\u30B7\u30B9\u30C6\u30E0\u306EJRE\u304C\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u8D77\u52D5\u306B\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002 + +param.images-root.name= +param.images-root.description= + +error.cannot-create-output-dir=\u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{0}\u3092\u4F5C\u6210\u3067\u304D\u307E\u305B\u3093\u3002 +error.cannot-write-to-output-dir=\u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{0}\u306F\u66F8\u8FBC\u307F\u4E0D\u53EF\u3067\u3059\u3002 +error.invalid-cfbundle-version=CFBundleVersion - ''{0}''\u304C\u7121\u52B9\u3067\u3059 +error.invalid-cfbundle-version.advice=\u4E92\u63DB\u6027\u306E\u3042\u308B'appVersion'\u3092\u8A2D\u5B9A\u3059\u308B\u304B\u3001'mac.CFBundleVersion'\u3092\u8A2D\u5B9A\u3057\u307E\u3059\u3002\u6709\u52B9\u306A\u30D0\u30FC\u30B8\u30E7\u30F3\u306F\u3001\u30C9\u30C3\u30C8\u3067\u533A\u5207\u3089\u308C\u305F1\u304B\u30893\u3064\u306E\u6574\u6570\u3067\u3059\u3002 +error.explicit-sign-no-cert=\u7F72\u540D\u304C\u660E\u793A\u7684\u306B\u8981\u6C42\u3055\u308C\u307E\u3057\u305F\u304C\u3001\u7F72\u540D\u8A3C\u660E\u66F8\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002 +error.explicit-sign-no-cert.advice=\u6709\u52B9\u306A\u8A3C\u660E\u66F8\u3092'mac.signing-key-developer-id-app'\u3067\u6307\u5B9A\u3059\u308B\u304B\u3001'signBundle'\u3092\u8A2D\u5B9A\u89E3\u9664\u3059\u308B\u304B\u3001\u307E\u305F\u306F'signBundle'\u3092false\u306B\u8A2D\u5B9A\u3057\u307E\u3059\u3002 +error.non-existent-runtime=\u30E9\u30F3\u30BF\u30A4\u30E0/JRE\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u30D5\u30A1\u30A4\u30EB\u304C\u5B58\u5728\u3057\u307E\u305B\u3093\u3002 +error.non-existent-runtime.advice=\u30E9\u30F3\u30BF\u30A4\u30E0\u30FB\u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u3001JRE\u3092\u542B\u3080\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002 +error.cannot-detect-runtime-in-directory=\u6307\u5B9A\u3057\u305F\u30E9\u30F3\u30BF\u30A4\u30E0\u30FB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u3069\u306EJRE/JDK\u304C\u5B58\u5728\u3059\u308B\u306E\u304B\u3092\u7279\u5B9A\u3067\u304D\u307E\u305B\u3093\u3002 +error.cannot-detect-runtime-in-directory.advice=\u30E9\u30A4\u30BF\u30A4\u30E0\u30FB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u3001JDK/JRE\u30EB\u30FC\u30C8\u3001\u305D\u306E\u30EB\u30FC\u30C8\u306E\u30B3\u30F3\u30C6\u30F3\u30C4/\u30DB\u30FC\u30E0\u30FB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3001\u307E\u305F\u306FJDK\u306E\u30B3\u30F3\u30C6\u30F3\u30C4/\u30DB\u30FC\u30E0/jre\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u3044\u305A\u308C\u304B\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002 +resource.app-info-plist=\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306EInfo.plist +resource.runtime-info-plist=Java\u30E9\u30F3\u30BF\u30A4\u30E0\u306EInfo.plist + +message.config-save-location=\u69CB\u6210\u30D5\u30A1\u30A4\u30EB\u304C{0}\u306B\u4FDD\u5B58\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u30AB\u30B9\u30BF\u30DE\u30A4\u30BA\u3059\u308B\u306B\u306F\u3053\u308C\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002 +message.bundle-name-too-long-warning={0}\u304C16\u6587\u5B57\u3092\u8D85\u3048\u308B''{1}''\u306B\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059\u3002Mac\u3067\u306E\u64CD\u4F5C\u6027\u3092\u3088\u308A\u826F\u304F\u3059\u308B\u305F\u3081\u306B\u77ED\u304F\u3059\u308B\u3053\u3068\u3092\u691C\u8A0E\u3057\u3066\u304F\u3060\u3055\u3044\u3002 +message.no-mac-jre-support=\u73FE\u5728\u3001Mac\u3067\u306FJDK\u3092\u30D1\u30C3\u30B1\u30FC\u30B8\u5316\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059 +message.creating-app-bundle=\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30D0\u30F3\u30C9\u30EB\u3092\u4F5C\u6210\u3057\u3066\u3044\u307E\u3059: {0} +message.null-classpath=Null\u306E\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30EA\u30BD\u30FC\u30B9\u3067\u3059\u304B\u3002 +message.preparing-info-plist=Info.plist\u3092\u6E96\u5099\u3057\u3066\u3044\u307E\u3059: {0} +message.icon-not-icns= \u6307\u5B9A\u3057\u305F\u30A2\u30A4\u30B3\u30F3"{0}"\u306FICNS\u30D5\u30A1\u30A4\u30EB\u3067\u306F\u306A\u304F\u3001\u4F7F\u7528\u3055\u308C\u307E\u305B\u3093\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30A2\u30A4\u30B3\u30F3\u304C\u305D\u306E\u4F4D\u7F6E\u306B\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002 +message.version-string-too-many-components=\u30D0\u30FC\u30B8\u30E7\u30F3\u6587\u5B57\u5217\u306B\u306F\u30011\u30011.2\u30011.2.3\u306A\u30691\u304B\u30893\u306E\u6570\u5B57\u3092\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002 +message.version-string-first-number-not-zero=CFBundleVersion\u306E\u6700\u521D\u306E\u6570\u5B57\u306F\u3001\u30BC\u30ED\u307E\u305F\u306F\u8CA0\u306E\u5024\u306B\u3067\u304D\u307E\u305B\u3093\u3002 +message.version-string-no-negative-numbers=\u30D0\u30FC\u30B8\u30E7\u30F3\u6587\u5B57\u5217\u306B\u8CA0\u306E\u6570\u306F\u8A31\u53EF\u3055\u308C\u307E\u305B\u3093\u3002 +message.version-string-numbers-only=\u30D0\u30FC\u30B8\u30E7\u30F3\u6587\u5B57\u5217\u306F\u3001\u6570\u5B57\u30682\u3064\u307E\u3067\u306E\u30C9\u30C3\u30C8\u3067\u306E\u307F\u69CB\u6210\u3067\u304D\u307E\u3059\u3002 +message.creating-association-with-null-extension=null\u62E1\u5F35\u5B50\u3068\u306E\u95A2\u9023\u4ED8\u3051\u3092\u4F5C\u6210\u3057\u3066\u3044\u307E\u3059\u3002 + +message.using-default-resource=\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30BD\u30FC\u30B9{0}\u306E\u4F7F\u7528({1}\u3092\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306B\u8FFD\u52A0\u3057\u3066\u30AB\u30B9\u30BF\u30DE\u30A4\u30BA) +message.using-custom-resource-from-file=\u30AB\u30B9\u30BF\u30E0\u30FB\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30BD\u30FC\u30B9{0}\u306E\u4F7F\u7528(\u30D5\u30A1\u30A4\u30EB{1}\u304B\u3089\u30ED\u30FC\u30C9\u6E08) +message.using-custom-resource-from-classpath=\u30AB\u30B9\u30BF\u30E0\u30FB\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30BD\u30FC\u30B9{0}\u306E\u4F7F\u7528({1}\u304B\u3089\u30ED\u30FC\u30C9\u6E08) +message.using-default-resource-from-classpath=\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30BD\u30FC\u30B9{0}\u306E\u4F7F\u7528({1}\u3092\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306B\u8FFD\u52A0\u3057\u3066\u30AB\u30B9\u30BF\u30DE\u30A4\u30BA) +message.ignoring.symlink=\u8B66\u544A: codesign\u304Csymlink {0}\u3092\u30B9\u30AD\u30C3\u30D7\u3057\u3066\u3044\u307E\u3059 --- /dev/null 2017-08-15 12:38:53.000000000 -0700 +++ new/modules/jdk.packager/src/main/resources/jdk/packager/internal/legacy/builders/mac/MacAppImageBuilder_zh_CN.properties 2017-08-15 12:38:52.000000000 -0700 @@ -0,0 +1,73 @@ +bundler.name=Mac \u5E94\u7528\u7A0B\u5E8F\u6620\u50CF +bundler.description=\u4E00\u4E2A\u57FA\u4E8E\u76EE\u5F55\u7684 mac \u5E94\u7528\u7A0B\u5E8F\u6620\u50CF, \u53EF\u4EE5\u9009\u62E9\u6027\u5730\u5E26\u6709\u5171\u540C\u6253\u5305\u7684 JRE\u3002\u7528\u4F5C\u5B89\u88C5\u7A0B\u5E8F\u6253\u5305\u7A0B\u5E8F\u7684\u57FA\u7840 + +param.signing-key-developer-id-app.name=Apple \u5F00\u53D1\u8005 ID \u5E94\u7528\u7A0B\u5E8F\u7B7E\u540D\u5BC6\u94A5 +param.signing-key-developer-id-app.description=Apple \u5F00\u53D1\u8005 ID \u5E94\u7528\u7A0B\u5E8F\u7B7E\u540D\u5BC6\u94A5\u7684\u5168\u540D\u3002 + +param.icon-icns.name=.icns \u56FE\u6807 +param.icon-icns.description= \u5E94\u7528\u7A0B\u5E8F\u7684\u56FE\u6807, \u91C7\u7528 ICNS \u683C\u5F0F\u3002 + +param.config-root.name= +param.config-root.description= + +param.configure-launcher-in-plist=\u5728 Info.plist \u4E2D\u914D\u7F6E\u542F\u52A8\u7A0B\u5E8F +param.configure-launcher-in-plist.description=\u662F\u5426\u5E94\u4F7F\u7528\u5728 Info.plist \u4E2D\u914D\u7F6E\u542F\u52A8\u7A0B\u5E8F\u7684\u65E7\u65B9\u6CD5\u3002 + +param.category-name=\u7C7B\u522B +param.category-name.description=Mac App Store \u7C7B\u522B\u3002\u8BF7\u6CE8\u610F, \u952E\u662F\u5411\u7528\u6237\u663E\u793A\u7684\u5B57\u7B26\u4E32, \u503C\u662F\u7C7B\u522B\u7684 ID\u3002 + +param.cfbundle-name.name=CFBundleName +param.cfbundle-name.description=\u5E94\u7528\u7A0B\u5E8F\u5728\u83DC\u5355\u680F\u4E2D\u7684\u663E\u793A\u540D\u79F0\u3002\u53EF\u4EE5\u4E0E\u5E94\u7528\u7A0B\u5E8F\u540D\u79F0\u4E0D\u540C\u3002\u6B64\u540D\u79F0\u7684\u957F\u5EA6\u5E94\u5C11\u4E8E 16 \u4E2A\u5B57\u7B26, \u5E76\u4E14\u5E94\u9002\u5408\u5728\u83DC\u5355\u680F\u548C\u5E94\u7528\u7A0B\u5E8F\u7684\u201C\u4FE1\u606F\u201D\u7A97\u53E3\u4E2D\u663E\u793A\u3002 + +param.cfbundle-identifier.name=CFBundleIdentifier +param.cfbundle-identifier.description=\u552F\u4E00\u6807\u8BC6 MacOSX \u5E94\u7528\u7A0B\u5E8F (\u5728 Mac App Store \u4E0A) \u7684\u6807\u8BC6\u7B26\u3002\u53EA\u80FD\u4F7F\u7528\u5B57\u6BCD\u6570\u5B57 (A-Z,a-z,0-9), \u8FDE\u5B57\u7B26 (-) \u548C\u53E5\u70B9 (.) \u5B57\u7B26\u3002 + +param.cfbundle-version.name=CFBundleVersion +param.cfbundle-version.description=CFBundle \u7684\u8BA1\u7B97\u673A\u53EF\u8BFB\u7248\u672C\u3002\u53EA\u80FD\u5305\u542B\u6570\u5B57\u4EE5\u53CA\u96F6\u5230\u4E24\u4E2A\u70B9, \u4F8B\u5982 "1.8.1" \u6216 "100"\u3002 + +param.bundle-id-signing-prefix.name=\u5305\u7B7E\u540D\u524D\u7F00 +param.bundle-id-signing-prefix.description=\u5BF9\u5E94\u7528\u7A0B\u5E8F\u5305\u8FDB\u884C\u7B7E\u540D\u65F6, \u6B64\u503C\u5C06\u4F5C\u4E3A\u524D\u7F00\u6DFB\u52A0\u5230\u9700\u8981\u7B7E\u540D\u4F46\u4E0D\u5177\u6709\u73B0\u6709 CFBundleIdentifier \u7684\u6240\u6709\u7EC4\u4EF6\u4E2D\u3002 + +param.raw-executable-url.name=\u542F\u52A8\u7A0B\u5E8F URL +param.raw-executable-url.description=\u4F7F\u7528\u5B9A\u5236\u542F\u52A8\u7A0B\u5E8F\u8986\u76D6\u6253\u5305\u7A0B\u5E8F\u9ED8\u8BA4\u542F\u52A8\u7A0B\u5E8F\u3002 + +param.default-icon-icns=\u9ED8\u8BA4\u56FE\u6807 +param.default-icon-icns.description=\u7528\u6237\u672A\u6307\u5B9A icns \u6587\u4EF6\u65F6\u4F7F\u7528\u7684\u9ED8\u8BA4\u56FE\u6807\u3002 + +param.runtime.name=JRE +param.runtime.description=\u8981\u5171\u540C\u6253\u5305\u7684 Java \u8FD0\u884C\u65F6\u3002\u9ED8\u8BA4\u503C\u4E3A\u8FD0\u884C\u6253\u5305\u7A0B\u5E8F\u7684\u5F53\u524D JRE\u3002\u503C\u4E3A\u7A7A\u503C\u5C06\u5BFC\u81F4\u4E0D\u4F1A\u5171\u540C\u6253\u5305\u4EFB\u4F55 JRE, \u5E76\u4E14\u5C06\u4F7F\u7528\u7CFB\u7EDF JRE \u6765\u542F\u52A8\u5E94\u7528\u7A0B\u5E8F\u3002 + +param.images-root.name= +param.images-root.description= + +error.cannot-create-output-dir=\u65E0\u6CD5\u521B\u5EFA\u8F93\u51FA\u76EE\u5F55 {0}\u3002 +error.cannot-write-to-output-dir=\u8F93\u51FA\u76EE\u5F55 {0} \u4E0D\u53EF\u5199\u3002 +error.invalid-cfbundle-version=\u65E0\u6548\u7684 CFBundleVersion - ''{0}'' +error.invalid-cfbundle-version.advice=\u8BBE\u7F6E\u517C\u5BB9\u7684 'appVersion' \u6216\u8005\u8BBE\u7F6E 'mac.CFBundleVersion'\u3002\u6709\u6548\u7248\u672C\u5305\u542B\u4E00\u5230\u4E09\u4E2A\u7528\u70B9\u5206\u9694\u7684\u6574\u6570\u3002 +error.explicit-sign-no-cert=\u5DF2\u660E\u786E\u8BF7\u6C42\u7B7E\u540D, \u4F46\u672A\u6307\u5B9A\u7B7E\u540D\u8BC1\u4E66\u3002 +error.explicit-sign-no-cert.advice=\u5728 'mac.signing-key-developer-id-app' \u4E2D\u6307\u5B9A\u6709\u6548\u7684\u8BC1\u4E66, \u6216\u8005\u53D6\u6D88\u8BBE\u7F6E 'signBundle', \u6216\u8005\u5C06 'signBundle' \u8BBE\u7F6E\u4E3A\u201C\u5047\u201D\u3002 +error.non-existent-runtime=\u8FD0\u884C\u65F6/JRE \u76EE\u5F55\u7684\u6587\u4EF6\u4E0D\u5B58\u5728\u3002 +error.non-existent-runtime.advice=\u5C06\u8FD0\u884C\u65F6\u53C2\u6570\u6307\u5411\u5305\u542B JRE \u7684\u76EE\u5F55\u3002 +error.cannot-detect-runtime-in-directory=\u65E0\u6CD5\u786E\u5B9A\u6307\u5B9A\u7684\u8FD0\u884C\u65F6\u76EE\u5F55\u4E2D\u5B58\u5728\u54EA\u4E2A\u7248\u672C\u7684 JRE/JDK\u3002 +error.cannot-detect-runtime-in-directory.advice=\u5C06\u8FD0\u884C\u65F6\u76EE\u5F55\u6307\u5411\u4EE5\u4E0B\u76EE\u5F55\u4E4B\u4E00: JDK/JRE \u6839\u76EE\u5F55, \u8BE5\u6839\u76EE\u5F55\u7684 Contents/Home \u76EE\u5F55\u6216 JDK \u7684 Contents/Home/jre \u76EE\u5F55\u3002 +resource.app-info-plist=\u5E94\u7528\u7A0B\u5E8F Info.plist +resource.runtime-info-plist=Java \u8FD0\u884C\u65F6 Info.plist + +message.config-save-location=\u914D\u7F6E\u6587\u4EF6\u5DF2\u4FDD\u5B58\u5230 {0}\u3002\u4F7F\u7528\u8FD9\u4E9B\u914D\u7F6E\u6587\u4EF6\u53EF\u5B9A\u5236\u7A0B\u5E8F\u5305\u3002 +message.bundle-name-too-long-warning={0}\u5DF2\u8BBE\u7F6E\u4E3A ''{1}'', \u5176\u957F\u5EA6\u8D85\u8FC7\u4E86 16 \u4E2A\u5B57\u7B26\u3002\u4E3A\u4E86\u83B7\u5F97\u66F4\u597D\u7684 Mac \u4F53\u9A8C, \u8BF7\u8003\u8651\u5C06\u5176\u7F29\u77ED\u3002 +message.no-mac-jre-support=Mac \u5F53\u524D\u9700\u8981 JDK \u4EE5\u4FBF\u6253\u5305 +message.creating-app-bundle=\u6B63\u5728\u521B\u5EFA\u5E94\u7528\u7A0B\u5E8F\u5305: {0} +message.null-classpath=\u662F\u5426\u4E3A\u7A7A\u5E94\u7528\u7A0B\u5E8F\u8D44\u6E90? +message.preparing-info-plist=\u6B63\u5728\u51C6\u5907 Info.plist: {0} +message.icon-not-icns= \u6307\u5B9A\u7684\u56FE\u6807 "{0}" \u4E0D\u662F ICNS \u6587\u4EF6, \u4E0D\u4F1A\u4F7F\u7528\u3002\u5C06\u4F7F\u7528\u9ED8\u8BA4\u56FE\u6807\u4EE3\u66FF\u3002 +message.version-string-too-many-components=\u7248\u672C\u5B57\u7B26\u4E32\u53EF\u4EE5\u5305\u542B 1 \u5230 3 \u4E2A\u6570\u5B57: 1, 1.2, 1.2.3\u3002 +message.version-string-first-number-not-zero=CFBundleVersion \u4E2D\u7684\u7B2C\u4E00\u4E2A\u6570\u5B57\u4E0D\u80FD\u4E3A\u96F6\u6216\u8D1F\u6570\u3002 +message.version-string-no-negative-numbers=\u7248\u672C\u5B57\u7B26\u4E32\u4E2D\u4E0D\u5141\u8BB8\u4F7F\u7528\u8D1F\u6570\u3002 +message.version-string-numbers-only=\u7248\u672C\u5B57\u7B26\u4E32\u53EA\u80FD\u5305\u542B\u6570\u5B57\u548C\u6700\u591A\u4E24\u4E2A\u70B9\u3002 +message.creating-association-with-null-extension=\u6B63\u5728\u4F7F\u7528\u7A7A\u6269\u5C55\u540D\u521B\u5EFA\u5173\u8054\u3002 + +message.using-default-resource=\u4F7F\u7528\u9ED8\u8BA4\u7A0B\u5E8F\u5305\u8D44\u6E90 {0} (\u5C06 {1} \u6DFB\u52A0\u5230\u7C7B\u8DEF\u5F84\u4EE5\u5B9A\u5236) +message.using-custom-resource-from-file=\u4F7F\u7528\u5B9A\u5236\u7A0B\u5E8F\u5305\u8D44\u6E90 {0} (\u4ECE\u6587\u4EF6 {1} \u52A0\u8F7D) +message.using-custom-resource-from-classpath=\u4F7F\u7528\u5B9A\u5236\u7A0B\u5E8F\u5305\u8D44\u6E90 {0} (\u4ECE {1} \u52A0\u8F7D) +message.using-default-resource-from-classpath=\u4F7F\u7528\u9ED8\u8BA4\u7A0B\u5E8F\u5305\u8D44\u6E90 {0} (\u5C06 {1} \u6DFB\u52A0\u5230\u7C7B\u8DEF\u5F84\u4EE5\u5B9A\u5236) +message.ignoring.symlink=\u8B66\u544A: codesign \u6B63\u5728\u8DF3\u8FC7\u7B26\u53F7\u94FE\u63A5 {0} --- /dev/null 2017-08-15 12:38:54.000000000 -0700 +++ new/modules/jdk.packager/src/main/resources/jdk/packager/internal/legacy/builders/windows/WindowsAppImageBuilder.properties 2017-08-15 12:38:54.000000000 -0700 @@ -0,0 +1,16 @@ +param.rebrand-executable.name = Rebrand Launcher +param.rebrand-executable.description = Update the launcher with the application icon and update ownership information. + +param.icon-ico.name=.ico Icon +param.icon-ico.description=Icon for the application, in ICO format. + +param.config-root.name= +param.config-root.description= + +error.cannot-create-output-dir=Output directory {0} cannot be created. +error.cannot-write-to-output-dir=Output directory {0} is not writable. + +message.config-save-location=Config files are saved to {0}. Use them to customize package. +message.potential.windows.defender.issue=Warning: Windows Defender may prevent the Java Packager from functioning. If there is an issue, it can be addressed by either disabling realtime monitoring, or adding an exclusion for the directory "{0}". + +resource.executable-properties-template=Template for creating executable properties file. \ No newline at end of file --- /dev/null 2017-08-15 12:38:55.000000000 -0700 +++ new/modules/jdk.packager/src/main/resources/jdk/packager/internal/legacy/builders/windows/WindowsAppImageBuilder_ja.properties 2017-08-15 12:38:55.000000000 -0700 @@ -0,0 +1,16 @@ +param.rebrand-executable.name = \u30E9\u30F3\u30C1\u30E3\u306E\u30EA\u30D6\u30E9\u30F3\u30C9 +param.rebrand-executable.description = \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30A2\u30A4\u30B3\u30F3\u3092\u542B\u3080\u30E9\u30F3\u30C1\u30E3\u304A\u3088\u3073\u6240\u6709\u8005\u60C5\u5831\u3092\u66F4\u65B0\u3057\u307E\u3059\u3002 + +param.icon-ico.name=.ico\u30A2\u30A4\u30B3\u30F3 +param.icon-ico.description=ICO\u5F62\u5F0F\u3067\u306E\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u30A2\u30A4\u30B3\u30F3\u3002 + +param.config-root.name= +param.config-root.description= + +error.cannot-create-output-dir=\u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{0}\u3092\u4F5C\u6210\u3067\u304D\u307E\u305B\u3093\u3002 +error.cannot-write-to-output-dir=\u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{0}\u306F\u66F8\u8FBC\u307F\u4E0D\u53EF\u3067\u3059\u3002 + +message.config-save-location=\u69CB\u6210\u30D5\u30A1\u30A4\u30EB\u304C{0}\u306B\u4FDD\u5B58\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u30AB\u30B9\u30BF\u30DE\u30A4\u30BA\u3059\u308B\u306B\u306F\u3053\u308C\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002 +message.potential.windows.defender.issue=\u8B66\u544A: Windows Defender\u304C\u539F\u56E0\u3067Java\u30D1\u30C3\u30B1\u30FC\u30B8\u30E3\u304C\u6A5F\u80FD\u3057\u306A\u3044\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002\u554F\u984C\u304C\u767A\u751F\u3057\u305F\u5834\u5408\u306F\u3001\u30EA\u30A2\u30EB\u30BF\u30A4\u30E0\u30FB\u30E2\u30CB\u30BF\u30EA\u30F3\u30B0\u3092\u7121\u52B9\u306B\u3059\u308B\u304B\u3001\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA"{0}"\u306E\u9664\u5916\u3092\u8FFD\u52A0\u3059\u308B\u3053\u3068\u306B\u3088\u308A\u3001\u554F\u984C\u306B\u5BFE\u51E6\u3067\u304D\u307E\u3059\u3002 + +resource.executable-properties-template=\u5B9F\u884C\u53EF\u80FD\u306A\u30D7\u30ED\u30D1\u30C6\u30A3\u30FB\u30D5\u30A1\u30A4\u30EB\u4F5C\u6210\u7528\u306E\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u3002 --- /dev/null 2017-08-15 12:38:56.000000000 -0700 +++ new/modules/jdk.packager/src/main/resources/jdk/packager/internal/legacy/builders/windows/WindowsAppImageBuilder_zh_CN.properties 2017-08-15 12:38:56.000000000 -0700 @@ -0,0 +1,16 @@ +param.rebrand-executable.name = \u66F4\u6539\u542F\u52A8\u7A0B\u5E8F\u54C1\u724C +param.rebrand-executable.description = \u4F7F\u7528\u5E94\u7528\u7A0B\u5E8F\u56FE\u6807\u66F4\u65B0\u542F\u52A8\u7A0B\u5E8F\u5E76\u66F4\u65B0\u6240\u6709\u6743\u4FE1\u606F\u3002 + +param.icon-ico.name=.ico \u56FE\u6807 +param.icon-ico.description=\u5E94\u7528\u7A0B\u5E8F\u7684\u56FE\u6807, \u91C7\u7528 ICO \u683C\u5F0F\u3002 + +param.config-root.name= +param.config-root.description= + +error.cannot-create-output-dir=\u65E0\u6CD5\u521B\u5EFA\u8F93\u51FA\u76EE\u5F55 {0}\u3002 +error.cannot-write-to-output-dir=\u8F93\u51FA\u76EE\u5F55 {0} \u4E0D\u53EF\u5199\u3002 + +message.config-save-location=\u914D\u7F6E\u6587\u4EF6\u5DF2\u4FDD\u5B58\u5230 {0}\u3002\u4F7F\u7528\u8FD9\u4E9B\u914D\u7F6E\u6587\u4EF6\u53EF\u5B9A\u5236\u7A0B\u5E8F\u5305\u3002 +message.potential.windows.defender.issue=\u8B66\u544A: Windows Defender \u53EF\u80FD\u4F1A\u963B\u6B62 Java \u6253\u5305\u7A0B\u5E8F\u6B63\u5E38\u5DE5\u4F5C\u3002\u5982\u679C\u5B58\u5728\u95EE\u9898, \u53EF\u4EE5\u901A\u8FC7\u7981\u7528\u5B9E\u65F6\u76D1\u89C6\u6216\u8005\u4E3A\u76EE\u5F55 "{0}" \u6DFB\u52A0\u6392\u9664\u9879\u8FDB\u884C\u89E3\u51B3\u3002 + +resource.executable-properties-template=\u7528\u4E8E\u521B\u5EFA\u53EF\u6267\u884C\u5C5E\u6027\u6587\u4EF6\u7684\u6A21\u677F\u3002 --- old/modules/jdk.packager/src/main/java/jdk/packager/builders/AbstractAppImageBuilder.java 2017-08-15 12:38:58.000000000 -0700 +++ /dev/null 2017-08-15 12:38:58.000000000 -0700 @@ -1,324 +0,0 @@ -/* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.packager.builders; - - -import jdk.packager.internal.JLinkBundlerHelper; -import com.oracle.tools.packager.RelativeFileSet; - -import com.oracle.tools.packager.Log; -import com.oracle.tools.packager.StandardBundlerParam; -import jdk.packager.internal.Module; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.text.MessageFormat; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.ResourceBundle; -import java.util.Set; - -import static com.oracle.tools.packager.StandardBundlerParam.*; -import static com.oracle.tools.packager.StandardBundlerParam.ARGUMENTS; -import static com.oracle.tools.packager.StandardBundlerParam.USER_JVM_OPTIONS; -import java.util.ArrayList; - - -public abstract class AbstractAppImageBuilder { - - private static final ResourceBundle I18N = - ResourceBundle.getBundle(AbstractAppImageBuilder.class.getName()); - - //do not use file separator - - // we use it for classpath lookup and there / are not platform specific - public final static String BUNDLER_PREFIX = "package/"; - - private Map properties; - private Path root; - protected List excludeFileList = new ArrayList<>(); - - public AbstractAppImageBuilder(Map properties, Path root) throws IOException { - this.properties = properties; - this.root = root; - excludeFileList.add(".*\\.diz"); - } - - public abstract InputStream getResourceAsStream(String name); - public abstract void prepareApplicationFiles() throws IOException; - - public Map getProperties() { - return this.properties; - } - - public Path getRoot() { - return this.root; - } - - public String getExcludeFileList() { - String result = ""; - - for (String item : excludeFileList) { - if (!result.isEmpty()) { - result += ","; - } - - result += item; - } - - return result; - } - - protected InputStream locateResource(String publicName, String category, - String defaultName, File customFile, - boolean verbose, File publicRoot) throws IOException { - InputStream is = null; - boolean customFromClasspath = false; - boolean customFromFile = false; - if (publicName != null) { - if (publicRoot != null) { - File publicResource = new File(publicRoot, publicName); - if (publicResource.exists() && publicResource.isFile()) { - is = new FileInputStream(publicResource); - } - } else { - is = getResourceAsStream(publicName); - } - customFromClasspath = (is != null); - } - if (is == null && customFile != null) { - is = new FileInputStream(customFile); - customFromFile = (is != null); - } - if (is == null && defaultName != null) { - is = getResourceAsStream(defaultName); - } - String msg = null; - if (customFromClasspath) { - msg = MessageFormat.format(I18N.getString("message.using-custom-resource-from-classpath"), category == null ? "" : "[" + category + "] ", publicName); - } else if (customFromFile) { - msg = MessageFormat.format(I18N.getString("message.using-custom-resource-from-file"), category == null ? "" : "[" + category + "] ", customFile.getAbsoluteFile()); - } else if (is != null) { - msg = MessageFormat.format(I18N.getString("message.using-default-resource-from-classpath"), category == null ? "" : "[" + category + "] ", publicName); - } else { - msg = MessageFormat.format(I18N.getString("message.using-default-resource"), category == null ? "" : "[" + category + "] ", publicName); - } - if (verbose) { - Log.info(msg); - } - return is; - } - - - protected String preprocessTextResource(String publicName, String category, - String defaultName, Map pairs, - boolean verbose, File publicRoot) throws IOException { - InputStream inp = locateResource(publicName, category, defaultName, null, verbose, publicRoot); - if (inp == null) { - throw new RuntimeException("Module corrupt? No "+defaultName+" resource!"); - } - - try (InputStream is = inp) { - //read fully into memory - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024]; - int length; - while ((length = is.read(buffer)) != -1) { - baos.write(buffer, 0, length); - } - - //substitute - String result = new String(baos.toByteArray()); - for (Map.Entry e : pairs.entrySet()) { - if (e.getValue() != null) { - result = result.replace(e.getKey(), e.getValue()); - } - } - return result; - } - } - - public void writeCfgFile(Map params, File cfgFileName, String runtimeLocation) throws IOException { - cfgFileName.delete(); - - boolean appCDEnabled = UNLOCK_COMMERCIAL_FEATURES.fetchFrom(params) && ENABLE_APP_CDS.fetchFrom(params); - String appCDSCacheMode = APP_CDS_CACHE_MODE.fetchFrom(params); - File mainJar = JLinkBundlerHelper.getMainJar(params); - Module.ModuleType mainJarType = Module.ModuleType.Unknown; - - if (mainJar != null) { - mainJarType = new Module(mainJar).getModuleType(); - } - - String mainModule = StandardBundlerParam.MODULE.fetchFrom(params); - - PrintStream out = new PrintStream(cfgFileName); - - out.println("[Application]"); - out.println("app.name=" + APP_NAME.fetchFrom(params)); - out.println("app.version=" + VERSION.fetchFrom(params)); - out.println("app.preferences.id=" + PREFERENCES_ID.fetchFrom(params)); - out.println("app.runtime=" + runtimeLocation); - out.println("app.identifier=" + IDENTIFIER.fetchFrom(params)); - out.println("app.classpath=" + String.join(File.pathSeparator, CLASSPATH.fetchFrom(params).split("[ :;]"))); - out.println("app.application.instance=" + (SINGLETON.fetchFrom(params) ? "single" : "multiple")); - - // The main app is required to be a jar, modular or unnamed. - if (mainJarType == Module.ModuleType.Unknown || mainJarType == Module.ModuleType.ModularJar) { - if (mainModule != null) { - out.println("app.mainmodule=" + mainModule); // TODO get app class from main module mainifest. - } - } - else { - String mainClass = JLinkBundlerHelper.getMainClass(params); - - if (mainJar != null && mainClass != null) { - // If the app is contained in an unnamed jar then launch it the - // legacy way and the main class string must be of the format com/foo/Main - out.println("app.mainclass=" + mainClass.replaceAll("\\.", "/")); - out.println("app.mainjar=" + mainJar.toPath().getFileName().toString()); - } - } - - String version = JLinkBundlerHelper.getJDKVersion(params); - - if (!version.isEmpty()) { - out.println("app.java.version=" + version); - } - - out.println("packager.java.version=" + System.getProperty("java.version")); - - Integer port = JLinkBundlerHelper.DEBUG.fetchFrom(params); - - if (port != null) { - out.println("app.debug=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=localhost:" + port); - } - - if (appCDEnabled) { - out.println("app.appcds.cache=" + appCDSCacheMode.split("\\+")[0]); - } - - - out.println(); - out.println("[JVMOptions]"); - List jvmargs = JVM_OPTIONS.fetchFrom(params); - for (String arg : jvmargs) { - out.println(arg); - } - Map jvmProps = JVM_PROPERTIES.fetchFrom(params); - for (Map.Entry property : jvmProps.entrySet()) { - out.println("-D" + property.getKey() + "=" + property.getValue()); - } - String preloader = PRELOADER_CLASS.fetchFrom(params); - if (preloader != null) { - out.println("-Djavafx.preloader="+preloader); - } - - - out.println(); - out.println("[JVMUserOptions]"); - Map overridableJVMOptions = USER_JVM_OPTIONS.fetchFrom(params); - for (Map.Entry arg: overridableJVMOptions.entrySet()) { - if (arg.getKey() == null || arg.getValue() == null) { - Log.info(I18N.getString("message.jvm-user-arg-is-null")); - } else { - out.println(arg.getKey().replaceAll("([\\=])", "\\\\$1") + "=" + arg.getValue()); - } - } - - if (appCDEnabled) { - prepareAppCDS(params, out); - } - - out.println(); - out.println("[ArgOptions]"); - List args = ARGUMENTS.fetchFrom(params); - for (String arg : args) { - if (arg.endsWith("=") && (arg.indexOf("=") == arg.lastIndexOf("="))) { - out.print(arg.substring(0, arg.length() - 1)); - out.println("\\="); - } else { - out.println(arg); - } - } - - - out.close(); - } - - protected abstract String getCacheLocation(Map params); - - void prepareAppCDS(Map params, PrintStream out) throws IOException { - File tempDir = Files.createTempDirectory("javapackager").toFile(); - tempDir.deleteOnExit(); - File classList = new File(tempDir, APP_FS_NAME.fetchFrom(params) + ".classlist"); - - try (FileOutputStream fos = new FileOutputStream(classList); - PrintStream ps = new PrintStream(fos)) { - for (String className : APP_CDS_CLASS_ROOTS.fetchFrom(params)) { - String slashyName = className.replace(".", "/"); - ps.println(slashyName); - } - } - APP_RESOURCES_LIST.fetchFrom(params).add(new RelativeFileSet(classList.getParentFile(), Arrays.asList(classList))); - - out.println(); - out.println("[AppCDSJVMOptions]"); - out.println("-XX:+UnlockCommercialFeatures"); - out.print("-XX:SharedArchiveFile="); - out.print(getCacheLocation(params)); - out.print(APP_FS_NAME.fetchFrom(params)); - out.println(".jpa"); - out.println("-Xshare:auto"); - out.println("-XX:+UseAppCDS"); - if (Log.isDebug()) { - out.println("-verbose:class"); - out.println("-XX:+TraceClassPaths"); - out.println("-XX:+UnlockDiagnosticVMOptions"); - } - out.println(""); - - out.println("[AppCDSGenerateCacheJVMOptions]"); - out.println("-XX:+UnlockCommercialFeatures"); - out.println("-Xshare:dump"); - out.println("-XX:+UseAppCDS"); - out.print("-XX:SharedArchiveFile="); - out.print(getCacheLocation(params)); - out.print(APP_FS_NAME.fetchFrom(params)); - out.println(".jpa"); - out.println("-XX:SharedClassListFile=$PACKAGEDIR/" + APP_FS_NAME.fetchFrom(params) + ".classlist"); - if (Log.isDebug()) { - out.println("-XX:+UnlockDiagnosticVMOptions"); - } - } -} --- old/modules/jdk.packager/src/main/java/jdk/packager/builders/linux/LinuxAppImageBuilder.java 2017-08-15 12:38:58.000000000 -0700 +++ /dev/null 2017-08-15 12:38:59.000000000 -0700 @@ -1,241 +0,0 @@ -/* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.packager.builders.linux; - - -import com.oracle.tools.packager.BundlerParamInfo; -import com.oracle.tools.packager.IOUtils; -import com.oracle.tools.packager.Log; -import com.oracle.tools.packager.RelativeFileSet; -import com.oracle.tools.packager.StandardBundlerParam; -import com.oracle.tools.packager.linux.LinuxResources; -import jdk.packager.builders.AbstractAppImageBuilder; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.UncheckedIOException; -import java.io.Writer; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.attribute.PosixFilePermission; -import java.text.MessageFormat; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.ResourceBundle; -import java.util.Set; - -import static com.oracle.tools.packager.StandardBundlerParam.*; - - -public class LinuxAppImageBuilder extends AbstractAppImageBuilder { - - private static final ResourceBundle I18N = - ResourceBundle.getBundle(LinuxAppImageBuilder.class.getName()); - - protected static final String LINUX_BUNDLER_PREFIX = - BUNDLER_PREFIX + "linux" + File.separator; - private static final String EXECUTABLE_NAME = "JavaAppLauncher"; - private static final String LIBRARY_NAME = "libpackager.so"; - - private final Path root; - private final Path appDir; - private final Path runtimeDir; - private final Path resourcesDir; - private final Path mdir; - - private final Map params; - - public static final BundlerParamInfo ICON_PNG = new StandardBundlerParam<>( - I18N.getString("param.icon-png.name"), - I18N.getString("param.icon-png.description"), - "icon.png", - File.class, - params -> { - File f = ICON.fetchFrom(params); - if (f != null && !f.getName().toLowerCase().endsWith(".png")) { - Log.info(MessageFormat.format(I18N.getString("message.icon-not-png"), f)); - return null; - } - return f; - }, - (s, p) -> new File(s)); - - public LinuxAppImageBuilder(Map config, Path imageOutDir) throws IOException { - super(config, imageOutDir.resolve(APP_NAME.fetchFrom(config) + "/runtime")); - - Objects.requireNonNull(imageOutDir); - - this.root = imageOutDir.resolve(APP_NAME.fetchFrom(config)); - this.appDir = root.resolve("app"); - this.runtimeDir = root.resolve("runtime"); - this.resourcesDir = root.resolve("resources"); - this.mdir = runtimeDir.resolve("lib"); - this.params = new HashMap(); - config.entrySet().stream().forEach(e -> params.put(e.getKey().toString(), e.getValue())); - Files.createDirectories(appDir); - Files.createDirectories(runtimeDir); - Files.createDirectories(resourcesDir); - } - - private Path destFile(String dir, String filename) { - return runtimeDir.resolve(dir).resolve(filename); - } - - private void writeEntry(InputStream in, Path dstFile) throws IOException { - Files.createDirectories(dstFile.getParent()); - Files.copy(in, dstFile); - } - - private void writeSymEntry(Path dstFile, Path target) throws IOException { - Files.createDirectories(dstFile.getParent()); - Files.createLink(dstFile, target); - } - - /** - * chmod ugo+x file - */ - private void setExecutable(Path file) { - try { - Set perms = Files.getPosixFilePermissions(file); - perms.add(PosixFilePermission.OWNER_EXECUTE); - perms.add(PosixFilePermission.GROUP_EXECUTE); - perms.add(PosixFilePermission.OTHERS_EXECUTE); - Files.setPosixFilePermissions(file, perms); - } catch (IOException ioe) { - throw new UncheckedIOException(ioe); - } - } - - private static void createUtf8File(File file, String content) throws IOException { - try (OutputStream fout = new FileOutputStream(file); - Writer output = new OutputStreamWriter(fout, "UTF-8")) { - output.write(content); - } - } - - - //it is static for the sake of sharing with "installer" bundlers - // that may skip calls to validate/bundle in this class! - public static File getRootDir(File outDir, Map p) { - return new File(outDir, APP_FS_NAME.fetchFrom(p)); - } - - public static String getLauncherName(Map p) { - return APP_FS_NAME.fetchFrom(p); - } - - public static String getLauncherCfgName(Map p) { - return "app/" + APP_FS_NAME.fetchFrom(p) + ".cfg"; - } - - @Override - public InputStream getResourceAsStream(String name) { - return LinuxResources.class.getResourceAsStream(name); - } - - @Override - public void prepareApplicationFiles() throws IOException { - Map originalParams = new HashMap<>(params); - - try { - // create the primary launcher - createLauncherForEntryPoint(params, root); - - // Copy library to the launcher folder - writeEntry(LinuxResources.class.getResourceAsStream(LIBRARY_NAME), root.resolve(LIBRARY_NAME)); - - // create the secondary launchers, if any - List> entryPoints = StandardBundlerParam.SECONDARY_LAUNCHERS.fetchFrom(params); - for (Map entryPoint : entryPoints) { - Map tmp = new HashMap<>(originalParams); - tmp.putAll(entryPoint); - // remove name.fs that was calculated for main launcher. - // otherwise, wrong launcher name will be selected. - tmp.remove(APP_FS_NAME.getID()); - createLauncherForEntryPoint(tmp, root); - } - - // Copy class path entries to Java folder - copyApplication(); - - // Copy icon to Resources folder - copyIcon(); - - } catch (IOException ex) { - Log.info("Exception: " + ex); - Log.debug(ex); - } - } - - private void createLauncherForEntryPoint(Map p, Path rootDir) throws IOException { - // Copy executable to Linux folder - Path executableFile = root.resolve(getLauncherName(p)); - - writeEntry(LinuxResources.class.getResourceAsStream(EXECUTABLE_NAME), executableFile); - - executableFile.toFile().setExecutable(true, false); - executableFile.toFile().setWritable(true, true); - - writeCfgFile(p, root.resolve(getLauncherCfgName(p)).toFile(), "$APPDIR/runtime"); - } - - private void copyIcon() throws IOException { - File icon = ICON_PNG.fetchFrom(params); - File iconTarget = new File(resourcesDir.toFile(), APP_FS_NAME.fetchFrom(params) + ".png"); - IOUtils.copyFile(icon, iconTarget); - } - - private void copyApplication() throws IOException { - List appResourcesList = APP_RESOURCES_LIST.fetchFrom(params); - if (appResourcesList == null) { - throw new RuntimeException("Null app resources?"); - } - for (RelativeFileSet appResources : appResourcesList) { - if (appResources == null) { - throw new RuntimeException("Null app resources?"); - } - File srcdir = appResources.getBaseDirectory(); - for (String fname : appResources.getIncludedFiles()) { - writeEntry( - new FileInputStream(new File(srcdir, fname)), - new File(appDir.toFile(), fname).toPath() - ); - } - } - } - - @Override - protected String getCacheLocation(Map params) { - return "$CACHEDIR/"; - } - -} --- old/modules/jdk.packager/src/main/java/jdk/packager/builders/mac/MacAppImageBuilder.java 2017-08-15 12:38:59.000000000 -0700 +++ /dev/null 2017-08-15 12:38:59.000000000 -0700 @@ -1,874 +0,0 @@ -/* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.packager.builders.mac; - - -import com.oracle.tools.packager.BundlerParamInfo; -import com.oracle.tools.packager.IOUtils; -import com.oracle.tools.packager.Log; -import com.oracle.tools.packager.RelativeFileSet; -import com.oracle.tools.packager.StandardBundlerParam; -import com.oracle.tools.packager.mac.MacResources; - -import jdk.packager.builders.AbstractAppImageBuilder; -import jdk.packager.internal.JLinkBundlerHelper; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.UncheckedIOException; -import java.io.Writer; -import java.math.BigInteger; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.attribute.PosixFilePermission; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.ResourceBundle; -import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; - -import static com.oracle.tools.packager.StandardBundlerParam.*; -import static com.oracle.tools.packager.mac.MacBaseInstallerBundler.*; -import static com.oracle.tools.packager.mac.MacAppBundler.*; - - -public class MacAppImageBuilder extends AbstractAppImageBuilder { - - private static final ResourceBundle I18N = - ResourceBundle.getBundle(MacAppImageBuilder.class.getName()); - - private static final String EXECUTABLE_NAME = "JavaAppLauncher"; - private static final String LIBRARY_NAME = "libpackager.dylib"; - private static final String TEMPLATE_BUNDLE_ICON = "GenericApp.icns"; - private static final String OS_TYPE_CODE = "APPL"; - private static final String TEMPLATE_INFO_PLIST_LITE = "Info-lite.plist.template"; - private static final String TEMPLATE_RUNTIME_INFO_PLIST = "Runtime-Info.plist.template"; - - private final Path root; - private final Path contentsDir; - private final Path javaDir; - private final Path resourcesDir; - private final Path macOSDir; - private final Path runtimeDir; - private final Path runtimeRoot; - private final Path mdir; - - private final Map params; - - private static Map getMacCategories() { - Map map = new HashMap<>(); - map.put("Business", "public.app-category.business"); - map.put("Developer Tools", "public.app-category.developer-tools"); - map.put("Education", "public.app-category.education"); - map.put("Entertainment", "public.app-category.entertainment"); - map.put("Finance", "public.app-category.finance"); - map.put("Games", "public.app-category.games"); - map.put("Graphics & Design", "public.app-category.graphics-design"); - map.put("Healthcare & Fitness", "public.app-category.healthcare-fitness"); - map.put("Lifestyle", "public.app-category.lifestyle"); - map.put("Medical", "public.app-category.medical"); - map.put("Music", "public.app-category.music"); - map.put("News", "public.app-category.news"); - map.put("Photography", "public.app-category.photography"); - map.put("Productivity", "public.app-category.productivity"); - map.put("Reference", "public.app-category.reference"); - map.put("Social Networking", "public.app-category.social-networking"); - map.put("Sports", "public.app-category.sports"); - map.put("Travel", "public.app-category.travel"); - map.put("Utilities", "public.app-category.utilities"); - map.put("Video", "public.app-category.video"); - map.put("Weather", "public.app-category.weather"); - - map.put("Action Games", "public.app-category.action-games"); - map.put("Adventure Games", "public.app-category.adventure-games"); - map.put("Arcade Games", "public.app-category.arcade-games"); - map.put("Board Games", "public.app-category.board-games"); - map.put("Card Games", "public.app-category.card-games"); - map.put("Casino Games", "public.app-category.casino-games"); - map.put("Dice Games", "public.app-category.dice-games"); - map.put("Educational Games", "public.app-category.educational-games"); - map.put("Family Games", "public.app-category.family-games"); - map.put("Kids Games", "public.app-category.kids-games"); - map.put("Music Games", "public.app-category.music-games"); - map.put("Puzzle Games", "public.app-category.puzzle-games"); - map.put("Racing Games", "public.app-category.racing-games"); - map.put("Role Playing Games", "public.app-category.role-playing-games"); - map.put("Simulation Games", "public.app-category.simulation-games"); - map.put("Sports Games", "public.app-category.sports-games"); - map.put("Strategy Games", "public.app-category.strategy-games"); - map.put("Trivia Games", "public.app-category.trivia-games"); - map.put("Word Games", "public.app-category.word-games"); - - return map; - } - - public static final BundlerParamInfo MAC_CONFIGURE_LAUNCHER_IN_PLIST = - new StandardBundlerParam<>( - I18N.getString("param.configure-launcher-in-plist"), - I18N.getString("param.configure-launcher-in-plist.description"), - "mac.configure-launcher-in-plist", - Boolean.class, - params -> Boolean.FALSE, - (s, p) -> Boolean.valueOf(s)); - - public static final BundlerParamInfo MAC_CATEGORY = - new StandardBundlerParam<>( - I18N.getString("param.category-name"), - I18N.getString("param.category-name.description"), - "mac.category", - String.class, - CATEGORY::fetchFrom, - (s, p) -> s - ); - - public static final BundlerParamInfo MAC_CF_BUNDLE_NAME = - new StandardBundlerParam<>( - I18N.getString("param.cfbundle-name.name"), - I18N.getString("param.cfbundle-name.description"), - "mac.CFBundleName", - String.class, - params -> null, - (s, p) -> s); - - public static final BundlerParamInfo MAC_CF_BUNDLE_IDENTIFIER = - new StandardBundlerParam<>( - I18N.getString("param.cfbundle-identifier.name"), - I18N.getString("param.cfbundle-identifier.description"), - "mac.CFBundleIdentifier", - String.class, - IDENTIFIER::fetchFrom, - (s, p) -> s); - - public static final BundlerParamInfo MAC_CF_BUNDLE_VERSION = - new StandardBundlerParam<>( - I18N.getString("param.cfbundle-version.name"), - I18N.getString("param.cfbundle-version.description"), - "mac.CFBundleVersion", - String.class, - p -> { - String s = VERSION.fetchFrom(p); - if (validCFBundleVersion(s)) { - return s; - } else { - return "100"; - } - }, - (s, p) -> s); - - public static final BundlerParamInfo CONFIG_ROOT = new StandardBundlerParam<>( - I18N.getString("param.config-root.name"), - I18N.getString("param.config-root.description"), - "configRoot", - File.class, - params -> { - File configRoot = new File(BUILD_ROOT.fetchFrom(params), "macosx"); - configRoot.mkdirs(); - return configRoot; - }, - (s, p) -> new File(s)); - - public static final BundlerParamInfo DEFAULT_ICNS_ICON = new StandardBundlerParam<>( - I18N.getString("param.default-icon-icns"), - I18N.getString("param.default-icon-icns.description"), - ".mac.default.icns", - String.class, - params -> TEMPLATE_BUNDLE_ICON, - (s, p) -> s); - -// public static final BundlerParamInfo DEVELOPER_ID_APP_SIGNING_KEY = new StandardBundlerParam<>( -// I18N.getString("param.signing-key-developer-id-app.name"), -// I18N.getString("param.signing-key-developer-id-app.description"), -// "mac.signing-key-developer-id-app", -// String.class, -// params -> MacBaseInstallerBundler.findKey("Developer ID Application: " + SIGNING_KEY_USER.fetchFrom(params), SIGNING_KEYCHAIN.fetchFrom(params), VERBOSE.fetchFrom(params)), -// (s, p) -> s); - - // public static final BundlerParamInfo BUNDLE_ID_SIGNING_PREFIX = new StandardBundlerParam<>( -// I18N.getString("param.bundle-id-signing-prefix.name"), -// I18N.getString("param.bundle-id-signing-prefix.description"), -// "mac.bundle-id-signing-prefix", -// String.class, -// params -> IDENTIFIER.fetchFrom(params) + ".", -// (s, p) -> s); -// - public static final BundlerParamInfo ICON_ICNS = new StandardBundlerParam<>( - I18N.getString("param.icon-icns.name"), - I18N.getString("param.icon-icns.description"), - "icon.icns", - File.class, - params -> { - File f = ICON.fetchFrom(params); - if (f != null && !f.getName().toLowerCase().endsWith(".icns")) { - Log.info(MessageFormat.format(I18N.getString("message.icon-not-icns"), f)); - return null; - } - return f; - }, - (s, p) -> new File(s)); - - public MacAppImageBuilder(Map config, Path imageOutDir) throws IOException { - super(config, imageOutDir.resolve(APP_NAME.fetchFrom(config) + ".app/Contents/PlugIns/Java.runtime/Contents/Home")); - - Objects.requireNonNull(imageOutDir); - - this.params = config; - this.root = imageOutDir.resolve(APP_NAME.fetchFrom(params) + ".app"); - this.contentsDir = root.resolve("Contents"); - this.javaDir = contentsDir.resolve("Java"); - this.resourcesDir = contentsDir.resolve("Resources"); - this.macOSDir = contentsDir.resolve("MacOS"); - this.runtimeDir = contentsDir.resolve("PlugIns/Java.runtime"); - this.runtimeRoot = runtimeDir.resolve("Contents/Home"); - this.mdir = runtimeRoot.resolve("lib"); - Files.createDirectories(javaDir); - Files.createDirectories(resourcesDir); - Files.createDirectories(macOSDir); - Files.createDirectories(runtimeDir); - } - - private static String extractAppName() { - return ""; - } - - private void writeEntry(InputStream in, Path dstFile) throws IOException { - Files.createDirectories(dstFile.getParent()); - Files.copy(in, dstFile); - } - - /** - * chmod ugo+x file - */ - private void setExecutable(Path file) { - try { - Set perms = Files.getPosixFilePermissions(file); - perms.add(PosixFilePermission.OWNER_EXECUTE); - perms.add(PosixFilePermission.GROUP_EXECUTE); - perms.add(PosixFilePermission.OTHERS_EXECUTE); - Files.setPosixFilePermissions(file, perms); - } catch (IOException ioe) { - throw new UncheckedIOException(ioe); - } - } - - private static void createUtf8File(File file, String content) throws IOException { - try (OutputStream fout = new FileOutputStream(file); - Writer output = new OutputStreamWriter(fout, "UTF-8")) { - output.write(content); - } - } - - @Override - protected String getCacheLocation(Map params) { - return "$CACHEDIR/"; - } - - public static boolean validCFBundleVersion(String v) { - // CFBundleVersion (String - iOS, OS X) specifies the build version - // number of the bundle, which identifies an iteration (released or - // unreleased) of the bundle. The build version number should be a - // string comprised of three non-negative, period-separated integers - // with the first integer being greater than zero. The string should - // only contain numeric (0-9) and period (.) characters. Leading zeros - // are truncated from each integer and will be ignored (that is, - // 1.02.3 is equivalent to 1.2.3). This key is not localizable. - - if (v == null) { - return false; - } - - String p[] = v.split("\\."); - if (p.length > 3 || p.length < 1) { - Log.verbose(I18N.getString("message.version-string-too-many-components")); - return false; - } - - try { - BigInteger n = new BigInteger(p[0]); - if (BigInteger.ONE.compareTo(n) > 0) { - Log.verbose(I18N.getString("message.version-string-first-number-not-zero")); - return false; - } - if (p.length > 1) { - n = new BigInteger(p[1]); - if (BigInteger.ZERO.compareTo(n) > 0) { - Log.verbose(I18N.getString("message.version-string-no-negative-numbers")); - return false; - } - } - if (p.length > 2) { - n = new BigInteger(p[2]); - if (BigInteger.ZERO.compareTo(n) > 0) { - Log.verbose(I18N.getString("message.version-string-no-negative-numbers")); - return false; - } - } - } catch (NumberFormatException ne) { - Log.verbose(I18N.getString("message.version-string-numbers-only")); - Log.verbose(ne); - return false; - } - - return true; - } - - @Override - public InputStream getResourceAsStream(String name) { - return MacResources.class.getResourceAsStream(name); - } - - @Override - public void prepareApplicationFiles() throws IOException { - File f; - - // Generate PkgInfo - File pkgInfoFile = new File(contentsDir.toFile(), "PkgInfo"); - pkgInfoFile.createNewFile(); - writePkgInfo(pkgInfoFile); - - - // Copy executable to MacOS folder - Path executable = macOSDir.resolve(getLauncherName(params)); - writeEntry(MacResources.class.getResourceAsStream(EXECUTABLE_NAME), executable); - executable.toFile().setExecutable(true, false); - - // Copy library to the MacOS folder - writeEntry( - MacResources.class.getResourceAsStream(LIBRARY_NAME), - macOSDir.resolve(LIBRARY_NAME) - ); - - // generate launcher config - - writeCfgFile(params, new File(root.toFile(), getLauncherCfgName(params)), "$APPDIR/PlugIns/Java.runtime"); - - // Copy class path entries to Java folder - copyClassPathEntries(javaDir); - - /*********** Take care of "config" files *******/ - // Copy icon to Resources folder - File icon = ICON_ICNS.fetchFrom(params); - InputStream in = locateResource("package/macosx/" + APP_NAME.fetchFrom(params) + ".icns", - "icon", - DEFAULT_ICNS_ICON.fetchFrom(params), - icon, - VERBOSE.fetchFrom(params), - DROP_IN_RESOURCES_ROOT.fetchFrom(params)); - Files.copy(in, resourcesDir.resolve(APP_NAME.fetchFrom(params) + ".icns")); - - // copy file association icons - for (Map fa : FILE_ASSOCIATIONS.fetchFrom(params)) { - f = FA_ICON.fetchFrom(fa); - if (f != null && f.exists()) { - try (InputStream in2 = new FileInputStream(f)) { - Files.copy(in2, resourcesDir.resolve(f.getName())); - } - - } - } - - // Generate Info.plist - writeInfoPlist(contentsDir.resolve("Info.plist").toFile()); - - // generate java runtime info.plist - writeRuntimeInfoPlist(runtimeDir.resolve("Contents/Info.plist").toFile()); - - // copy library - Path runtimeMacOSDir = Files.createDirectories(runtimeDir.resolve("Contents/MacOS")); - Files.copy(runtimeRoot.resolve("lib/jli/libjli.dylib"), runtimeMacOSDir.resolve("libjli.dylib")); - - // maybe sign - if (Optional.ofNullable(SIGN_BUNDLE.fetchFrom(params)).orElse(Boolean.TRUE)) { - String signingIdentity = DEVELOPER_ID_APP_SIGNING_KEY.fetchFrom(params); - if (signingIdentity != null) { - signAppBundle(params, root, signingIdentity, BUNDLE_ID_SIGNING_PREFIX.fetchFrom(params), null, null); - } - } - } - - - private String getLauncherName(Map params) { - if (APP_NAME.fetchFrom(params) != null) { - return APP_NAME.fetchFrom(params); - } else { - return MAIN_CLASS.fetchFrom(params); - } - } - - public static String getLauncherCfgName(Map p) { - return "Contents/Java/" + APP_NAME.fetchFrom(p) + ".cfg"; - } - - private void copyClassPathEntries(Path javaDirectory) throws IOException { - List resourcesList = APP_RESOURCES_LIST.fetchFrom(params); - if (resourcesList == null) { - throw new RuntimeException(I18N.getString("message.null-classpath")); - } - - for (RelativeFileSet classPath : resourcesList) { - File srcdir = classPath.getBaseDirectory(); - for (String fname : classPath.getIncludedFiles()) { - // use new File since fname can have file separators - Files.copy(new File(srcdir, fname).toPath(), new File(javaDirectory.toFile(), fname).toPath()); - } - } - } - - private String getBundleName(Map params) { - if (MAC_CF_BUNDLE_NAME.fetchFrom(params) != null) { - String bn = MAC_CF_BUNDLE_NAME.fetchFrom(params); - if (bn.length() > 16) { - Log.info(MessageFormat.format(I18N.getString("message.bundle-name-too-long-warning"), MAC_CF_BUNDLE_NAME.getID(), bn)); - } - return MAC_CF_BUNDLE_NAME.fetchFrom(params); - } else if (APP_NAME.fetchFrom(params) != null) { - return APP_NAME.fetchFrom(params); - } else { - String nm = MAIN_CLASS.fetchFrom(params); - if (nm.length() > 16) { - nm = nm.substring(0, 16); - } - return nm; - } - } - - private void writeRuntimeInfoPlist(File file) throws IOException { - Map data = new HashMap<>(); - data.put("CF_BUNDLE_IDENTIFIER", "com.oracle.java." + MAC_CF_BUNDLE_IDENTIFIER.fetchFrom(params)); - data.put("CF_BUNDLE_NAME", "Java Runtime Image"); - data.put("CF_BUNDLE_VERSION", VERSION.fetchFrom(params)); - data.put("CF_BUDNEL_SHORT_VERSION_STRING", VERSION.fetchFrom(params)); - - Writer w = new BufferedWriter(new FileWriter(file)); - w.write(preprocessTextResource( - "package/macosx/Runtime-Info.plist", - I18N.getString("resource.runtime-info-plist"), - TEMPLATE_RUNTIME_INFO_PLIST, - data, - VERBOSE.fetchFrom(params), - DROP_IN_RESOURCES_ROOT.fetchFrom(params))); - w.close(); - } - - private void writeInfoPlist(File file) throws IOException { - Log.verbose(MessageFormat.format(I18N.getString("message.preparing-info-plist"), file.getAbsolutePath())); - - //prepare config for exe - //Note: do not need CFBundleDisplayName if we do not support localization - Map data = new HashMap<>(); - data.put("DEPLOY_ICON_FILE", APP_NAME.fetchFrom(params) + ".icns"); - data.put("DEPLOY_BUNDLE_IDENTIFIER", - MAC_CF_BUNDLE_IDENTIFIER.fetchFrom(params)); - data.put("DEPLOY_BUNDLE_NAME", - getBundleName(params)); - data.put("DEPLOY_BUNDLE_COPYRIGHT", - COPYRIGHT.fetchFrom(params) != null ? COPYRIGHT.fetchFrom(params) : "Unknown"); - data.put("DEPLOY_LAUNCHER_NAME", getLauncherName(params)); - data.put("DEPLOY_JAVA_RUNTIME_NAME", "$APPDIR/PlugIns/Java.runtime"); - data.put("DEPLOY_BUNDLE_SHORT_VERSION", - VERSION.fetchFrom(params) != null ? VERSION.fetchFrom(params) : "1.0.0"); - data.put("DEPLOY_BUNDLE_CFBUNDLE_VERSION", - MAC_CF_BUNDLE_VERSION.fetchFrom(params) != null ? MAC_CF_BUNDLE_VERSION.fetchFrom(params) : "100"); - data.put("DEPLOY_BUNDLE_CATEGORY", MAC_CATEGORY.fetchFrom(params)); - - boolean hasMainJar = MAIN_JAR.fetchFrom(params) != null; - boolean hasMainModule = StandardBundlerParam.MODULE.fetchFrom(params) != null; - - if (hasMainJar) { - data.put("DEPLOY_MAIN_JAR_NAME", MAIN_JAR.fetchFrom(params).getIncludedFiles().iterator().next()); - } - else if (hasMainModule) { - data.put("DEPLOY_MODULE_NAME", StandardBundlerParam.MODULE.fetchFrom(params)); - } - - data.put("DEPLOY_PREFERENCES_ID", PREFERENCES_ID.fetchFrom(params).toLowerCase()); - - StringBuilder sb = new StringBuilder(); - List jvmOptions = JVM_OPTIONS.fetchFrom(params); - - String newline = ""; //So we don't add unneccessary extra line after last append - for (String o : jvmOptions) { - sb.append(newline).append(" ").append(o).append(""); - newline = "\n"; - } - - Map jvmProps = JVM_PROPERTIES.fetchFrom(params); - for (Map.Entry entry : jvmProps.entrySet()) { - sb.append(newline) - .append(" -D") - .append(entry.getKey()) - .append("=") - .append(entry.getValue()) - .append(""); - newline = "\n"; - } - - String preloader = PRELOADER_CLASS.fetchFrom(params); - if (preloader != null) { - sb.append(newline) - .append(" -Djavafx.preloader=") - .append(preloader) - .append(""); - } - - data.put("DEPLOY_JVM_OPTIONS", sb.toString()); - - sb = new StringBuilder(); - List args = ARGUMENTS.fetchFrom(params); - newline = ""; //So we don't add unneccessary extra line after last append - for (String o : args) { - sb.append(newline).append(" ").append(o).append(""); - newline = "\n"; - } - data.put("DEPLOY_ARGUMENTS", sb.toString()); - - newline = ""; - sb = new StringBuilder(); - Map overridableJVMOptions = USER_JVM_OPTIONS.fetchFrom(params); - for (Map.Entry arg : overridableJVMOptions.entrySet()) { - sb.append(newline) - .append(" ").append(arg.getKey()).append("\n") - .append(" ").append(arg.getValue()).append(""); - newline = "\n"; - } - data.put("DEPLOY_JVM_USER_OPTIONS", sb.toString()); - - - data.put("DEPLOY_LAUNCHER_CLASS", MAIN_CLASS.fetchFrom(params)); - - StringBuilder macroedPath = new StringBuilder(); - for (String s : CLASSPATH.fetchFrom(params).split("[ ;:]+")) { - macroedPath.append(s); - macroedPath.append(":"); - } - macroedPath.deleteCharAt(macroedPath.length() - 1); - - data.put("DEPLOY_APP_CLASSPATH", macroedPath.toString()); - - StringBuilder bundleDocumentTypes = new StringBuilder(); - StringBuilder exportedTypes = new StringBuilder(); - for (Map fileAssociation : FILE_ASSOCIATIONS.fetchFrom(params)) { - - List extensions = FA_EXTENSIONS.fetchFrom(fileAssociation); - - if (extensions == null) { - Log.info(I18N.getString("message.creating-association-with-null-extension")); - } - - List mimeTypes = FA_CONTENT_TYPE.fetchFrom(fileAssociation); - String itemContentType = MAC_CF_BUNDLE_IDENTIFIER.fetchFrom(params) + "." + ((extensions == null || extensions.isEmpty()) - ? "mime" - : extensions.get(0)); - String description = FA_DESCRIPTION.fetchFrom(fileAssociation); - File icon = FA_ICON.fetchFrom(fileAssociation); //TODO FA_ICON_ICNS - - bundleDocumentTypes.append(" \n") - .append(" LSItemContentTypes\n") - .append(" \n") - .append(" ") - .append(itemContentType) - .append("\n") - .append(" \n") - .append("\n") - .append(" CFBundleTypeName\n") - .append(" ") - .append(description) - .append("\n") - .append("\n") - .append(" LSHandlerRank\n") - .append(" Owner\n") //TODO make a bundler arg - .append("\n") - .append(" CFBundleTypeRole\n") - .append(" Editor\n") // TODO make a bundler arg - .append("\n") - .append(" LSIsAppleDefaultForType\n") - .append(" \n") // TODO make a bundler arg - .append("\n"); - - if (icon != null && icon.exists()) { - //? - bundleDocumentTypes.append(" CFBundleTypeIconFile\n") - .append(" ") - .append(icon.getName()) - .append("\n"); - } - bundleDocumentTypes.append(" \n"); - - exportedTypes.append(" \n") - .append(" UTTypeIdentifier\n") - .append(" ") - .append(itemContentType) - .append("\n") - .append("\n") - .append(" UTTypeDescription\n") - .append(" ") - .append(description) - .append("\n") - .append(" UTTypeConformsTo\n") - .append(" \n") - .append(" public.data\n") //TODO expose this? - .append(" \n") - .append("\n"); - - if (icon != null && icon.exists()) { - exportedTypes.append(" UTTypeIconFile\n") - .append(" ") - .append(icon.getName()) - .append("\n") - .append("\n"); - } - - exportedTypes.append("\n") - .append(" UTTypeTagSpecification\n") - .append(" \n") - //TODO expose via param? .append(" com.apple.ostype\n"); - //TODO expose via param? .append(" ABCD\n") - .append("\n"); - - if (extensions != null && !extensions.isEmpty()) { - exportedTypes.append(" public.filename-extension\n") - .append(" \n"); - - for (String ext : extensions) { - exportedTypes.append(" ") - .append(ext) - .append("\n"); - } - exportedTypes.append(" \n"); - } - if (mimeTypes != null && !mimeTypes.isEmpty()) { - exportedTypes.append(" public.mime-type\n") - .append(" \n"); - - for (String mime : mimeTypes) { - exportedTypes.append(" ") - .append(mime) - .append("\n"); - } - exportedTypes.append(" \n"); - } - exportedTypes.append(" \n") - .append(" \n"); - } - String associationData; - if (bundleDocumentTypes.length() > 0) { - associationData = "\n CFBundleDocumentTypes\n \n" - + bundleDocumentTypes.toString() - + " \n\n UTExportedTypeDeclarations\n \n" - + exportedTypes.toString() - + " \n"; - } else { - associationData = ""; - } - data.put("DEPLOY_FILE_ASSOCIATIONS", associationData); - - - Writer w = new BufferedWriter(new FileWriter(file)); - w.write(preprocessTextResource( - //MAC_BUNDLER_PREFIX + getConfig_InfoPlist(params).getName(), - "package/macosx/Info.plist", - I18N.getString("resource.app-info-plist"), - TEMPLATE_INFO_PLIST_LITE, - data, VERBOSE.fetchFrom(params), - DROP_IN_RESOURCES_ROOT.fetchFrom(params))); - w.close(); - } - - private void writePkgInfo(File file) throws IOException { - //hardcoded as it does not seem we need to change it ever - String signature = "????"; - - try (Writer out = new BufferedWriter(new FileWriter(file))) { - out.write(OS_TYPE_CODE + signature); - out.flush(); - } - } - - public static void signAppBundle(Map params, Path appLocation, String signingIdentity, String identifierPrefix, String entitlementsFile, String inheritedEntitlements) throws IOException { - AtomicReference toThrow = new AtomicReference<>(); - String appExecutable = "/Contents/MacOS/" + APP_NAME.fetchFrom(params); - String keyChain = SIGNING_KEYCHAIN.fetchFrom(params); - - // sign all dylibs and jars - Files.walk(appLocation) - // fix permissions - .peek(path -> { - try { - Set pfp = Files.getPosixFilePermissions(path); - if (!pfp.contains(PosixFilePermission.OWNER_WRITE)) { - pfp = EnumSet.copyOf(pfp); - pfp.add(PosixFilePermission.OWNER_WRITE); - Files.setPosixFilePermissions(path, pfp); - } - } catch (IOException e) { - Log.debug(e); - } - }) - .filter(p -> Files.isRegularFile(p) && - !(p.toString().contains("/Contents/MacOS/libjli.dylib") - || p.toString().contains("/Contents/MacOS/JavaAppletPlugin") - || p.toString().endsWith(appExecutable)) - ).forEach(p -> { - //noinspection ThrowableResultOfMethodCallIgnored - if (toThrow.get() != null) return; - - // If p is a symlink then skip the signing process. - if (Files.isSymbolicLink(p)) { - if (VERBOSE.fetchFrom(params)) { - Log.verbose(MessageFormat.format(I18N.getString("message.ignoring.symlink"), p.toString())); - } - } - else { - List args = new ArrayList<>(); - args.addAll(Arrays.asList("codesign", - "-s", signingIdentity, // sign with this key - "--prefix", identifierPrefix, // use the identifier as a prefix - "-vvvv")); - if (entitlementsFile != null && - (p.toString().endsWith(".jar") - || p.toString().endsWith(".dylib"))) { - args.add("--entitlements"); - args.add(entitlementsFile); // entitlements - } else if (inheritedEntitlements != null && Files.isExecutable(p)) { - args.add("--entitlements"); - args.add(inheritedEntitlements); // inherited entitlements for executable processes - } - if (keyChain != null && !keyChain.isEmpty()) { - args.add("--keychain"); - args.add(keyChain); - } - args.add(p.toString()); - - try { - Set oldPermissions = Files.getPosixFilePermissions(p); - File f = p.toFile(); - f.setWritable(true, true); - - ProcessBuilder pb = new ProcessBuilder(args); - IOUtils.exec(pb, VERBOSE.fetchFrom(params)); - - Files.setPosixFilePermissions(p, oldPermissions); - } catch (IOException ioe) { - toThrow.set(ioe); - } - } - }); - - IOException ioe = toThrow.get(); - if (ioe != null) { - throw ioe; - } - - // sign all plugins and frameworks - Consumer signIdentifiedByPList = path -> { - //noinspection ThrowableResultOfMethodCallIgnored - if (toThrow.get() != null) return; - - try { - List args = new ArrayList<>(); - args.addAll(Arrays.asList("codesign", - "-s", signingIdentity, // sign with this key - "--prefix", identifierPrefix, // use the identifier as a prefix - "-vvvv")); - if (keyChain != null && !keyChain.isEmpty()) { - args.add("--keychain"); - args.add(keyChain); - } - args.add(path.toString()); - ProcessBuilder pb = new ProcessBuilder(args); - IOUtils.exec(pb, VERBOSE.fetchFrom(params)); - - args = new ArrayList<>(); - args.addAll(Arrays.asList("codesign", - "-s", signingIdentity, // sign with this key - "--prefix", identifierPrefix, // use the identifier as a prefix - "-vvvv")); - if (keyChain != null && !keyChain.isEmpty()) { - args.add("--keychain"); - args.add(keyChain); - } - args.add(path.toString() + "/Contents/_CodeSignature/CodeResources"); - pb = new ProcessBuilder(args); - IOUtils.exec(pb, VERBOSE.fetchFrom(params)); - } catch (IOException e) { - toThrow.set(e); - } - }; - - Path pluginsPath = appLocation.resolve("Contents/PlugIns"); - if (Files.isDirectory(pluginsPath)) { - Files.list(pluginsPath) - .forEach(signIdentifiedByPList); - - ioe = toThrow.get(); - if (ioe != null) { - throw ioe; - } - } - Path frameworkPath = appLocation.resolve("Contents/Frameworks"); - if (Files.isDirectory(frameworkPath)) { - Files.list(frameworkPath) - .forEach(signIdentifiedByPList); - - ioe = toThrow.get(); - if (ioe != null) { - throw ioe; - } - } - - // sign the app itself - List args = new ArrayList<>(); - args.addAll(Arrays.asList("codesign", - "-s", signingIdentity, // sign with this key - "-vvvv")); // super verbose output - if (entitlementsFile != null) { - args.add("--entitlements"); - args.add(entitlementsFile); // entitlements - } - if (keyChain != null && !keyChain.isEmpty()) { - args.add("--keychain"); - args.add(keyChain); - } - args.add(appLocation.toString()); - - ProcessBuilder pb = new ProcessBuilder(args.toArray(new String[args.size()])); - IOUtils.exec(pb, VERBOSE.fetchFrom(params)); - } - -} --- old/modules/jdk.packager/src/main/java/jdk/packager/builders/windows/WindowsAppImageBuilder.java 2017-08-15 12:39:00.000000000 -0700 +++ /dev/null 2017-08-15 12:39:00.000000000 -0700 @@ -1,446 +0,0 @@ -/* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.packager.builders.windows; - - -import com.oracle.tools.packager.BundlerParamInfo; -import com.oracle.tools.packager.Log; -import com.oracle.tools.packager.RelativeFileSet; -import com.oracle.tools.packager.IOUtils; -import com.oracle.tools.packager.StandardBundlerParam; -import com.oracle.tools.packager.windows.WinResources; -import com.oracle.tools.packager.windows.WindowsBundlerParam; -import jdk.packager.builders.AbstractAppImageBuilder; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.UncheckedIOException; -import java.io.Writer; -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.attribute.PosixFilePermission; -import java.text.MessageFormat; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.ResourceBundle; -import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; -import java.util.regex.Pattern; -import java.util.stream.Stream; - -import static com.oracle.tools.packager.StandardBundlerParam.*; -import jdk.packager.internal.windows.WindowsDefender; - -/** - * - */ -public class WindowsAppImageBuilder extends AbstractAppImageBuilder { - - private static final ResourceBundle I18N = - ResourceBundle.getBundle(WindowsAppImageBuilder.class.getName()); - - protected static final String WINDOWS_BUNDLER_PREFIX = - BUNDLER_PREFIX + "windows" + File.separator; - - private final static String EXECUTABLE_NAME = "WinLauncher.exe"; - private final static String LIBRARY_NAME = "packager.dll"; - - private final static String[] VS_VERS = {"100", "110", "120", "140"}; - private final static String REDIST_MSVCR = "vcruntimeVS_VER.dll"; - private final static String REDIST_MSVCP = "msvcpVS_VER.dll"; - - private final static String TEMPLATE_APP_ICON ="javalogo_white_48.ico"; - - private static final String EXECUTABLE_PROPERTIES_TEMPLATE = "WinLauncher.properties"; - - private final Path root; - private final Path appDir; - private final Path runtimeDir; - private final Path mdir; - - private final Map params; - - public static final BundlerParamInfo CONFIG_ROOT = new WindowsBundlerParam<>( - I18N.getString("param.config-root.name"), - I18N.getString("param.config-root.description"), - "configRoot", - File.class, - params -> { - File imagesRoot = new File(BUILD_ROOT.fetchFrom(params), "windows"); - imagesRoot.mkdirs(); - return imagesRoot; - }, - (s, p) -> null); - - public static final BundlerParamInfo REBRAND_EXECUTABLE = new WindowsBundlerParam<>( - I18N.getString("param.rebrand-executable.name"), - I18N.getString("param.rebrand-executable.description"), - "win.launcher.rebrand", - Boolean.class, - params -> Boolean.TRUE, - (s, p) -> Boolean.valueOf(s)); - - public static final BundlerParamInfo ICON_ICO = new StandardBundlerParam<>( - I18N.getString("param.icon-ico.name"), - I18N.getString("param.icon-ico.description"), - "icon.ico", - File.class, - params -> { - File f = ICON.fetchFrom(params); - if (f != null && !f.getName().toLowerCase().endsWith(".ico")) { - Log.info(MessageFormat.format(I18N.getString("message.icon-not-ico"), f)); - return null; - } - return f; - }, - (s, p) -> new File(s)); - - - - public WindowsAppImageBuilder(Map config, Path imageOutDir) throws IOException { - super(config, imageOutDir.resolve(APP_NAME.fetchFrom(config) + "/runtime")); - - Objects.requireNonNull(imageOutDir); - - this.params = config; - - this.root = imageOutDir.resolve(APP_NAME.fetchFrom(params)); - this.appDir = root.resolve("app"); - this.runtimeDir = root.resolve("runtime"); - this.mdir = runtimeDir.resolve("lib"); - Files.createDirectories(appDir); - Files.createDirectories(runtimeDir); - } - - private Path destFile(String dir, String filename) { - return runtimeDir.resolve(dir).resolve(filename); - } - - private void writeEntry(InputStream in, Path dstFile) throws IOException { - Files.createDirectories(dstFile.getParent()); - Files.copy(in, dstFile); - } - - private void writeSymEntry(Path dstFile, Path target) throws IOException { - Files.createDirectories(dstFile.getParent()); - Files.createLink(dstFile, target); - } - - /** - * chmod ugo+x file - */ - private void setExecutable(Path file) { - try { - Set perms = Files.getPosixFilePermissions(file); - perms.add(PosixFilePermission.OWNER_EXECUTE); - perms.add(PosixFilePermission.GROUP_EXECUTE); - perms.add(PosixFilePermission.OTHERS_EXECUTE); - Files.setPosixFilePermissions(file, perms); - } catch (IOException ioe) { - throw new UncheckedIOException(ioe); - } - } - - private static void createUtf8File(File file, String content) throws IOException { - try (OutputStream fout = new FileOutputStream(file); - Writer output = new OutputStreamWriter(fout, "UTF-8")) { - output.write(content); - } - } - - // This method is static for the sake of sharing with "installer" bundlers - // that may skip calls to validate/bundle in this class! - public static File getRootDir(File outDir, Map p) { - return new File(outDir, APP_FS_NAME.fetchFrom(p)); - } - - public static String getLauncherName(Map p) { - return APP_FS_NAME.fetchFrom(p) + ".exe"; - } - - public static String getLauncherCfgName(Map p) { - return "app/" + APP_FS_NAME.fetchFrom(p) +".cfg"; - } - - private File getConfig_AppIcon(Map params) { - return new File(getConfigRoot(params), APP_FS_NAME.fetchFrom(params) + ".ico"); - } - - private File getConfig_ExecutableProperties(Map params) { - return new File(getConfigRoot(params), APP_FS_NAME.fetchFrom(params) + ".properties"); - } - - File getConfigRoot(Map params) { - return CONFIG_ROOT.fetchFrom(params); - } - - protected void cleanupConfigFiles(Map params) { - getConfig_AppIcon(params).delete(); - getConfig_ExecutableProperties(params).delete(); - } - - @Override - public InputStream getResourceAsStream(String name) { - return WinResources.class.getResourceAsStream(name); - } - - @Override - public void prepareApplicationFiles() throws IOException { - Map originalParams = new HashMap<>(params); - File rootFile = root.toFile(); - if (!rootFile.isDirectory() && !rootFile.mkdirs()) { - throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-create-output-dir"), rootFile.getAbsolutePath())); - } - if (!rootFile.canWrite()) { - throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-write-to-output-dir"), rootFile.getAbsolutePath())); - } - try { -// if (!dependentTask) { -// Log.info(MessageFormat.format(I18N.getString("message.creating-app-bundle"), APP_NAME.fetchFrom(p), outputDirectory.getAbsolutePath())); -// } - - // Create directory structure -// IOUtils.deleteRecursive(rootDirectory); -// rootDirectory.mkdirs(); - - - // create the .exe launchers - createLauncherForEntryPoint(params); - - // copy the jars - copyApplication(params); - - // copy in the needed libraries - Files.copy(WinResources.class.getResourceAsStream(LIBRARY_NAME), - root.resolve(LIBRARY_NAME)); - - copyMSVCDLLs(); - - // create the secondary launchers, if any - List> entryPoints = StandardBundlerParam.SECONDARY_LAUNCHERS.fetchFrom(params); - for (Map entryPoint : entryPoints) { - Map tmp = new HashMap<>(originalParams); - tmp.putAll(entryPoint); - createLauncherForEntryPoint(tmp); - } - - } catch (IOException ex) { - Log.info("Exception: "+ex); - Log.debug(ex); - } finally { - - if (VERBOSE.fetchFrom(params)) { - Log.info(MessageFormat.format(I18N.getString("message.config-save-location"), getConfigRoot(params).getAbsolutePath())); - } else { - cleanupConfigFiles(params); - } - } - } - - private void copyMSVCDLLs() throws IOException { - String vsVer = null; - - // first copy the ones needed for the launcher - for (String thisVer : VS_VERS) { - if (copyMSVCDLLs(thisVer)) { - vsVer = thisVer; - break; - } - } - if (vsVer == null) { - throw new RuntimeException("Not found MSVC dlls"); - } - - AtomicReference ioe = new AtomicReference<>(); - final String finalVsVer = vsVer; - try (Stream files = Files.list(runtimeDir.resolve("bin"))) { - files.filter(p -> Pattern.matches("(vcruntime|msvcp)\\d\\d\\d.dll", p.toFile().getName().toLowerCase())) - .filter(p -> !p.toString().toLowerCase().endsWith(finalVsVer + ".dll")) - .forEach(p -> { - try { - Files.copy(p, root.resolve((p.toFile().getName()))); - } catch (IOException e) { - ioe.set(e); - } - }); - } - - IOException e = ioe.get(); - if (e != null) { - throw e; - } - } - - private boolean copyMSVCDLLs(String VS_VER) throws IOException { - final InputStream REDIST_MSVCR_URL = WinResources.class.getResourceAsStream( - REDIST_MSVCR.replaceAll("VS_VER", VS_VER)); - final InputStream REDIST_MSVCP_URL = WinResources.class.getResourceAsStream( - REDIST_MSVCP.replaceAll("VS_VER", VS_VER)); - - if (REDIST_MSVCR_URL != null && REDIST_MSVCP_URL != null) { - Files.copy( - REDIST_MSVCR_URL, - root.resolve(REDIST_MSVCR.replaceAll("VS_VER", VS_VER))); - Files.copy( - REDIST_MSVCP_URL, - root.resolve(REDIST_MSVCP.replaceAll("VS_VER", VS_VER))); - return true; - } - - return false; // not found - } - - private void validateValueAndPut(Map data, String key, - BundlerParamInfo param, Map params) { - String value = param.fetchFrom(params); - if (value.contains("\r") || value.contains("\n")) { - Log.info("Configuration Parameter " + param.getID() + " contains multiple lines of text, ignore it"); - data.put(key, ""); - return; - } - data.put(key, value); - } - - protected void prepareExecutableProperties(Map params) - throws IOException { - Map data = new HashMap<>(); - - // mapping Java parameters in strings for version resource - data.put("COMMENTS", ""); - validateValueAndPut(data, "COMPANY_NAME", VENDOR, params); - validateValueAndPut(data, "FILE_DESCRIPTION", DESCRIPTION, params); - validateValueAndPut(data, "FILE_VERSION", VERSION, params); - data.put("INTERNAL_NAME", getLauncherName(params)); - validateValueAndPut(data, "LEGAL_COPYRIGHT", COPYRIGHT, params); - data.put("LEGAL_TRADEMARK", ""); - data.put("ORIGINAL_FILENAME", getLauncherName(params)); - data.put("PRIVATE_BUILD", ""); - validateValueAndPut(data, "PRODUCT_NAME", APP_NAME, params); - validateValueAndPut(data, "PRODUCT_VERSION", VERSION, params); - data.put("SPECIAL_BUILD", ""); - - Writer w = new BufferedWriter(new FileWriter(getConfig_ExecutableProperties(params))); - String content = preprocessTextResource( - WINDOWS_BUNDLER_PREFIX + getConfig_ExecutableProperties(params).getName(), - I18N.getString("resource.executable-properties-template"), EXECUTABLE_PROPERTIES_TEMPLATE, data, - VERBOSE.fetchFrom(params), - DROP_IN_RESOURCES_ROOT.fetchFrom(params)); - w.write(content); - w.close(); - } - - private void createLauncherForEntryPoint(Map p) throws IOException { - - File launcherIcon = ICON_ICO.fetchFrom(p); - File icon = launcherIcon != null ? launcherIcon : ICON_ICO.fetchFrom(params); - File iconTarget = getConfig_AppIcon(p); - - InputStream in = locateResource("package/windows/" + APP_NAME.fetchFrom(params) + ".ico", - "icon", - TEMPLATE_APP_ICON, - icon, - VERBOSE.fetchFrom(params), - DROP_IN_RESOURCES_ROOT.fetchFrom(params)); - Files.copy(in, iconTarget.toPath()); - - writeCfgFile(p, root.resolve(getLauncherCfgName(p)).toFile(), "$APPDIR\\runtime"); - - prepareExecutableProperties(p); - - // Copy executable root folder - Path executableFile = root.resolve(getLauncherName(p)); - writeEntry(WinResources.class.getResourceAsStream(EXECUTABLE_NAME), executableFile); - File launcher = executableFile.toFile(); - launcher.setWritable(true, true); - - // Update branding of EXE file - if (REBRAND_EXECUTABLE.fetchFrom(p)) { - File tool = new File(System.getProperty("java.home") + "\\bin\\javapackager.exe"); - - // Run tool on launcher file to change the icon and the metadata. - try { - if (WindowsDefender.isThereAPotentialWindowsDefenderIssue()) { - Log.info(MessageFormat.format(I18N.getString("message.potential.windows.defender.issue"), WindowsDefender.getUserTempDirectory())); - } - - launcher.setWritable(true); - - if (iconTarget.exists()) { - ProcessBuilder pb = new ProcessBuilder( - tool.getAbsolutePath(), - "--icon-swap", - iconTarget.getAbsolutePath(), - launcher.getAbsolutePath()); - IOUtils.exec(pb, VERBOSE.fetchFrom(p)); - } - - File executableProperties = getConfig_ExecutableProperties(p); - - if (executableProperties.exists()) { - ProcessBuilder pb = new ProcessBuilder( - tool.getAbsolutePath(), - "--version-swap", - executableProperties.getAbsolutePath(), - launcher.getAbsolutePath()); - IOUtils.exec(pb, VERBOSE.fetchFrom(p)); - } - } - finally { - executableFile.toFile().setReadOnly(); - } - } - - Files.copy(iconTarget.toPath(), root.resolve(APP_NAME.fetchFrom(p) + ".ico")); - } - - private void copyApplication(Map params) throws IOException { - List appResourcesList = APP_RESOURCES_LIST.fetchFrom(params); - if (appResourcesList == null) { - throw new RuntimeException("Null app resources?"); - } - for (RelativeFileSet appResources : appResourcesList) { - if (appResources == null) { - throw new RuntimeException("Null app resources?"); - } - File srcdir = appResources.getBaseDirectory(); - for (String fname : appResources.getIncludedFiles()) { - Files.copy(new File(srcdir, fname).toPath(), new File(appDir.toFile(), fname).toPath()); - } - } - } - - @Override - protected String getCacheLocation(Map params) { - return "$CACHEDIR/"; - } -} --- old/modules/jdk.packager/src/main/java/jdk/packager/internal/JDepHelper.java 2017-08-15 12:39:01.000000000 -0700 +++ /dev/null 2017-08-15 12:39:01.000000000 -0700 @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.packager.internal; - - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.PrintWriter; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.spi.ToolProvider; -import java.util.Optional; -import java.io.PrintWriter; -import java.util.Collection; - -import com.oracle.tools.packager.Log; - - -public final class JDepHelper { - - private JDepHelper() {} - - private static int execute(String[] args, PrintWriter out) { - Optional jdeps = ToolProvider.findFirst("jdeps"); - if (jdeps.isPresent()) { - return jdeps.get().run(out, null, args); - } else throw new RuntimeException("jdeps not found"); - } - - public static Set calculateModules(Collection Files, List modulePath) { - Set result = null; - - if (!Files.isEmpty()) { - try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); - PrintWriter writer = new PrintWriter(baos)) { - - List arguments = new ArrayList<>(); - arguments.add("-s"); - - // Uncomment out once JDK-8151729 is fixed - /*if (modulePath != null || !modulePath.isEmpty()) { - arguments.add("-modulepath"); - arguments.add(ListOfPathToString(modulePath)); - }*/ - - arguments.addAll(Files); - - execute(arguments.toArray(new String[arguments.size()]), writer); - - // Output format is multiple lines of "this.jar -> that.module.name" - // we only care about what is to the right of the arrow. - result = Arrays.stream(baos.toString().split("\\s*\\S+\\s+->\\s+")) - .map(String::trim) - .filter(s -> !s.isEmpty() && !arguments.contains(s) && !"not found".equals(s)) - .collect(Collectors.toSet()); - } catch (IOException exception) { - Log.verbose(exception); - } - } - - if (result == null) { - result = new LinkedHashSet(); - } - - return result; - } - - private static String ListOfPathToString(List Value) { - String result = ""; - - for (Path path : Value) { - if (result.isEmpty()) { - result = path.toString(); - } - else { - result = File.pathSeparator + path.toString(); - } - } - - return result; - } -} --- old/modules/jdk.packager/src/main/java/jdk/packager/internal/JLinkBundlerHelper.java 2017-08-15 12:39:02.000000000 -0700 +++ /dev/null 2017-08-15 12:39:02.000000000 -0700 @@ -1,498 +0,0 @@ -/* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.packager.internal; - - -import com.oracle.tools.packager.StandardBundlerParam; -import com.oracle.tools.packager.BundlerParamInfo; -import com.oracle.tools.packager.RelativeFileSet; -import com.oracle.tools.packager.Log; -import com.oracle.tools.packager.Platform; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintWriter; -import java.io.StringReader; -import java.net.URI; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Properties; -import java.util.ResourceBundle; -import java.util.Set; -import java.util.TreeSet; -import java.util.function.Supplier; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -import jdk.packager.builders.AbstractAppImageBuilder; -import jdk.packager.internal.Module; -import jdk.tools.jlink.internal.packager.AppRuntimeImageBuilder; - - -public final class JLinkBundlerHelper { - - private static final ResourceBundle I18N = - ResourceBundle.getBundle(JLinkBundlerHelper.class.getName()); - - private JLinkBundlerHelper() {} - - @SuppressWarnings("unchecked") - public static final BundlerParamInfo DETECT_MODULES = - new StandardBundlerParam<>( - I18N.getString("param.detect-modules.name"), - I18N.getString("param.detect-modules.description"), - "detect-modules", - Boolean.class, - p -> Boolean.FALSE, - (s, p) -> Boolean.valueOf(s)); - - @SuppressWarnings("unchecked") - public static final BundlerParamInfo> JLINK_OPTIONS = - new StandardBundlerParam<>( - I18N.getString("param.jlink-options.name"), - I18N.getString("param.jlink-options.description"), - "jlinkOptions", - (Class>) (Object) Map.class, - p -> Collections.emptyMap(), - (s, p) -> { - try { - Properties props = new Properties(); - props.load(new StringReader(s)); - return new LinkedHashMap<>((Map)props); - } catch (IOException e) { - return new LinkedHashMap<>(); - } - }); - - @SuppressWarnings("unchecked") - public static final BundlerParamInfo JLINK_BUILDER = - new StandardBundlerParam<>( - I18N.getString("param.jlink-builder.name"), - I18N.getString("param.jlink-builder.description"), - "jlink.builder", - String.class, - null, - (s, p) -> s); - - @SuppressWarnings("unchecked") - public static final BundlerParamInfo DEBUG = - new StandardBundlerParam<>( - "", - "", - "-J-Xdebug", - Integer.class, - p -> null, - (s, p) -> { - return Integer.valueOf(s); - }); - - public static String listOfPathToString(List value) { - String result = ""; - - for (Path path : value) { - if (result.length() > 0) { - result += File.pathSeparator; - } - - result += path.toString(); - } - - return result; - } - - public static String setOfStringToString(Set value) { - String result = ""; - - for (String element : value) { - if (result.length() > 0) { - result += ","; - } - - result += element; - } - - return result; - } - - public static File getMainJar(Map params) { - File result = null; - RelativeFileSet fileset = StandardBundlerParam.MAIN_JAR.fetchFrom(params); - - if (fileset != null) { - String filename = fileset.getIncludedFiles().iterator().next(); - result = fileset.getBaseDirectory().toPath().resolve(filename).toFile(); - - if (result == null || !result.exists()) { - String srcdir = StandardBundlerParam.SOURCE_DIR.fetchFrom(params); - - if (srcdir != null) { - result = new File(srcdir + File.separator + filename); - } - } - } - - return result; - } - - public static String getMainClass(Map params) { - String result = ""; - File mainJar = getMainJar(params); - - if (mainJar != null) { - result = StandardBundlerParam.MAIN_CLASS.fetchFrom(params); - } - else { - String mainModule = StandardBundlerParam.MODULE.fetchFrom(params); - - if (mainModule != null) { - int index = mainModule.indexOf("/"); - - if (index > 0) { - result = mainModule.substring(index + 1); - } - } - } - - return result; - } - - public static String getMainModule(Map params) { - String result = ""; - String mainModule = StandardBundlerParam.MODULE.fetchFrom(params); - - if (mainModule != null) { - int index = mainModule.indexOf("/"); - - if (index > 0) { - result = mainModule.substring(0, index); - } - else { - result = mainModule; - } - } - - return result; - } - - public static String getJDKVersion(Map params) { - String result = ""; - List modulePath = StandardBundlerParam.MODULE_PATH.fetchFrom(params); - Set limitModules = StandardBundlerParam.LIMIT_MODULES.fetchFrom(params); - Path javaBasePath = findPathOfModule(modulePath, "java.base.jmod"); - Set addModules = getRedistributableModules(modulePath, StandardBundlerParam.ADD_MODULES.fetchFrom(params), limitModules); - - if (javaBasePath != null && javaBasePath.toFile().exists()) { - result = RedistributableModules.getModuleVersion(javaBasePath.toFile(), - modulePath, addModules, limitModules); - } - - return result; - } - - public static Path getJDKHome(Map params) { - Path result = null; - List modulePath = StandardBundlerParam.MODULE_PATH.fetchFrom(params); - Path javaBasePath = findPathOfModule(modulePath, "java.base.jmod"); - - if (javaBasePath != null && javaBasePath.toFile().exists()) { - result = javaBasePath.getParent(); - - // On a developer build the JDK Home isn't where we expect it - // relative to the jmods directory. Do some extra - // processing to find it. - if (result != null) { - boolean found = false; - Path bin = result.resolve("bin"); - - if (Files.exists(bin)) { - final String exe = (Platform.getPlatform() == Platform.WINDOWS) ? ".exe" : ""; - Path javaExe = bin.resolve("java" + exe); - - if (Files.exists(javaExe)) { - found = true; - } - } - - if (!found) { - result = result.resolve(".." + File.separator + "jdk"); - } - } - } - - return result; - } - - private static Set getRedistributableModules(List modulePath, Set addModules, Set limitModules) { - ModuleHelper moduleHelper = new ModuleHelper(modulePath, addModules, limitModules); - return removeInvalidModules(modulePath, moduleHelper.modules()); - } - - public static void execute(Map params, AbstractAppImageBuilder imageBuilder) throws IOException, Exception { - List modulePath = StandardBundlerParam.MODULE_PATH.fetchFrom(params); - Set addModules = StandardBundlerParam.ADD_MODULES.fetchFrom(params); - Set limitModules = StandardBundlerParam.LIMIT_MODULES.fetchFrom(params); - boolean stripNativeCommands = StandardBundlerParam.STRIP_NATIVE_COMMANDS.fetchFrom(params); - Map userArguments = JLINK_OPTIONS.fetchFrom(params); - Path outputDir = imageBuilder.getRoot(); - String excludeFileList = imageBuilder.getExcludeFileList(); - Set jars = getResourceFileJarList(params, Module.JarType.UnnamedJar); - File mainJar = getMainJar(params); - Module.ModuleType mainJarType = Module.ModuleType.Unknown; - - if (mainJar != null) { - mainJarType = new Module(mainJar).getModuleType(); - } - - //-------------------------------------------------------------------- - // Modules - - boolean detectModules = DETECT_MODULES.fetchFrom(params); - - // The default for an unnamed jar is ALL_DEFAULT with the - // non-redistributable modules removed. - if (mainJarType == Module.ModuleType.UnnamedJar && !detectModules) { - addModules.add(ModuleHelper.ALL_RUNTIME); - } - else if (mainJarType == Module.ModuleType.Unknown || mainJarType == Module.ModuleType.ModularJar) { - String mainModule = getMainModule(params); - addModules.add(mainModule); - - // Error if any of the srcfiles are modular jars. - Set modularJars = getResourceFileJarList(params, Module.JarType.ModularJar); - - if (!modularJars.isEmpty()) { - throw new Exception(MessageFormat.format(I18N.getString("error.srcfiles.contain.modules"), modularJars.toString())); - } - } - - Set redistModules = getRedistributableModules(modulePath, addModules, limitModules); - addModules.addAll(redistModules); - - //-------------------------------------------------------------------- - // Jars - - // Bundle with minimum dependencies that unnamed jars depend on. - if (detectModules && !jars.isEmpty()) { - Log.info(MessageFormat.format(I18N.getString("using.experimental.feature"), "--" + DETECT_MODULES.getID())); - Collection detectedModules = JDepHelper.calculateModules(jars, modulePath); - - if (!detectedModules.isEmpty()) { - addModules.addAll(detectedModules); - } - } - - Log.info(MessageFormat.format(I18N.getString("message.modules"), addModules.toString())); - - if (StandardBundlerParam.VERBOSE.fetchFrom(params)) { - Log.info("outputDir = " + outputDir.toString()); - Log.info("modulePath = " + modulePath.toString()); - Log.info("addModules = " + addModules.toString()); - Log.info("limitModules = " + limitModules.toString()); - Log.info("excludeFileList = " + excludeFileList); - Log.info("stripNativeCommands = " + stripNativeCommands); - Log.info("userArguments = " + userArguments.toString()); - } - - AppRuntimeImageBuilder appRuntimeBuilder = new AppRuntimeImageBuilder(); - appRuntimeBuilder.setOutputDir(outputDir); - appRuntimeBuilder.setModulePath(modulePath); - appRuntimeBuilder.setAddModules(addModules); - appRuntimeBuilder.setLimitModules(limitModules); - appRuntimeBuilder.setExcludeFileList(excludeFileList); - appRuntimeBuilder.setStripNativeCommands(stripNativeCommands); - appRuntimeBuilder.setUserArguments(userArguments); - - appRuntimeBuilder.build(); - imageBuilder.prepareApplicationFiles(); - } - - // Returns the path to the JDK modules in the user defined module path. - public static Path findPathOfModule(List modulePath, String moduleName) { - Path result = null; - - for (Path path : modulePath) { - Path moduleNamePath = path.resolve(moduleName); - - if (Files.exists(moduleNamePath)) { - result = path; - break; - } - } - - return result; - } - - private static Set getResourceFileJarList(Map params, Module.JarType Query) { - Set files = new LinkedHashSet(); - - String srcdir = StandardBundlerParam.SOURCE_DIR.fetchFrom(params); - - for (RelativeFileSet appResources : StandardBundlerParam.APP_RESOURCES_LIST.fetchFrom(params)) { - for (String resource : appResources.getIncludedFiles()) { - if (resource.endsWith(".jar")) { - String filename = srcdir + File.separator + resource; - - switch (Query) { - case All: { - files.add(filename); - break; - } - case ModularJar: { - Module module = new Module(new File(filename)); - - if (module.getModuleType() == Module.ModuleType.ModularJar) { - files.add(filename); - } - break; - } - case UnnamedJar: { - Module module = new Module(new File(filename)); - - if (module.getModuleType() == Module.ModuleType.UnnamedJar) { - files.add(filename); - } - break; - } - } - } - } - } - - return files; - } - - private static Set removeInvalidModules(List modulePath, Set modules) { - Set result = new LinkedHashSet(); - ModuleManager mm = new ModuleManager(modulePath); - List lmodules = mm.getModules(EnumSet.of(ModuleManager.SearchType.ModularJar, - ModuleManager.SearchType.Jmod, - ModuleManager.SearchType.ExplodedModule)); - - HashMap validModules = new HashMap<>(); - - for (Module module : lmodules) { - validModules.put(module.getModuleName(), module); - } - - for (String name : modules) { - if (validModules.containsKey(name)) { - result.add(name); - } - else { - Log.info(MessageFormat.format(I18N.getString("warning.module.does.not.exist"), name)); - } - } - - return result; - } - - private static class ModuleHelper { - // The token for "all modules on the module path". - private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH"; - - // The token for "all redistributable runtime modules". - public static final String ALL_RUNTIME = "ALL-RUNTIME"; - - private final Set modules = new HashSet<>(); - private enum Macros {None, AllModulePath, AllRuntime} - - public ModuleHelper(List paths, Set roots, Set limitMods) { - Macros macro = Macros.None; - - for (Iterator iterator = roots.iterator(); iterator.hasNext();) { - String module = iterator.next(); - - switch (module) { - case ALL_MODULE_PATH: - iterator.remove(); - macro = Macros.AllModulePath; - break; - case ALL_RUNTIME: - iterator.remove(); - macro = Macros.AllRuntime; - break; - default: - this.modules.add(module); - } - } - - switch (macro) { - case AllModulePath: - this.modules.addAll(getModuleNamesFromPath(paths)); - break; - case AllRuntime: - Set m = RedistributableModules.getRedistributableModules(paths); - - if (m != null) { - this.modules.addAll(m); - } - - break; - } - } - - public Set modules() { - return modules; - } - - private static Set getModuleNamesFromPath(List Value) { - Set result = new LinkedHashSet(); - ModuleManager mm = new ModuleManager(Value); - List modules = mm.getModules(EnumSet.of(ModuleManager.SearchType.ModularJar, - ModuleManager.SearchType.Jmod, - ModuleManager.SearchType.ExplodedModule)); - - for (Module module : modules) { - result.add(module.getModuleName()); - } - - return result; - } - } -} --- old/modules/jdk.packager/src/main/java/jdk/packager/internal/Module.java 2017-08-15 12:39:03.000000000 -0700 +++ /dev/null 2017-08-15 12:39:03.000000000 -0700 @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.packager.internal; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - - -public final class Module { - private String filename; - private ModuleType moduleType; - - public enum JarType {All, UnnamedJar, ModularJar} - public enum ModuleType {Unknown, UnnamedJar, ModularJar, Jmod, ExplodedModule} - - public Module(File AFile) { - super(); - filename = AFile.getPath(); - moduleType = getModuleType(AFile); - } - - public String getModuleName() { - File file = new File(getFileName()); - return getFileWithoutExtension(file.getName()); - } - - public String getFileName() { - return filename; - } - - public ModuleType getModuleType() { - return moduleType; - } - - private static ModuleType getModuleType(File AFile) { - ModuleType result = ModuleType.Unknown; - String filename = AFile.getAbsolutePath(); - - if (AFile.isFile()) { - if (filename.endsWith(".jmod")) { - result = ModuleType.Jmod; - } - else if (filename.endsWith(".jar")) { - JarType status = isModularJar(filename); - - if (status == JarType.ModularJar) { - result = ModuleType.ModularJar; - } - else if (status == JarType.UnnamedJar) { - result = ModuleType.UnnamedJar; - } - } - } - else if (AFile.isDirectory()) { - File moduleInfo = new File(filename + File.separator + "module-info.class"); - - if (moduleInfo.exists()) { - result = ModuleType.ExplodedModule; - } - } - - return result; - } - - private static JarType isModularJar(String FileName) { - JarType result = JarType.All; - List classNames = new ArrayList(); - - try { - ZipInputStream zip = new ZipInputStream(new FileInputStream(FileName)); - result = JarType.UnnamedJar; - - try { - for (ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip.getNextEntry()) { - if (entry.getName().matches("module-info.class")) { - result = JarType.ModularJar; - break; - } - } - - zip.close(); - } catch (IOException ex) { - } - } catch (FileNotFoundException e) { - } - - return result; - } - - private static String getFileWithoutExtension(String FileName) { - return FileName.replaceFirst("[.][^.]+$", ""); - } -} --- old/modules/jdk.packager/src/main/java/jdk/packager/internal/ModuleManager.java 2017-08-15 12:39:04.000000000 -0700 +++ /dev/null 2017-08-15 12:39:04.000000000 -0700 @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.packager.internal; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumSet; -import java.util.List; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - - -public final class ModuleManager { - private List folders = new ArrayList(); - - public enum SearchType {UnnamedJar, ModularJar, Jmod, ExplodedModule} - - public ModuleManager(String folders) { - super(); - String lfolders = folders.replaceAll("^\"|\"$", ""); - List paths = new ArrayList(); - - for (String folder : Arrays.asList(lfolders.split(File.pathSeparator))) { - File file = new File(folder); - paths.add(file.toPath()); - } - - initialize(paths); - } - - public ModuleManager(List Paths) { - super(); - initialize(Paths); - } - - private void initialize(List Paths) { - for (Path path : Paths) { - folders.add(path.toString().replaceAll("^\"|\"$", "")); - } - } - - public List getModules() { - return getModules(EnumSet.of(SearchType.UnnamedJar, - SearchType.ModularJar, SearchType.Jmod, SearchType.ExplodedModule)); - } - - public List getModules(EnumSet Search) { - List result = new ArrayList(); - - for (String folder : folders) { - result.addAll(getAllModulesInDirectory(folder, Search)); - } - - return result; - } - - private static List getAllModulesInDirectory(String Folder, EnumSet Search) { - List result = new ArrayList(); - File lfolder = new File(Folder); - File[] files = lfolder.listFiles(); - - for (File file : files) { - Module module = new Module(file); - - switch (module.getModuleType()) { - case Unknown: - break; - case UnnamedJar: - if (Search.contains(SearchType.UnnamedJar)) { - result.add(module); - } - break; - case ModularJar: - if (Search.contains(SearchType.ModularJar)) { - result.add(module); - } - break; - case Jmod: - if (Search.contains(SearchType.Jmod)) { - result.add(module); - } - break; - case ExplodedModule: - if (Search.contains(SearchType.ExplodedModule)) { - result.add(module); - } - break; - } - } - - return result; - } -} \ No newline at end of file --- old/modules/jdk.packager/src/main/java/jdk/packager/internal/RedistributableModules.java 2017-08-15 12:39:04.000000000 -0700 +++ /dev/null 2017-08-15 12:39:04.000000000 -0700 @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.packager.internal; - - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; -import java.util.Optional; - -import jdk.tools.jlink.internal.packager.AppRuntimeImageBuilder; - -import java.lang.module.ModuleDescriptor; -import java.lang.module.ModuleFinder; -import java.lang.module.ModuleReference; -import java.lang.module.ModuleReader; - -import java.nio.file.Path; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Set; - - -public final class RedistributableModules { - private static final String JDK_PACKAGER_MODULE = "jdk.packager"; - private static final String LEGACY_JRE_MODULES_FILENAME = "jdk/packager/internal/resources/tools/legacy/jre.list"; - - private RedistributableModules() {} - - public static String stripComments(String line) { - String result = line.trim(); - int i = result.indexOf(";"); - - if (i >= 0) { - result = result.substring(0, i); - result = result.trim(); - } - - return result; - } - - public static Set getRedistributableModules(List modulePath) { - Set result = null; - - Set addModules = new HashSet<>(); - Set limitModules = new HashSet<>(); - ModuleFinder finder = AppRuntimeImageBuilder.moduleFinder(modulePath, addModules, limitModules); - Optional mref = finder.find(JDK_PACKAGER_MODULE); - - if (mref.isPresent()) { - ModuleReader reader = null; - - try { - reader = mref.get().open(); - } catch (NoSuchElementException | IOException ex) { - } - - if (reader != null) { - Optional stream = null; - - try { - stream = reader.open(LEGACY_JRE_MODULES_FILENAME); - } catch (IOException ex) { - } - - if (stream != null) { - if (stream.isPresent()) { - BufferedReader br = null; - - try { - br = new BufferedReader(new InputStreamReader(stream.get(), "UTF-8")); - } catch (UnsupportedEncodingException ex) { - } - - if (br != null) { - result = new LinkedHashSet(); - String line; - - try { - while ((line = br.readLine()) != null) { - String module = stripComments(line); - - if (!module.isEmpty()) { - result.add(module); - } - } - } catch (IOException ex) { - } - } - } - } - } - } - - return result; - } - - public static String getModuleVersion(File moduleFile, List modulePath, Set addModules, Set limitModules) { - String result = ""; - - Module module = new Module(moduleFile); - ModuleFinder finder = AppRuntimeImageBuilder.moduleFinder(modulePath, addModules, limitModules); - Optional mref = finder.find(module.getModuleName()); - - if (mref.isPresent()) { - ModuleDescriptor descriptor = mref.get().descriptor(); - - if (descriptor != null) { - Optional version = descriptor.version(); - - if (version.isPresent()) { - result = version.get().toString(); - } - } - } - - return result; - } -} --- old/modules/jdk.packager/src/main/java/jdk/packager/internal/mac/MacCertificate.java 2017-08-15 12:39:05.000000000 -0700 +++ /dev/null 2017-08-15 12:39:05.000000000 -0700 @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.packager.internal.mac; - -import com.oracle.tools.packager.IOUtils; -import java.io.BufferedOutputStream; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintStream; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.List; -import java.util.Locale; - -final public class MacCertificate { - private String certificate; - private boolean verbose; - - public MacCertificate(String certificate) { - this.certificate = certificate; - this.verbose = false; - } - - public MacCertificate(String certificate, boolean verbose) { - this.certificate = certificate; - this.verbose = verbose; - } - - public boolean isValid() { - return verifyCertificate(this.certificate, verbose); - } - - private static File findCertificate(String certificate, boolean verbose) { - File result = null; - - List args = new ArrayList<>(); - args.add("security"); - args.add("find-certificate"); - args.add("-c"); - args.add(certificate); - args.add("-a"); - args.add("-p"); - - try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos)) { - ProcessBuilder security = new ProcessBuilder(args); - IOUtils.exec(security, verbose, false, ps); - - File output = File.createTempFile("tempfile", ".tmp"); - PrintStream p = new PrintStream(new BufferedOutputStream(new FileOutputStream(output, true))); - BufferedReader bfReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(baos.toByteArray()))); - String line = null; - - while((line = bfReader.readLine()) != null){ - p.println(line); - } - - p.close(); - result = output; - } - catch (IOException ioe) { - } - - return result; - } - - private static Date findCertificateDate(String filename, boolean verbose) { - Date result = null; - - List args = new ArrayList<>(); - args.add("/usr/bin/openssl"); - args.add("x509"); - args.add("-noout"); - args.add("-enddate"); - args.add("-in"); - args.add(filename); - - try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos)) { - ProcessBuilder security = new ProcessBuilder(args); - IOUtils.exec(security, verbose, false, ps); - String output = baos.toString(); - output = output.substring(output.indexOf("=") + 1); - DateFormat df = new SimpleDateFormat("MMM dd kk:mm:ss yyyy z", Locale.ENGLISH); - result = df.parse(output); - } - catch (IOException ioe) { - } - catch (ParseException ex) { - } - - return result; - } - - private static boolean verifyCertificate(String certificate, boolean verbose) { - boolean result = false; - - try { - File file = null; - Date certificateDate = null; - - try { - file = findCertificate(certificate, verbose); - - if (file != null) { - certificateDate = findCertificateDate(file.getCanonicalPath(), verbose); - } - } - finally { - if (file != null) { - file.delete(); - } - } - - if (certificateDate != null) { - Calendar c = Calendar.getInstance(); - Date today = c.getTime(); - - if (certificateDate.after(today)) { - result = true; - } - } - } - catch (IOException ex) { - } - - return result; - } -} \ No newline at end of file --- old/modules/jdk.packager/src/main/java/jdk/packager/internal/windows/WindowsDefender.java 2017-08-15 12:39:06.000000000 -0700 +++ /dev/null 2017-08-15 12:39:06.000000000 -0700 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.packager.internal.windows; - -import com.oracle.tools.packager.Platform; -import java.util.List; - -public final class WindowsDefender { - - private WindowsDefender() {} - - public static final boolean isThereAPotentialWindowsDefenderIssue() { - boolean result = false; - - if (Platform.getPlatform() == Platform.WINDOWS && - Platform.getMajorVersion() == 10) { - - // If DisableRealtimeMonitoring is not enabled then there - // may be a problem. - if (!WindowsRegistry.readDisableRealtimeMonitoring() && - !isTempDirectoryInExclusionPath()) { - result = true; - } - } - - return result; - } - - private static final boolean isTempDirectoryInExclusionPath() { - boolean result = false; - // If the user temp directory is not found in the exclusion - // list then there may be a problem. - List paths = WindowsRegistry.readExclusionsPaths(); - String tempDirectory = getUserTempDirectory(); - - for (String s : paths) { - if (s.equals(tempDirectory)) { - result = true; - break; - } - } - - return result; - } - - public static final String getUserTempDirectory() { - String tempDirectory = System.getProperty("java.io.tmpdir"); - return tempDirectory; - } -} --- old/modules/jdk.packager/src/main/java/jdk/packager/internal/windows/WindowsRegistry.java 2017-08-15 12:39:07.000000000 -0700 +++ /dev/null 2017-08-15 12:39:07.000000000 -0700 @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.packager.internal.windows; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintStream; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.List; - -import static com.oracle.tools.packager.IOUtils.exec; - -public final class WindowsRegistry { - - private WindowsRegistry() {} - - /** - * Reads the registry value for DisableRealtimeMonitoring. - * @return true if DisableRealtimeMonitoring is set to 0x1, false otherwise. - */ - public static final boolean readDisableRealtimeMonitoring() { - boolean result = false; - final String key = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows Defender\\Real-Time Protection"; - final String subkey = "DisableRealtimeMonitoring"; - String value = readRegistry(key, subkey); - - if (!value.isEmpty()) { - // This code could be written better but this works. It validates - // that the result of readRegistry returned what we expect and then - // checks for a 0x0 or 0x1. 0x0 means real time monitoring is - // on, 0x1 means it is off. So this function returns true if - // real-time-monitoring is disabled. - int index = value.indexOf(subkey); - value = value.substring(index + subkey.length()); - String reg = "REG_DWORD"; - index = value.indexOf(reg); - value = value.substring(index + reg.length()); - String hex = "0x"; - index = value.indexOf(hex); - value = value.substring(index + hex.length()); - - if (value.equals("1")) { - result = true; - } - } - - return result; - } - - public static final List readExclusionsPaths() { - List result = new ArrayList(); - final String key = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows Defender\\Exclusions\\Paths"; - String value = readRegistry(key, ""); - - if (!value.isEmpty()) { - final String reg = "REG_DWORD"; - final String hex = "0x0"; - - int index = value.indexOf(key); - if (index == 0) { - value = value.substring(index + key.length()); - - while (value.length() > 0) { - index = value.indexOf(reg); - String name = value.substring(0, index); - value = value.substring(index + reg.length()); - index = value.indexOf(hex); - value = value.substring(index + hex.length()); - - if (index > 0) { - name = name.trim(); - result.add(name); - } - } - } - } - - return result; - } - /** - * @param key in the registry - * @param subkey in the registry key - * @return registry value or null if not found - */ - public static final String readRegistry(String key, String subkey){ - String result = ""; - - try { - List buildOptions = new ArrayList<>(); - buildOptions.add("reg"); - buildOptions.add("query"); - buildOptions.add("\"" + key + "\""); - - if (!subkey.isEmpty()) { - buildOptions.add("/v"); - buildOptions.add(subkey); - } - - try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos)) { - ProcessBuilder security = new ProcessBuilder(buildOptions); - exec(security, false, false, ps); - BufferedReader bfReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(baos.toByteArray()))); - String line = null; - - while((line = bfReader.readLine()) != null){ - result += line; - } - } - catch (IOException e) { - } - } - catch (Exception e) { - } - - return result; - } -} --- old/modules/jdk.packager/src/main/resources/jdk/packager/builders/AbstractAppImageBuilder.properties 2017-08-15 12:39:08.000000000 -0700 +++ /dev/null 2017-08-15 12:39:08.000000000 -0700 @@ -1,5 +0,0 @@ -message.using-default-resource=Using default package resource {0} (add {1} to the class path to customize) -message.using-custom-resource-from-file=Using custom package resource {0} (loaded from file {1}) -message.using-custom-resource-from-classpath=Using custom package resource {0} (loaded from {1}) -message.using-default-resource-from-classpath=Using default package resource {0} (add {1} to the class path to customize) -message.jvm-user-arg-is-null=WARNING\: a jvmuserarg has a null name or value. --- old/modules/jdk.packager/src/main/resources/jdk/packager/builders/AbstractAppImageBuilder_ja.properties 2017-08-15 12:39:09.000000000 -0700 +++ /dev/null 2017-08-15 12:39:09.000000000 -0700 @@ -1,5 +0,0 @@ -message.using-default-resource=\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30BD\u30FC\u30B9{0}\u306E\u4F7F\u7528({1}\u3092\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306B\u8FFD\u52A0\u3057\u3066\u30AB\u30B9\u30BF\u30DE\u30A4\u30BA) -message.using-custom-resource-from-file=\u30AB\u30B9\u30BF\u30E0\u30FB\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30BD\u30FC\u30B9{0}\u306E\u4F7F\u7528(\u30D5\u30A1\u30A4\u30EB{1}\u304B\u3089\u30ED\u30FC\u30C9\u6E08) -message.using-custom-resource-from-classpath=\u30AB\u30B9\u30BF\u30E0\u30FB\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30BD\u30FC\u30B9{0}\u306E\u4F7F\u7528({1}\u304B\u3089\u30ED\u30FC\u30C9\u6E08) -message.using-default-resource-from-classpath=\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30BD\u30FC\u30B9{0}\u306E\u4F7F\u7528({1}\u3092\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306B\u8FFD\u52A0\u3057\u3066\u30AB\u30B9\u30BF\u30DE\u30A4\u30BA) -message.jvm-user-arg-is-null=\u8B66\u544A: jvmuserarg\u306Bnull\u306E\u540D\u524D\u307E\u305F\u306F\u5024\u304C\u3042\u308A\u307E\u3059\u3002 --- old/modules/jdk.packager/src/main/resources/jdk/packager/builders/AbstractAppImageBuilder_zh_CN.properties 2017-08-15 12:39:09.000000000 -0700 +++ /dev/null 2017-08-15 12:39:09.000000000 -0700 @@ -1,5 +0,0 @@ -message.using-default-resource=\u4F7F\u7528\u9ED8\u8BA4\u7A0B\u5E8F\u5305\u8D44\u6E90 {0} (\u5C06 {1} \u6DFB\u52A0\u5230\u7C7B\u8DEF\u5F84\u4EE5\u5B9A\u5236) -message.using-custom-resource-from-file=\u4F7F\u7528\u5B9A\u5236\u7A0B\u5E8F\u5305\u8D44\u6E90 {0} (\u4ECE\u6587\u4EF6 {1} \u52A0\u8F7D) -message.using-custom-resource-from-classpath=\u4F7F\u7528\u5B9A\u5236\u7A0B\u5E8F\u5305\u8D44\u6E90 {0} (\u4ECE {1} \u52A0\u8F7D) -message.using-default-resource-from-classpath=\u4F7F\u7528\u9ED8\u8BA4\u7A0B\u5E8F\u5305\u8D44\u6E90 {0} (\u5C06 {1} \u6DFB\u52A0\u5230\u7C7B\u8DEF\u5F84\u4EE5\u5B9A\u5236) -message.jvm-user-arg-is-null=\u8B66\u544A: jvmuserarg \u7684\u540D\u79F0\u6216\u503C\u4E3A\u7A7A\u503C\u3002 --- old/modules/jdk.packager/src/main/resources/jdk/packager/builders/linux/LinuxAppImageBuilder.properties 2017-08-15 12:39:10.000000000 -0700 +++ /dev/null 2017-08-15 12:39:10.000000000 -0700 @@ -1,4 +0,0 @@ -param.icon-png.name=.png Icon -param.icon-png.description=Icon for the application, in PNG format. - -message.icon-not-png=The specified icon "{0}" is not a PNG file and will not be used. The default icon will be used in it's place. --- old/modules/jdk.packager/src/main/resources/jdk/packager/builders/linux/LinuxAppImageBuilder_ja.properties 2017-08-15 12:39:11.000000000 -0700 +++ /dev/null 2017-08-15 12:39:11.000000000 -0700 @@ -1,4 +0,0 @@ -param.icon-png.name=.png\u30A2\u30A4\u30B3\u30F3 -param.icon-png.description=PNG\u5F62\u5F0F\u3067\u306E\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u30A2\u30A4\u30B3\u30F3\u3002 - -message.icon-not-png=\u6307\u5B9A\u3057\u305F\u30A2\u30A4\u30B3\u30F3"{0}"\u306FPNG\u30D5\u30A1\u30A4\u30EB\u3067\u306F\u306A\u304F\u3001\u4F7F\u7528\u3055\u308C\u307E\u305B\u3093\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30A2\u30A4\u30B3\u30F3\u304C\u305D\u306E\u4F4D\u7F6E\u306B\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002 --- old/modules/jdk.packager/src/main/resources/jdk/packager/builders/linux/LinuxAppImageBuilder_zh_CN.properties 2017-08-15 12:39:12.000000000 -0700 +++ /dev/null 2017-08-15 12:39:12.000000000 -0700 @@ -1,4 +0,0 @@ -param.icon-png.name=.png \u56FE\u6807 -param.icon-png.description=\u5E94\u7528\u7A0B\u5E8F\u7684\u56FE\u6807, \u91C7\u7528 PNG \u683C\u5F0F\u3002 - -message.icon-not-png=\u6307\u5B9A\u7684\u56FE\u6807 "{0}" \u4E0D\u662F PNG \u6587\u4EF6, \u4E0D\u4F1A\u4F7F\u7528\u3002\u5C06\u4F7F\u7528\u9ED8\u8BA4\u56FE\u6807\u4EE3\u66FF\u3002 --- old/modules/jdk.packager/src/main/resources/jdk/packager/builders/mac/MacAppImageBuilder.properties 2017-08-15 12:39:12.000000000 -0700 +++ /dev/null 2017-08-15 12:39:13.000000000 -0700 @@ -1,73 +0,0 @@ -bundler.name=Mac Application Image -bundler.description=A Directory based image of a mac Application with an optionally co-bundled JRE. Used as a base for the Installer bundlers - -param.signing-key-developer-id-app.name=Apple Developer ID Application Signing Key -param.signing-key-developer-id-app.description=The full name of the Apple Developer ID Application signing key. - -param.icon-icns.name=.icns Icon -param.icon-icns.description= Icon for the application, in ICNS format. - -param.config-root.name= -param.config-root.description= - -param.configure-launcher-in-plist=Configure Launcher in Info.plist -param.configure-launcher-in-plist.description=Should the legacy method of configuring hte launcher in the Info.plist be used. - -param.category-name=Category -param.category-name.description=Mac App Store Categories. Note that the key is the string to display to the user and the value is the id of the category. - -param.cfbundle-name.name=CFBundleName -param.cfbundle-name.description=The name of the app as it appears in the Menu Bar. This can be different from the application name. This name should be less than 16 characters long and be suitable for displaying in the menu bar and the app's Info window. - -param.cfbundle-identifier.name=CFBundleIdentifier -param.cfbundle-identifier.description=An identifier that uniquely identifies the application for MacOSX (and on the Mac App Store). May only use alphanumeric (A-Z,a-z,0-9), hyphen (-), and period (.) characters. - -param.cfbundle-version.name=CFBundleVersion -param.cfbundle-version.description=An computer readable version for the CFBundle. May contain only digits and from zero to two dots, such as "1.8.1" or "100". - -param.bundle-id-signing-prefix.name=Bundle Signing Prefix -param.bundle-id-signing-prefix.description=When signing the application bundle this value is prefixed to all components that need to be signed that don't have an existing CFBundleIdentifier. - -param.raw-executable-url.name=Launcher URL -param.raw-executable-url.description=Override the packager default launcher with a custom launcher. - -param.default-icon-icns=Default Icon -param.default-icon-icns.description=The Default Icon for when a user does not specify an icns file. - -param.runtime.name=JRE -param.runtime.description=The Java Runtime to co-bundle. The default value is the current JRE running the bundler. A value of null will cause no JRE to be co-bundled and the system JRE will be used to launch the application. - -param.images-root.name= -param.images-root.description= - -error.cannot-create-output-dir=Output directory {0} cannot be created. -error.cannot-write-to-output-dir=Output directory {0} is not writable. -error.invalid-cfbundle-version=Invalid CFBundleVersion - ''{0}'' -error.invalid-cfbundle-version.advice=Set a compatible 'appVersion' or set a 'mac.CFBundleVersion'. Valid versions are one to three integers separated by dots. -error.explicit-sign-no-cert=Signature explicitly requested but no signing certificate specified. -error.explicit-sign-no-cert.advice=Either specify a valid cert in 'mac.signing-key-developer-id-app' or unset 'signBundle' or set 'signBundle' to false. -error.non-existent-runtime=The file for the Runtime/JRE directory does not exist. -error.non-existent-runtime.advice=Point the runtime parameter to a directory that containes the JRE. -error.cannot-detect-runtime-in-directory=Cannot determine which JRE/JDK exists in the specified runtime directory. -error.cannot-detect-runtime-in-directory.advice=Point the runtime directory to one of the JDK/JRE root, the Contents/Home directory of that root, or the Contents/Home/jre directory of the JDK. -resource.app-info-plist=Application Info.plist -resource.runtime-info-plist=Java Runtime Info.plist - -message.config-save-location=Config files are saved to {0}. Use them to customize package. -message.bundle-name-too-long-warning={0} is set to ''{1}'', which is longer than 16 characters. For a better Mac experience consider shortening it. -message.no-mac-jre-support=Currently Macs require a JDK to package -message.creating-app-bundle=Creating app bundle\: {0} -message.null-classpath=Null app resources? -message.preparing-info-plist=Preparing Info.plist\: {0} -message.icon-not-icns= The specified icon "{0}" is not an ICNS file and will not be used. The default icon will be used in it's place. -message.version-string-too-many-components=Version sting may have between 1 and 3 numbers: 1, 1.2, 1.2.3. -message.version-string-first-number-not-zero=The first number in a CFBundleVersion cannot be zero or negative. -message.version-string-no-negative-numbers=Negative numbers are not allowed in version strings. -message.version-string-numbers-only=Version strings can consist of only numbers and up to two dots. -message.creating-association-with-null-extension=Creating association with null extension. - -message.using-default-resource=Using default package resource {0} (add {1} to the class path to customize) -message.using-custom-resource-from-file=Using custom package resource {0} (loaded from file {1}) -message.using-custom-resource-from-classpath=Using custom package resource {0} (loaded from {1}) -message.using-default-resource-from-classpath=Using default package resource {0} (add {1} to the class path to customize) -message.ignoring.symlink=Warning: codesign is skipping the symlink {0} \ No newline at end of file --- old/modules/jdk.packager/src/main/resources/jdk/packager/builders/mac/MacAppImageBuilder_ja.properties 2017-08-15 12:39:13.000000000 -0700 +++ /dev/null 2017-08-15 12:39:13.000000000 -0700 @@ -1,73 +0,0 @@ -bundler.name=Mac\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30A4\u30E1\u30FC\u30B8 -bundler.description=\u30AA\u30D7\u30B7\u30E7\u30F3\u3067JRE\u304C\u30D0\u30F3\u30C9\u30EB\u3055\u308C\u3066\u3044\u308BMac\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u30FB\u30D9\u30FC\u30B9\u306E\u30A4\u30E1\u30FC\u30B8\u3002\u30A4\u30F3\u30B9\u30C8\u30FC\u30E9\u30FB\u30D0\u30F3\u30C9\u30EB\u306E\u30D9\u30FC\u30B9\u3068\u3057\u3066\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002 - -param.signing-key-developer-id-app.name=Apple Developer ID\u306E\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u7F72\u540D\u30AD\u30FC -param.signing-key-developer-id-app.description=Apple Developer ID\u306E\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u7F72\u540D\u30AD\u30FC\u306E\u30D5\u30EB\u30FB\u30CD\u30FC\u30E0\u3002 - -param.icon-icns.name=.icns\u30A2\u30A4\u30B3\u30F3 -param.icon-icns.description= ICNS\u5F62\u5F0F\u3067\u306E\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u30A2\u30A4\u30B3\u30F3\u3002 - -param.config-root.name= -param.config-root.description= - -param.configure-launcher-in-plist=Info.plist\u3067\u306E\u30E9\u30F3\u30C1\u30E3\u306E\u69CB\u6210 -param.configure-launcher-in-plist.description=Info.plist\u3067\u306E\u30E9\u30F3\u30C1\u30E3\u306E\u69CB\u6210\u306B\u306F\u30EC\u30AC\u30B7\u30FC\u30FB\u30E1\u30BD\u30C3\u30C9\u3092\u4F7F\u7528\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002 - -param.category-name=\u30AB\u30C6\u30B4\u30EA -param.category-name.description=Mac App Store\u306E\u30AB\u30C6\u30B4\u30EA\u3002\u30AD\u30FC\u306F\u30E6\u30FC\u30B6\u30FC\u306B\u8868\u793A\u3055\u308C\u308B\u6587\u5B57\u5217\u3067\u3001\u5024\u306F\u30AB\u30C6\u30B4\u30EA\u306EID\u3067\u3059\u3002 - -param.cfbundle-name.name=CFBundleName -param.cfbundle-name.description=\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u304C\u30E1\u30CB\u30E5\u30FC\u30FB\u30D0\u30FC\u306B\u8868\u793A\u3055\u308C\u308B\u969B\u306E\u540D\u524D\u3002\u3053\u308C\u306F\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u540D\u3068\u306F\u7570\u306A\u308B\u5834\u5408\u304C\u3042\u308A\u307E\u3059\u3002\u3053\u306E\u540D\u524D\u306F16\u6587\u5B57\u672A\u6E80\u3068\u3057\u3001\u30E1\u30CB\u30E5\u30FC\u30FB\u30D0\u30FC\u3068\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u60C5\u5831\u30A6\u30A3\u30F3\u30C9\u30A6\u3067\u306E\u8868\u793A\u306B\u9069\u3057\u305F\u3082\u306E\u306B\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002 - -param.cfbundle-identifier.name=CFBundleIdentifier -param.cfbundle-identifier.description=MacOSX(\u304A\u3088\u3073Mac App Store)\u306E\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u3092\u4E00\u610F\u306B\u8B58\u5225\u3059\u308B\u8B58\u5225\u5B50\u3002\u82F1\u6570\u5B57(A-Z\u3001a-z\u30010-9)\u3001\u30CF\u30A4\u30D5\u30F3(-)\u304A\u3088\u3073\u30D4\u30EA\u30AA\u30C9(.)\u306E\u307F\u3092\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002 - -param.cfbundle-version.name=CFBundleVersion -param.cfbundle-version.description=\u30B3\u30F3\u30D4\u30E5\u30FC\u30BF\u3067\u8AAD\u53D6\u308A\u53EF\u80FD\u306ACFBundle\u306E\u30D0\u30FC\u30B8\u30E7\u30F3\u3002\u6570\u5B57\u304A\u3088\u3073\u30BC\u30ED\u304B\u30892\u3064\u307E\u3067\u306E\u30C9\u30C3\u30C8\u306E\u307F\u3092\u542B\u3081\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u3059("1.8.1"\u3001"100"\u306A\u3069)\u3002 - -param.bundle-id-signing-prefix.name=\u30D0\u30F3\u30C9\u30EB\u7F72\u540D\u63A5\u982D\u8F9E -param.bundle-id-signing-prefix.description=\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30D0\u30F3\u30C9\u30EB\u306B\u7F72\u540D\u3059\u308B\u969B\u3001\u7F72\u540D\u3059\u308B\u5FC5\u8981\u306E\u3042\u308B\u3001\u65E2\u5B58\u306ECFBundleIdentifier\u3092\u6301\u305F\u306A\u3044\u3059\u3079\u3066\u306E\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8\u306B\u3053\u306E\u5024\u304C\u63A5\u982D\u8F9E\u3068\u3057\u3066\u4ED8\u3051\u3089\u308C\u307E\u3059\u3002 - -param.raw-executable-url.name=\u30E9\u30F3\u30C1\u30E3URL -param.raw-executable-url.description=\u30D1\u30C3\u30B1\u30FC\u30B8\u30E3\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30E9\u30F3\u30C1\u30E3\u3092\u30AB\u30B9\u30BF\u30E0\u30FB\u30E9\u30F3\u30C1\u30E3\u3067\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3057\u307E\u3059\u3002 - -param.default-icon-icns=\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30A2\u30A4\u30B3\u30F3 -param.default-icon-icns.description=\u30E6\u30FC\u30B6\u30FC\u304C\u30A2\u30A4\u30B3\u30F3\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u6307\u5B9A\u3057\u306A\u3044\u5834\u5408\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30A2\u30A4\u30B3\u30F3\u3002 - -param.runtime.name=JRE -param.runtime.description=\u30D0\u30F3\u30C9\u30EB\u3059\u308BJava\u30E9\u30F3\u30BF\u30A4\u30E0\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u5024\u306F\u3001\u30D0\u30F3\u30C9\u30E9\u3092\u5B9F\u884C\u3057\u3066\u3044\u308B\u73FE\u5728\u306EJRE\u3067\u3059\u3002\u5024\u304Cnull\u306E\u5834\u5408\u3001JRE\u306F\u30D0\u30F3\u30C9\u30EB\u3055\u308C\u305A\u3001\u30B7\u30B9\u30C6\u30E0\u306EJRE\u304C\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u8D77\u52D5\u306B\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002 - -param.images-root.name= -param.images-root.description= - -error.cannot-create-output-dir=\u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{0}\u3092\u4F5C\u6210\u3067\u304D\u307E\u305B\u3093\u3002 -error.cannot-write-to-output-dir=\u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{0}\u306F\u66F8\u8FBC\u307F\u4E0D\u53EF\u3067\u3059\u3002 -error.invalid-cfbundle-version=CFBundleVersion - ''{0}''\u304C\u7121\u52B9\u3067\u3059 -error.invalid-cfbundle-version.advice=\u4E92\u63DB\u6027\u306E\u3042\u308B'appVersion'\u3092\u8A2D\u5B9A\u3059\u308B\u304B\u3001'mac.CFBundleVersion'\u3092\u8A2D\u5B9A\u3057\u307E\u3059\u3002\u6709\u52B9\u306A\u30D0\u30FC\u30B8\u30E7\u30F3\u306F\u3001\u30C9\u30C3\u30C8\u3067\u533A\u5207\u3089\u308C\u305F1\u304B\u30893\u3064\u306E\u6574\u6570\u3067\u3059\u3002 -error.explicit-sign-no-cert=\u7F72\u540D\u304C\u660E\u793A\u7684\u306B\u8981\u6C42\u3055\u308C\u307E\u3057\u305F\u304C\u3001\u7F72\u540D\u8A3C\u660E\u66F8\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002 -error.explicit-sign-no-cert.advice=\u6709\u52B9\u306A\u8A3C\u660E\u66F8\u3092'mac.signing-key-developer-id-app'\u3067\u6307\u5B9A\u3059\u308B\u304B\u3001'signBundle'\u3092\u8A2D\u5B9A\u89E3\u9664\u3059\u308B\u304B\u3001\u307E\u305F\u306F'signBundle'\u3092false\u306B\u8A2D\u5B9A\u3057\u307E\u3059\u3002 -error.non-existent-runtime=\u30E9\u30F3\u30BF\u30A4\u30E0/JRE\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u30D5\u30A1\u30A4\u30EB\u304C\u5B58\u5728\u3057\u307E\u305B\u3093\u3002 -error.non-existent-runtime.advice=\u30E9\u30F3\u30BF\u30A4\u30E0\u30FB\u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u3001JRE\u3092\u542B\u3080\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002 -error.cannot-detect-runtime-in-directory=\u6307\u5B9A\u3057\u305F\u30E9\u30F3\u30BF\u30A4\u30E0\u30FB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u3069\u306EJRE/JDK\u304C\u5B58\u5728\u3059\u308B\u306E\u304B\u3092\u7279\u5B9A\u3067\u304D\u307E\u305B\u3093\u3002 -error.cannot-detect-runtime-in-directory.advice=\u30E9\u30A4\u30BF\u30A4\u30E0\u30FB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u3001JDK/JRE\u30EB\u30FC\u30C8\u3001\u305D\u306E\u30EB\u30FC\u30C8\u306E\u30B3\u30F3\u30C6\u30F3\u30C4/\u30DB\u30FC\u30E0\u30FB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3001\u307E\u305F\u306FJDK\u306E\u30B3\u30F3\u30C6\u30F3\u30C4/\u30DB\u30FC\u30E0/jre\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u3044\u305A\u308C\u304B\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002 -resource.app-info-plist=\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306EInfo.plist -resource.runtime-info-plist=Java\u30E9\u30F3\u30BF\u30A4\u30E0\u306EInfo.plist - -message.config-save-location=\u69CB\u6210\u30D5\u30A1\u30A4\u30EB\u304C{0}\u306B\u4FDD\u5B58\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u30AB\u30B9\u30BF\u30DE\u30A4\u30BA\u3059\u308B\u306B\u306F\u3053\u308C\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002 -message.bundle-name-too-long-warning={0}\u304C16\u6587\u5B57\u3092\u8D85\u3048\u308B''{1}''\u306B\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059\u3002Mac\u3067\u306E\u64CD\u4F5C\u6027\u3092\u3088\u308A\u826F\u304F\u3059\u308B\u305F\u3081\u306B\u77ED\u304F\u3059\u308B\u3053\u3068\u3092\u691C\u8A0E\u3057\u3066\u304F\u3060\u3055\u3044\u3002 -message.no-mac-jre-support=\u73FE\u5728\u3001Mac\u3067\u306FJDK\u3092\u30D1\u30C3\u30B1\u30FC\u30B8\u5316\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059 -message.creating-app-bundle=\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30D0\u30F3\u30C9\u30EB\u3092\u4F5C\u6210\u3057\u3066\u3044\u307E\u3059: {0} -message.null-classpath=Null\u306E\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30EA\u30BD\u30FC\u30B9\u3067\u3059\u304B\u3002 -message.preparing-info-plist=Info.plist\u3092\u6E96\u5099\u3057\u3066\u3044\u307E\u3059: {0} -message.icon-not-icns= \u6307\u5B9A\u3057\u305F\u30A2\u30A4\u30B3\u30F3"{0}"\u306FICNS\u30D5\u30A1\u30A4\u30EB\u3067\u306F\u306A\u304F\u3001\u4F7F\u7528\u3055\u308C\u307E\u305B\u3093\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30A2\u30A4\u30B3\u30F3\u304C\u305D\u306E\u4F4D\u7F6E\u306B\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002 -message.version-string-too-many-components=\u30D0\u30FC\u30B8\u30E7\u30F3\u6587\u5B57\u5217\u306B\u306F\u30011\u30011.2\u30011.2.3\u306A\u30691\u304B\u30893\u306E\u6570\u5B57\u3092\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002 -message.version-string-first-number-not-zero=CFBundleVersion\u306E\u6700\u521D\u306E\u6570\u5B57\u306F\u3001\u30BC\u30ED\u307E\u305F\u306F\u8CA0\u306E\u5024\u306B\u3067\u304D\u307E\u305B\u3093\u3002 -message.version-string-no-negative-numbers=\u30D0\u30FC\u30B8\u30E7\u30F3\u6587\u5B57\u5217\u306B\u8CA0\u306E\u6570\u306F\u8A31\u53EF\u3055\u308C\u307E\u305B\u3093\u3002 -message.version-string-numbers-only=\u30D0\u30FC\u30B8\u30E7\u30F3\u6587\u5B57\u5217\u306F\u3001\u6570\u5B57\u30682\u3064\u307E\u3067\u306E\u30C9\u30C3\u30C8\u3067\u306E\u307F\u69CB\u6210\u3067\u304D\u307E\u3059\u3002 -message.creating-association-with-null-extension=null\u62E1\u5F35\u5B50\u3068\u306E\u95A2\u9023\u4ED8\u3051\u3092\u4F5C\u6210\u3057\u3066\u3044\u307E\u3059\u3002 - -message.using-default-resource=\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30BD\u30FC\u30B9{0}\u306E\u4F7F\u7528({1}\u3092\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306B\u8FFD\u52A0\u3057\u3066\u30AB\u30B9\u30BF\u30DE\u30A4\u30BA) -message.using-custom-resource-from-file=\u30AB\u30B9\u30BF\u30E0\u30FB\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30BD\u30FC\u30B9{0}\u306E\u4F7F\u7528(\u30D5\u30A1\u30A4\u30EB{1}\u304B\u3089\u30ED\u30FC\u30C9\u6E08) -message.using-custom-resource-from-classpath=\u30AB\u30B9\u30BF\u30E0\u30FB\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30BD\u30FC\u30B9{0}\u306E\u4F7F\u7528({1}\u304B\u3089\u30ED\u30FC\u30C9\u6E08) -message.using-default-resource-from-classpath=\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30BD\u30FC\u30B9{0}\u306E\u4F7F\u7528({1}\u3092\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306B\u8FFD\u52A0\u3057\u3066\u30AB\u30B9\u30BF\u30DE\u30A4\u30BA) -message.ignoring.symlink=\u8B66\u544A: codesign\u304Csymlink {0}\u3092\u30B9\u30AD\u30C3\u30D7\u3057\u3066\u3044\u307E\u3059 --- old/modules/jdk.packager/src/main/resources/jdk/packager/builders/mac/MacAppImageBuilder_zh_CN.properties 2017-08-15 12:39:14.000000000 -0700 +++ /dev/null 2017-08-15 12:39:14.000000000 -0700 @@ -1,73 +0,0 @@ -bundler.name=Mac \u5E94\u7528\u7A0B\u5E8F\u6620\u50CF -bundler.description=\u4E00\u4E2A\u57FA\u4E8E\u76EE\u5F55\u7684 mac \u5E94\u7528\u7A0B\u5E8F\u6620\u50CF, \u53EF\u4EE5\u9009\u62E9\u6027\u5730\u5E26\u6709\u5171\u540C\u6253\u5305\u7684 JRE\u3002\u7528\u4F5C\u5B89\u88C5\u7A0B\u5E8F\u6253\u5305\u7A0B\u5E8F\u7684\u57FA\u7840 - -param.signing-key-developer-id-app.name=Apple \u5F00\u53D1\u8005 ID \u5E94\u7528\u7A0B\u5E8F\u7B7E\u540D\u5BC6\u94A5 -param.signing-key-developer-id-app.description=Apple \u5F00\u53D1\u8005 ID \u5E94\u7528\u7A0B\u5E8F\u7B7E\u540D\u5BC6\u94A5\u7684\u5168\u540D\u3002 - -param.icon-icns.name=.icns \u56FE\u6807 -param.icon-icns.description= \u5E94\u7528\u7A0B\u5E8F\u7684\u56FE\u6807, \u91C7\u7528 ICNS \u683C\u5F0F\u3002 - -param.config-root.name= -param.config-root.description= - -param.configure-launcher-in-plist=\u5728 Info.plist \u4E2D\u914D\u7F6E\u542F\u52A8\u7A0B\u5E8F -param.configure-launcher-in-plist.description=\u662F\u5426\u5E94\u4F7F\u7528\u5728 Info.plist \u4E2D\u914D\u7F6E\u542F\u52A8\u7A0B\u5E8F\u7684\u65E7\u65B9\u6CD5\u3002 - -param.category-name=\u7C7B\u522B -param.category-name.description=Mac App Store \u7C7B\u522B\u3002\u8BF7\u6CE8\u610F, \u952E\u662F\u5411\u7528\u6237\u663E\u793A\u7684\u5B57\u7B26\u4E32, \u503C\u662F\u7C7B\u522B\u7684 ID\u3002 - -param.cfbundle-name.name=CFBundleName -param.cfbundle-name.description=\u5E94\u7528\u7A0B\u5E8F\u5728\u83DC\u5355\u680F\u4E2D\u7684\u663E\u793A\u540D\u79F0\u3002\u53EF\u4EE5\u4E0E\u5E94\u7528\u7A0B\u5E8F\u540D\u79F0\u4E0D\u540C\u3002\u6B64\u540D\u79F0\u7684\u957F\u5EA6\u5E94\u5C11\u4E8E 16 \u4E2A\u5B57\u7B26, \u5E76\u4E14\u5E94\u9002\u5408\u5728\u83DC\u5355\u680F\u548C\u5E94\u7528\u7A0B\u5E8F\u7684\u201C\u4FE1\u606F\u201D\u7A97\u53E3\u4E2D\u663E\u793A\u3002 - -param.cfbundle-identifier.name=CFBundleIdentifier -param.cfbundle-identifier.description=\u552F\u4E00\u6807\u8BC6 MacOSX \u5E94\u7528\u7A0B\u5E8F (\u5728 Mac App Store \u4E0A) \u7684\u6807\u8BC6\u7B26\u3002\u53EA\u80FD\u4F7F\u7528\u5B57\u6BCD\u6570\u5B57 (A-Z,a-z,0-9), \u8FDE\u5B57\u7B26 (-) \u548C\u53E5\u70B9 (.) \u5B57\u7B26\u3002 - -param.cfbundle-version.name=CFBundleVersion -param.cfbundle-version.description=CFBundle \u7684\u8BA1\u7B97\u673A\u53EF\u8BFB\u7248\u672C\u3002\u53EA\u80FD\u5305\u542B\u6570\u5B57\u4EE5\u53CA\u96F6\u5230\u4E24\u4E2A\u70B9, \u4F8B\u5982 "1.8.1" \u6216 "100"\u3002 - -param.bundle-id-signing-prefix.name=\u5305\u7B7E\u540D\u524D\u7F00 -param.bundle-id-signing-prefix.description=\u5BF9\u5E94\u7528\u7A0B\u5E8F\u5305\u8FDB\u884C\u7B7E\u540D\u65F6, \u6B64\u503C\u5C06\u4F5C\u4E3A\u524D\u7F00\u6DFB\u52A0\u5230\u9700\u8981\u7B7E\u540D\u4F46\u4E0D\u5177\u6709\u73B0\u6709 CFBundleIdentifier \u7684\u6240\u6709\u7EC4\u4EF6\u4E2D\u3002 - -param.raw-executable-url.name=\u542F\u52A8\u7A0B\u5E8F URL -param.raw-executable-url.description=\u4F7F\u7528\u5B9A\u5236\u542F\u52A8\u7A0B\u5E8F\u8986\u76D6\u6253\u5305\u7A0B\u5E8F\u9ED8\u8BA4\u542F\u52A8\u7A0B\u5E8F\u3002 - -param.default-icon-icns=\u9ED8\u8BA4\u56FE\u6807 -param.default-icon-icns.description=\u7528\u6237\u672A\u6307\u5B9A icns \u6587\u4EF6\u65F6\u4F7F\u7528\u7684\u9ED8\u8BA4\u56FE\u6807\u3002 - -param.runtime.name=JRE -param.runtime.description=\u8981\u5171\u540C\u6253\u5305\u7684 Java \u8FD0\u884C\u65F6\u3002\u9ED8\u8BA4\u503C\u4E3A\u8FD0\u884C\u6253\u5305\u7A0B\u5E8F\u7684\u5F53\u524D JRE\u3002\u503C\u4E3A\u7A7A\u503C\u5C06\u5BFC\u81F4\u4E0D\u4F1A\u5171\u540C\u6253\u5305\u4EFB\u4F55 JRE, \u5E76\u4E14\u5C06\u4F7F\u7528\u7CFB\u7EDF JRE \u6765\u542F\u52A8\u5E94\u7528\u7A0B\u5E8F\u3002 - -param.images-root.name= -param.images-root.description= - -error.cannot-create-output-dir=\u65E0\u6CD5\u521B\u5EFA\u8F93\u51FA\u76EE\u5F55 {0}\u3002 -error.cannot-write-to-output-dir=\u8F93\u51FA\u76EE\u5F55 {0} \u4E0D\u53EF\u5199\u3002 -error.invalid-cfbundle-version=\u65E0\u6548\u7684 CFBundleVersion - ''{0}'' -error.invalid-cfbundle-version.advice=\u8BBE\u7F6E\u517C\u5BB9\u7684 'appVersion' \u6216\u8005\u8BBE\u7F6E 'mac.CFBundleVersion'\u3002\u6709\u6548\u7248\u672C\u5305\u542B\u4E00\u5230\u4E09\u4E2A\u7528\u70B9\u5206\u9694\u7684\u6574\u6570\u3002 -error.explicit-sign-no-cert=\u5DF2\u660E\u786E\u8BF7\u6C42\u7B7E\u540D, \u4F46\u672A\u6307\u5B9A\u7B7E\u540D\u8BC1\u4E66\u3002 -error.explicit-sign-no-cert.advice=\u5728 'mac.signing-key-developer-id-app' \u4E2D\u6307\u5B9A\u6709\u6548\u7684\u8BC1\u4E66, \u6216\u8005\u53D6\u6D88\u8BBE\u7F6E 'signBundle', \u6216\u8005\u5C06 'signBundle' \u8BBE\u7F6E\u4E3A\u201C\u5047\u201D\u3002 -error.non-existent-runtime=\u8FD0\u884C\u65F6/JRE \u76EE\u5F55\u7684\u6587\u4EF6\u4E0D\u5B58\u5728\u3002 -error.non-existent-runtime.advice=\u5C06\u8FD0\u884C\u65F6\u53C2\u6570\u6307\u5411\u5305\u542B JRE \u7684\u76EE\u5F55\u3002 -error.cannot-detect-runtime-in-directory=\u65E0\u6CD5\u786E\u5B9A\u6307\u5B9A\u7684\u8FD0\u884C\u65F6\u76EE\u5F55\u4E2D\u5B58\u5728\u54EA\u4E2A\u7248\u672C\u7684 JRE/JDK\u3002 -error.cannot-detect-runtime-in-directory.advice=\u5C06\u8FD0\u884C\u65F6\u76EE\u5F55\u6307\u5411\u4EE5\u4E0B\u76EE\u5F55\u4E4B\u4E00: JDK/JRE \u6839\u76EE\u5F55, \u8BE5\u6839\u76EE\u5F55\u7684 Contents/Home \u76EE\u5F55\u6216 JDK \u7684 Contents/Home/jre \u76EE\u5F55\u3002 -resource.app-info-plist=\u5E94\u7528\u7A0B\u5E8F Info.plist -resource.runtime-info-plist=Java \u8FD0\u884C\u65F6 Info.plist - -message.config-save-location=\u914D\u7F6E\u6587\u4EF6\u5DF2\u4FDD\u5B58\u5230 {0}\u3002\u4F7F\u7528\u8FD9\u4E9B\u914D\u7F6E\u6587\u4EF6\u53EF\u5B9A\u5236\u7A0B\u5E8F\u5305\u3002 -message.bundle-name-too-long-warning={0}\u5DF2\u8BBE\u7F6E\u4E3A ''{1}'', \u5176\u957F\u5EA6\u8D85\u8FC7\u4E86 16 \u4E2A\u5B57\u7B26\u3002\u4E3A\u4E86\u83B7\u5F97\u66F4\u597D\u7684 Mac \u4F53\u9A8C, \u8BF7\u8003\u8651\u5C06\u5176\u7F29\u77ED\u3002 -message.no-mac-jre-support=Mac \u5F53\u524D\u9700\u8981 JDK \u4EE5\u4FBF\u6253\u5305 -message.creating-app-bundle=\u6B63\u5728\u521B\u5EFA\u5E94\u7528\u7A0B\u5E8F\u5305: {0} -message.null-classpath=\u662F\u5426\u4E3A\u7A7A\u5E94\u7528\u7A0B\u5E8F\u8D44\u6E90? -message.preparing-info-plist=\u6B63\u5728\u51C6\u5907 Info.plist: {0} -message.icon-not-icns= \u6307\u5B9A\u7684\u56FE\u6807 "{0}" \u4E0D\u662F ICNS \u6587\u4EF6, \u4E0D\u4F1A\u4F7F\u7528\u3002\u5C06\u4F7F\u7528\u9ED8\u8BA4\u56FE\u6807\u4EE3\u66FF\u3002 -message.version-string-too-many-components=\u7248\u672C\u5B57\u7B26\u4E32\u53EF\u4EE5\u5305\u542B 1 \u5230 3 \u4E2A\u6570\u5B57: 1, 1.2, 1.2.3\u3002 -message.version-string-first-number-not-zero=CFBundleVersion \u4E2D\u7684\u7B2C\u4E00\u4E2A\u6570\u5B57\u4E0D\u80FD\u4E3A\u96F6\u6216\u8D1F\u6570\u3002 -message.version-string-no-negative-numbers=\u7248\u672C\u5B57\u7B26\u4E32\u4E2D\u4E0D\u5141\u8BB8\u4F7F\u7528\u8D1F\u6570\u3002 -message.version-string-numbers-only=\u7248\u672C\u5B57\u7B26\u4E32\u53EA\u80FD\u5305\u542B\u6570\u5B57\u548C\u6700\u591A\u4E24\u4E2A\u70B9\u3002 -message.creating-association-with-null-extension=\u6B63\u5728\u4F7F\u7528\u7A7A\u6269\u5C55\u540D\u521B\u5EFA\u5173\u8054\u3002 - -message.using-default-resource=\u4F7F\u7528\u9ED8\u8BA4\u7A0B\u5E8F\u5305\u8D44\u6E90 {0} (\u5C06 {1} \u6DFB\u52A0\u5230\u7C7B\u8DEF\u5F84\u4EE5\u5B9A\u5236) -message.using-custom-resource-from-file=\u4F7F\u7528\u5B9A\u5236\u7A0B\u5E8F\u5305\u8D44\u6E90 {0} (\u4ECE\u6587\u4EF6 {1} \u52A0\u8F7D) -message.using-custom-resource-from-classpath=\u4F7F\u7528\u5B9A\u5236\u7A0B\u5E8F\u5305\u8D44\u6E90 {0} (\u4ECE {1} \u52A0\u8F7D) -message.using-default-resource-from-classpath=\u4F7F\u7528\u9ED8\u8BA4\u7A0B\u5E8F\u5305\u8D44\u6E90 {0} (\u5C06 {1} \u6DFB\u52A0\u5230\u7C7B\u8DEF\u5F84\u4EE5\u5B9A\u5236) -message.ignoring.symlink=\u8B66\u544A: codesign \u6B63\u5728\u8DF3\u8FC7\u7B26\u53F7\u94FE\u63A5 {0} --- old/modules/jdk.packager/src/main/resources/jdk/packager/builders/windows/WindowsAppImageBuilder.properties 2017-08-15 12:39:15.000000000 -0700 +++ /dev/null 2017-08-15 12:39:15.000000000 -0700 @@ -1,16 +0,0 @@ -param.rebrand-executable.name = Rebrand Launcher -param.rebrand-executable.description = Update the launcher with the application icon and update ownership information. - -param.icon-ico.name=.ico Icon -param.icon-ico.description=Icon for the application, in ICO format. - -param.config-root.name= -param.config-root.description= - -error.cannot-create-output-dir=Output directory {0} cannot be created. -error.cannot-write-to-output-dir=Output directory {0} is not writable. - -message.config-save-location=Config files are saved to {0}. Use them to customize package. -message.potential.windows.defender.issue=Warning: Windows Defender may prevent the Java Packager from functioning. If there is an issue, it can be addressed by either disabling realtime monitoring, or adding an exclusion for the directory "{0}". - -resource.executable-properties-template=Template for creating executable properties file. \ No newline at end of file --- old/modules/jdk.packager/src/main/resources/jdk/packager/builders/windows/WindowsAppImageBuilder_ja.properties 2017-08-15 12:39:16.000000000 -0700 +++ /dev/null 2017-08-15 12:39:16.000000000 -0700 @@ -1,16 +0,0 @@ -param.rebrand-executable.name = \u30E9\u30F3\u30C1\u30E3\u306E\u30EA\u30D6\u30E9\u30F3\u30C9 -param.rebrand-executable.description = \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30A2\u30A4\u30B3\u30F3\u3092\u542B\u3080\u30E9\u30F3\u30C1\u30E3\u304A\u3088\u3073\u6240\u6709\u8005\u60C5\u5831\u3092\u66F4\u65B0\u3057\u307E\u3059\u3002 - -param.icon-ico.name=.ico\u30A2\u30A4\u30B3\u30F3 -param.icon-ico.description=ICO\u5F62\u5F0F\u3067\u306E\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u30A2\u30A4\u30B3\u30F3\u3002 - -param.config-root.name= -param.config-root.description= - -error.cannot-create-output-dir=\u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{0}\u3092\u4F5C\u6210\u3067\u304D\u307E\u305B\u3093\u3002 -error.cannot-write-to-output-dir=\u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{0}\u306F\u66F8\u8FBC\u307F\u4E0D\u53EF\u3067\u3059\u3002 - -message.config-save-location=\u69CB\u6210\u30D5\u30A1\u30A4\u30EB\u304C{0}\u306B\u4FDD\u5B58\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u30AB\u30B9\u30BF\u30DE\u30A4\u30BA\u3059\u308B\u306B\u306F\u3053\u308C\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002 -message.potential.windows.defender.issue=\u8B66\u544A: Windows Defender\u304C\u539F\u56E0\u3067Java\u30D1\u30C3\u30B1\u30FC\u30B8\u30E3\u304C\u6A5F\u80FD\u3057\u306A\u3044\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002\u554F\u984C\u304C\u767A\u751F\u3057\u305F\u5834\u5408\u306F\u3001\u30EA\u30A2\u30EB\u30BF\u30A4\u30E0\u30FB\u30E2\u30CB\u30BF\u30EA\u30F3\u30B0\u3092\u7121\u52B9\u306B\u3059\u308B\u304B\u3001\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA"{0}"\u306E\u9664\u5916\u3092\u8FFD\u52A0\u3059\u308B\u3053\u3068\u306B\u3088\u308A\u3001\u554F\u984C\u306B\u5BFE\u51E6\u3067\u304D\u307E\u3059\u3002 - -resource.executable-properties-template=\u5B9F\u884C\u53EF\u80FD\u306A\u30D7\u30ED\u30D1\u30C6\u30A3\u30FB\u30D5\u30A1\u30A4\u30EB\u4F5C\u6210\u7528\u306E\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u3002 --- old/modules/jdk.packager/src/main/resources/jdk/packager/builders/windows/WindowsAppImageBuilder_zh_CN.properties 2017-08-15 12:39:17.000000000 -0700 +++ /dev/null 2017-08-15 12:39:17.000000000 -0700 @@ -1,16 +0,0 @@ -param.rebrand-executable.name = \u66F4\u6539\u542F\u52A8\u7A0B\u5E8F\u54C1\u724C -param.rebrand-executable.description = \u4F7F\u7528\u5E94\u7528\u7A0B\u5E8F\u56FE\u6807\u66F4\u65B0\u542F\u52A8\u7A0B\u5E8F\u5E76\u66F4\u65B0\u6240\u6709\u6743\u4FE1\u606F\u3002 - -param.icon-ico.name=.ico \u56FE\u6807 -param.icon-ico.description=\u5E94\u7528\u7A0B\u5E8F\u7684\u56FE\u6807, \u91C7\u7528 ICO \u683C\u5F0F\u3002 - -param.config-root.name= -param.config-root.description= - -error.cannot-create-output-dir=\u65E0\u6CD5\u521B\u5EFA\u8F93\u51FA\u76EE\u5F55 {0}\u3002 -error.cannot-write-to-output-dir=\u8F93\u51FA\u76EE\u5F55 {0} \u4E0D\u53EF\u5199\u3002 - -message.config-save-location=\u914D\u7F6E\u6587\u4EF6\u5DF2\u4FDD\u5B58\u5230 {0}\u3002\u4F7F\u7528\u8FD9\u4E9B\u914D\u7F6E\u6587\u4EF6\u53EF\u5B9A\u5236\u7A0B\u5E8F\u5305\u3002 -message.potential.windows.defender.issue=\u8B66\u544A: Windows Defender \u53EF\u80FD\u4F1A\u963B\u6B62 Java \u6253\u5305\u7A0B\u5E8F\u6B63\u5E38\u5DE5\u4F5C\u3002\u5982\u679C\u5B58\u5728\u95EE\u9898, \u53EF\u4EE5\u901A\u8FC7\u7981\u7528\u5B9E\u65F6\u76D1\u89C6\u6216\u8005\u4E3A\u76EE\u5F55 "{0}" \u6DFB\u52A0\u6392\u9664\u9879\u8FDB\u884C\u89E3\u51B3\u3002 - -resource.executable-properties-template=\u7528\u4E8E\u521B\u5EFA\u53EF\u6267\u884C\u5C5E\u6027\u6587\u4EF6\u7684\u6A21\u677F\u3002 --- old/modules/jdk.packager/src/main/resources/jdk/packager/internal/JLinkBundlerHelper.properties 2017-08-15 12:39:18.000000000 -0700 +++ /dev/null 2017-08-15 12:39:18.000000000 -0700 @@ -1,17 +0,0 @@ -param.detect-modules.name=Auto Modules -param.detect-modules.description=Automatically calculate modules to Limit JImage creation to. - -param.jlink-options.name=JLink Options -param.jlink-options.description=Options to be added to JLink invocation. - -param.jlink-builder.name=JLink Builder -param.jlink-builder.description=Name of the JLink Builder to build the applicaiton image with. - -error.srcfiles.contain.modules=Error: Modules are not allowed in srcfiles: {0}. - -warning.module.does.not.exist=Module {0} does not exist. - -message.detected.modules="Automatically adding detected modules: {0}." -message.modules="Adding modules: {0} to runtime image." - -using.experimental.feature="Using experimental feature: {0}." \ No newline at end of file --- old/modules/jdk.packager/src/main/resources/jdk/packager/internal/JLinkBundlerHelper_ja.properties 2017-08-15 12:39:18.000000000 -0700 +++ /dev/null 2017-08-15 12:39:18.000000000 -0700 @@ -1,17 +0,0 @@ -param.detect-modules.name=\u81EA\u52D5\u30E2\u30B8\u30E5\u30FC\u30EB -param.detect-modules.description=JImage\u306E\u4F5C\u6210\u3092\u5236\u9650\u3059\u308B\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u81EA\u52D5\u7684\u306B\u8A08\u7B97\u3057\u307E\u3059\u3002 - -param.jlink-options.name=JLink\u30AA\u30D7\u30B7\u30E7\u30F3 -param.jlink-options.description=JLink\u306E\u8D77\u52D5\u306B\u8FFD\u52A0\u3055\u308C\u308B\u30AA\u30D7\u30B7\u30E7\u30F3 - -param.jlink-builder.name=JLink\u30D3\u30EB\u30C0\u30FC -param.jlink-builder.description=\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u30FB\u30A4\u30E1\u30FC\u30B8\u3092\u4F5C\u6210\u3059\u308BJLink\u30D3\u30EB\u30C0\u30FC\u306E\u540D\u524D - -error.srcfiles.contain.modules=\u30A8\u30E9\u30FC: \u30E2\u30B8\u30E5\u30FC\u30EB\u306Fsrcfiles\u3067\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093: {0}\u3002 - -warning.module.does.not.exist=\u30E2\u30B8\u30E5\u30FC\u30EB{0}\u306F\u5B58\u5728\u3057\u307E\u305B\u3093\u3002 - -message.detected.modules="\u691C\u51FA\u3055\u308C\u305F\u30E2\u30B8\u30E5\u30FC\u30EB\u3092\u81EA\u52D5\u7684\u306B\u8FFD\u52A0\u3057\u3066\u3044\u307E\u3059: {0}." -message.modules="\u30E2\u30B8\u30E5\u30FC\u30EB: {0}\u3092\u30E9\u30F3\u30BF\u30A4\u30E0\u30FB\u30A4\u30E1\u30FC\u30B8\u306B\u8FFD\u52A0\u3057\u3066\u3044\u307E\u3059\u3002" - -using.experimental.feature="\u8A66\u9A13\u7684\u306A\u6A5F\u80FD\u3092\u4F7F\u7528\u3057\u3066\u3044\u307E\u3059: {0}\u3002" --- old/modules/jdk.packager/src/main/resources/jdk/packager/internal/JLinkBundlerHelper_zh_CN.properties 2017-08-15 12:39:19.000000000 -0700 +++ /dev/null 2017-08-15 12:39:19.000000000 -0700 @@ -1,17 +0,0 @@ -param.detect-modules.name=\u81EA\u52A8\u6A21\u5757 -param.detect-modules.description=\u81EA\u52A8\u8BA1\u7B97\u6A21\u5757\u4EE5\u5C06 JImage \u521B\u5EFA\u64CD\u4F5C\u9650\u5236\u4E3A\u8FD9\u4E9B\u6A21\u5757\u3002 - -param.jlink-options.name=JLink \u9009\u9879 -param.jlink-options.description=\u8981\u6DFB\u52A0\u5230 JLink \u8C03\u7528\u7684\u9009\u9879\u3002 - -param.jlink-builder.name=JLink Builder -param.jlink-builder.description=\u7528\u4E8E\u6784\u5EFA\u5E94\u7528\u7A0B\u5E8F\u6620\u50CF\u7684 JLink Builder \u7684\u540D\u79F0\u3002 - -error.srcfiles.contain.modules=\u9519\u8BEF: srcfile \u4E2D\u4E0D\u5141\u8BB8\u6A21\u5757: {0}\u3002 - -warning.module.does.not.exist=\u6A21\u5757 {0} \u4E0D\u5B58\u5728\u3002 - -message.detected.modules="\u6B63\u5728\u81EA\u52A8\u6DFB\u52A0\u68C0\u6D4B\u5230\u7684\u6A21\u5757: {0}\u3002" -message.modules="\u6B63\u5728\u5C06\u6A21\u5757 {0} \u6DFB\u52A0\u5230\u8FD0\u884C\u65F6\u6620\u50CF\u3002" - -using.experimental.feature="\u6B63\u5728\u4F7F\u7528\u8BD5\u9A8C\u529F\u80FD: {0}\u3002"