< prev index next >

src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WindowsAppImageBuilder.java

Print this page

        

*** 21,31 **** * 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.jpackage.internal; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; --- 21,31 ---- * 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.incubator.jpackage.internal; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream;
*** 48,85 **** 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 jdk.jpackage.internal.StandardBundlerParam.*; public class WindowsAppImageBuilder extends AbstractAppImageBuilder { static { System.loadLibrary("jpackage"); } private static final ResourceBundle I18N = ResourceBundle.getBundle( ! "jdk.jpackage.internal.resources.WinResources"); private final static String LIBRARY_NAME = "applauncher.dll"; 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.template"; private final Path root; private final Path appDir; private final Path appModsDir; private final Path runtimeDir; private final Path mdir; ! ! private final Map<String, ? super Object> params; public static final BundlerParamInfo<Boolean> REBRAND_EXECUTABLE = new WindowsBundlerParam<>( "win.launcher.rebrand", Boolean.class, --- 48,85 ---- 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 jdk.incubator.jpackage.internal.OverridableResource.createResource; ! import static jdk.incubator.jpackage.internal.StandardBundlerParam.*; public class WindowsAppImageBuilder extends AbstractAppImageBuilder { static { System.loadLibrary("jpackage"); } private static final ResourceBundle I18N = ResourceBundle.getBundle( ! "jdk.incubator.jpackage.internal.resources.WinResources"); private final static String LIBRARY_NAME = "applauncher.dll"; 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 ="java48.ico"; private static final String EXECUTABLE_PROPERTIES_TEMPLATE = "WinLauncher.template"; private final Path root; private final Path appDir; private final Path appModsDir; private final Path runtimeDir; private final Path mdir; ! private final Path binDir; public static final BundlerParamInfo<Boolean> REBRAND_EXECUTABLE = new WindowsBundlerParam<>( "win.launcher.rebrand", Boolean.class,
*** 109,205 **** // valueOf(null) is false, // and we actually do want null in some cases (s, p) -> (s == null || "null".equalsIgnoreCase(s)) ? true : Boolean.valueOf(s)); ! public WindowsAppImageBuilder(Map<String, Object> 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.appModsDir = appDir.resolve("mods"); this.runtimeDir = root.resolve("runtime"); this.mdir = runtimeDir.resolve("lib"); Files.createDirectories(appDir); Files.createDirectories(runtimeDir); } - public WindowsAppImageBuilder(String jreName, Path imageOutDir) - throws IOException { - super(null, imageOutDir.resolve(jreName)); - - Objects.requireNonNull(imageOutDir); - - this.params = null; - this.root = imageOutDir.resolve(jreName); - this.appDir = null; - this.appModsDir = null; - this.runtimeDir = root; - this.mdir = runtimeDir.resolve("lib"); - 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<PosixFilePermission> 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); ! } ! } ! ! public static String getLauncherName(Map<String, ? super Object> p) { ! return APP_NAME.fetchFrom(p) + ".exe"; } // Returns launcher resource name for launcher we need to use. public static String getLauncherResourceName( ! Map<String, ? super Object> p) { ! if (CONSOLE_HINT.fetchFrom(p)) { return "jpackageapplauncher.exe"; } else { return "jpackageapplauncherw.exe"; } } ! public static String getLauncherCfgName(Map<String, ? super Object> p) { ! return "app/" + APP_NAME.fetchFrom(p) +".cfg"; } private File getConfig_AppIcon(Map<String, ? super Object> params) { return new File(getConfigRoot(params), APP_NAME.fetchFrom(params) + ".ico"); --- 109,157 ---- // valueOf(null) is false, // and we actually do want null in some cases (s, p) -> (s == null || "null".equalsIgnoreCase(s)) ? true : Boolean.valueOf(s)); ! public WindowsAppImageBuilder(Map<String, Object> params, Path imageOutDir) throws IOException { ! super(params, ! imageOutDir.resolve(APP_NAME.fetchFrom(params) + "/runtime")); Objects.requireNonNull(imageOutDir); this.root = imageOutDir.resolve(APP_NAME.fetchFrom(params)); this.appDir = root.resolve("app"); this.appModsDir = appDir.resolve("mods"); this.runtimeDir = root.resolve("runtime"); this.mdir = runtimeDir.resolve("lib"); + this.binDir = root; Files.createDirectories(appDir); Files.createDirectories(runtimeDir); } private void writeEntry(InputStream in, Path dstFile) throws IOException { Files.createDirectories(dstFile.getParent()); Files.copy(in, dstFile); } ! private static String getLauncherName(Map<String, ? super Object> params) { ! return APP_NAME.fetchFrom(params) + ".exe"; } // Returns launcher resource name for launcher we need to use. public static String getLauncherResourceName( ! Map<String, ? super Object> params) { ! if (CONSOLE_HINT.fetchFrom(params)) { return "jpackageapplauncher.exe"; } else { return "jpackageapplauncherw.exe"; } } ! public static String getLauncherCfgName( ! Map<String, ? super Object> params) { ! return "app/" + APP_NAME.fetchFrom(params) +".cfg"; } private File getConfig_AppIcon(Map<String, ? super Object> params) { return new File(getConfigRoot(params), APP_NAME.fetchFrom(params) + ".ico");
*** 224,254 **** public Path getAppModsDir() { return appModsDir; } @Override ! public void prepareApplicationFiles() throws IOException { Map<String, ? super Object> 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())); } // create the .exe launchers createLauncherForEntryPoint(params); // copy the jars copyApplication(params); // copy in the needed libraries try (InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) { ! Files.copy(is_lib, root.resolve(LIBRARY_NAME)); } copyMSVCDLLs(); // create the additional launcher(s), if any --- 176,206 ---- public Path getAppModsDir() { return appModsDir; } @Override ! public void prepareApplicationFiles(Map<String, ? super Object> params) ! throws IOException { Map<String, ? super Object> originalParams = new HashMap<>(params); ! ! try { ! IOUtils.writableOutputDir(root); ! IOUtils.writableOutputDir(binDir); ! } catch (PackagerException pe) { ! throw new RuntimeException(pe); } + AppImageFile.save(root, params); + // create the .exe launchers createLauncherForEntryPoint(params); // copy the jars copyApplication(params); // copy in the needed libraries try (InputStream is_lib = getResourceAsStream(LIBRARY_NAME)) { ! Files.copy(is_lib, binDir.resolve(LIBRARY_NAME)); } copyMSVCDLLs(); // create the additional launcher(s), if any
*** 259,279 **** AddLauncherArguments.merge(originalParams, entryPoint)); } } @Override ! public void prepareJreFiles() throws IOException {} private void copyMSVCDLLs() throws IOException { AtomicReference<IOException> ioe = new AtomicReference<>(); try (Stream<Path> files = Files.list(runtimeDir.resolve("bin"))) { files.filter(p -> Pattern.matches( "^(vcruntime|msvcp|msvcr|ucrtbase|api-ms-win-).*\\.dll$", p.toFile().getName().toLowerCase())) .forEach(p -> { try { ! Files.copy(p, root.resolve((p.toFile().getName()))); } catch (IOException e) { ioe.set(e); } }); } --- 211,232 ---- AddLauncherArguments.merge(originalParams, entryPoint)); } } @Override ! public void prepareJreFiles(Map<String, ? super Object> params) ! throws IOException {} private void copyMSVCDLLs() throws IOException { AtomicReference<IOException> ioe = new AtomicReference<>(); try (Stream<Path> files = Files.list(runtimeDir.resolve("bin"))) { files.filter(p -> Pattern.matches( "^(vcruntime|msvcp|msvcr|ucrtbase|api-ms-win-).*\\.dll$", p.toFile().getName().toLowerCase())) .forEach(p -> { try { ! Files.copy(p, binDir.resolve((p.toFile().getName()))); } catch (IOException e) { ioe.set(e); } }); }
*** 282,311 **** if (e != null) { throw e; } } - // TODO: do we still need this? - private boolean copyMSVCDLLs(String VS_VER) throws IOException { - final InputStream REDIST_MSVCR_URL = getResourceAsStream( - REDIST_MSVCR.replaceAll("VS_VER", VS_VER)); - final InputStream REDIST_MSVCP_URL = 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; - } - private void validateValueAndPut( Map<String, String> data, String key, BundlerParamInfo<String> param, Map<String, ? super Object> params) { String value = param.fetchFrom(params); --- 235,244 ----
*** 318,327 **** --- 251,261 ---- data.put(key, value); } protected void prepareExecutableProperties( Map<String, ? super Object> params) throws IOException { + Map<String, String> data = new HashMap<>(); // mapping Java parameters in strings for version resource validateValueAndPut(data, "COMPANY_NAME", VENDOR, params); validateValueAndPut(data, "FILE_DESCRIPTION", DESCRIPTION, params);
*** 330,396 **** validateValueAndPut(data, "LEGAL_COPYRIGHT", COPYRIGHT, params); data.put("ORIGINAL_FILENAME", getLauncherName(params)); validateValueAndPut(data, "PRODUCT_NAME", APP_NAME, params); validateValueAndPut(data, "PRODUCT_VERSION", VERSION, params); ! try (Writer w = Files.newBufferedWriter( ! getConfig_ExecutableProperties(params).toPath(), ! StandardCharsets.UTF_8)) { ! String content = preprocessTextResource( ! getConfig_ExecutableProperties(params).getName(), ! I18N.getString("resource.executable-properties-template"), ! EXECUTABLE_PROPERTIES_TEMPLATE, data, ! VERBOSE.fetchFrom(params), ! RESOURCE_DIR.fetchFrom(params)); ! w.write(content); ! } } private void createLauncherForEntryPoint( ! Map<String, ? super Object> 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( ! APP_NAME.fetchFrom(params) + ".ico", ! "icon", ! TEMPLATE_APP_ICON, ! icon, ! VERBOSE.fetchFrom(params), ! RESOURCE_DIR.fetchFrom(params)); ! ! Files.copy(in, iconTarget.toPath(), ! StandardCopyOption.REPLACE_EXISTING); ! writeCfgFile(p, root.resolve( ! getLauncherCfgName(p)).toFile(), "$APPDIR\\runtime"); ! prepareExecutableProperties(p); - // Copy executable root folder - Path executableFile = root.resolve(getLauncherName(p)); try (InputStream is_launcher = ! getResourceAsStream(getLauncherResourceName(p))) { writeEntry(is_launcher, executableFile); } File launcher = executableFile.toFile(); launcher.setWritable(true, true); // Update branding of EXE file ! if (REBRAND_EXECUTABLE.fetchFrom(p)) { try { String tempDirectory = WindowsDefender.getUserTempDirectory(); if (Arguments.CLIOptions.context().userProvidedBuildRoot) { ! tempDirectory = TEMP_ROOT.fetchFrom(p).getAbsolutePath(); } if (WindowsDefender.isThereAPotentialWindowsDefenderIssue( tempDirectory)) { ! Log.error(MessageFormat.format(I18N.getString( "message.potential.windows.defender.issue"), tempDirectory)); } launcher.setWritable(true); --- 264,316 ---- validateValueAndPut(data, "LEGAL_COPYRIGHT", COPYRIGHT, params); data.put("ORIGINAL_FILENAME", getLauncherName(params)); validateValueAndPut(data, "PRODUCT_NAME", APP_NAME, params); validateValueAndPut(data, "PRODUCT_VERSION", VERSION, params); ! createResource(EXECUTABLE_PROPERTIES_TEMPLATE, params) ! .setCategory(I18N.getString("resource.executable-properties-template")) ! .setSubstitutionData(data) ! .saveToFile(getConfig_ExecutableProperties(params)); } private void createLauncherForEntryPoint( ! Map<String, ? super Object> params) throws IOException { ! ! File iconTarget = getConfig_AppIcon(params); ! ! createResource(TEMPLATE_APP_ICON, params) ! .setCategory("icon") ! .setExternal(ICON_ICO.fetchFrom(params)) ! .saveToFile(iconTarget); ! writeCfgFile(params, root.resolve( ! getLauncherCfgName(params)).toFile()); ! prepareExecutableProperties(params); ! // Copy executable to bin folder ! Path executableFile = binDir.resolve(getLauncherName(params)); try (InputStream is_launcher = ! getResourceAsStream(getLauncherResourceName(params))) { writeEntry(is_launcher, executableFile); } File launcher = executableFile.toFile(); launcher.setWritable(true, true); // Update branding of EXE file ! if (REBRAND_EXECUTABLE.fetchFrom(params)) { try { String tempDirectory = WindowsDefender.getUserTempDirectory(); if (Arguments.CLIOptions.context().userProvidedBuildRoot) { ! tempDirectory = ! TEMP_ROOT.fetchFrom(params).getAbsolutePath(); } if (WindowsDefender.isThereAPotentialWindowsDefenderIssue( tempDirectory)) { ! Log.verbose(MessageFormat.format(I18N.getString( "message.potential.windows.defender.issue"), tempDirectory)); } launcher.setWritable(true);
*** 398,424 **** if (iconTarget.exists()) { iconSwap(iconTarget.getAbsolutePath(), launcher.getAbsolutePath()); } ! File executableProperties = getConfig_ExecutableProperties(p); if (executableProperties.exists()) { if (versionSwap(executableProperties.getAbsolutePath(), launcher.getAbsolutePath()) != 0) { throw new RuntimeException(MessageFormat.format( I18N.getString("error.version-swap"), executableProperties.getAbsolutePath())); } } } finally { executableFile.toFile().setReadOnly(); } } Files.copy(iconTarget.toPath(), ! root.resolve(APP_NAME.fetchFrom(p) + ".ico")); } private void copyApplication(Map<String, ? super Object> params) throws IOException { List<RelativeFileSet> appResourcesList = --- 318,346 ---- if (iconTarget.exists()) { iconSwap(iconTarget.getAbsolutePath(), launcher.getAbsolutePath()); } ! File executableProperties = ! getConfig_ExecutableProperties(params); if (executableProperties.exists()) { if (versionSwap(executableProperties.getAbsolutePath(), launcher.getAbsolutePath()) != 0) { throw new RuntimeException(MessageFormat.format( I18N.getString("error.version-swap"), executableProperties.getAbsolutePath())); } } } finally { + executableFile.toFile().setExecutable(true); executableFile.toFile().setReadOnly(); } } Files.copy(iconTarget.toPath(), ! binDir.resolve(APP_NAME.fetchFrom(params) + ".ico")); } private void copyApplication(Map<String, ? super Object> params) throws IOException { List<RelativeFileSet> appResourcesList =
*** 437,444 **** } } private static native int iconSwap(String iconTarget, String launcher); ! private static native int versionSwap(String executableProperties, String launcher); } --- 359,367 ---- } } private static native int iconSwap(String iconTarget, String launcher); ! private static native int versionSwap(String executableProperties, ! String launcher); }
< prev index next >