8223955: Eliminate or reduce mixing of old File API and new Path/Files APIs

Reviewed-by: herrick, asemenyuk
This commit is contained in:
Alexander Matveev 2020-07-07 16:08:29 -07:00
parent c782d0e486
commit ed05d57603
34 changed files with 537 additions and 514 deletions

View File

@ -435,8 +435,8 @@ final class DesktopIntegration {
File.separatorChar, '-') + IOUtils.getSuffix( File.separatorChar, '-') + IOUtils.getSuffix(
assoc.data.iconPath)); assoc.data.iconPath));
IOUtils.copyFile(assoc.data.iconPath.toFile(), IOUtils.copyFile(assoc.data.iconPath,
faIconFile.srcPath().toFile()); faIconFile.srcPath());
shellCommands.addIcon(mimeType, faIconFile.installPath(), shellCommands.addIcon(mimeType, faIconFile.installPath(),
assoc.iconSize); assoc.iconSize);

View File

@ -25,7 +25,6 @@
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Files; import java.nio.file.Files;
@ -39,20 +38,21 @@ import static jdk.incubator.jpackage.internal.StandardBundlerParam.ADD_LAUNCHERS
public class LinuxAppImageBuilder extends AbstractAppImageBuilder { public class LinuxAppImageBuilder extends AbstractAppImageBuilder {
static final BundlerParamInfo<File> ICON_PNG = static final BundlerParamInfo<Path> ICON_PNG =
new StandardBundlerParam<>( new StandardBundlerParam<>(
"icon.png", "icon.png",
File.class, Path.class,
params -> { params -> {
File f = ICON.fetchFrom(params); Path f = ICON.fetchFrom(params);
if (f != null && !f.getName().toLowerCase().endsWith(".png")) { if (f != null && f.getFileName() != null && !f.getFileName()
.toString().toLowerCase().endsWith(".png")) {
Log.error(MessageFormat.format( Log.error(MessageFormat.format(
I18N.getString("message.icon-not-png"), f)); I18N.getString("message.icon-not-png"), f));
return null; return null;
} }
return f; return f;
}, },
(s, p) -> new File(s)); (s, p) -> Path.of(s));
final static String DEFAULT_ICON = "java32.png"; final static String DEFAULT_ICON = "java32.png";

View File

@ -25,7 +25,6 @@
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.FileVisitResult; import java.nio.file.FileVisitResult;
import java.nio.file.Files; import java.nio.file.Files;
@ -178,13 +177,13 @@ public class LinuxDebBundler extends LinuxPackageBundler {
} }
@Override @Override
protected File buildPackageBundle( protected Path buildPackageBundle(
Map<String, String> replacementData, Map<String, String> replacementData,
Map<String, ? super Object> params, File outputParentDir) throws Map<String, ? super Object> params, Path outputParentDir) throws
PackagerException, IOException { PackagerException, IOException {
prepareProjectConfig(replacementData, params); prepareProjectConfig(replacementData, params);
adjustPermissionsRecursive(createMetaPackage(params).sourceRoot().toFile()); adjustPermissionsRecursive(createMetaPackage(params).sourceRoot());
return buildDeb(params, outputParentDir); return buildDeb(params, outputParentDir);
} }
@ -309,12 +308,12 @@ public class LinuxDebBundler extends LinuxPackageBundler {
* *
* This cannot be directly backport to 22u which is built with 1.6 * This cannot be directly backport to 22u which is built with 1.6
*/ */
private void setPermissions(File file, String permissions) { private void setPermissions(Path file, String permissions) {
Set<PosixFilePermission> filePermissions = Set<PosixFilePermission> filePermissions =
PosixFilePermissions.fromString(permissions); PosixFilePermissions.fromString(permissions);
try { try {
if (file.exists()) { if (Files.exists(file)) {
Files.setPosixFilePermissions(file.toPath(), filePermissions); Files.setPosixFilePermissions(file, filePermissions);
} }
} catch (IOException ex) { } catch (IOException ex) {
Log.error(ex.getMessage()); Log.error(ex.getMessage());
@ -335,16 +334,16 @@ public class LinuxDebBundler extends LinuxPackageBundler {
return false; return false;
} }
private void adjustPermissionsRecursive(File dir) throws IOException { private void adjustPermissionsRecursive(Path dir) throws IOException {
Files.walkFileTree(dir.toPath(), new SimpleFileVisitor<Path>() { Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
@Override @Override
public FileVisitResult visitFile(Path file, public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) BasicFileAttributes attrs)
throws IOException { throws IOException {
if (file.endsWith(".so") || !Files.isExecutable(file)) { if (file.endsWith(".so") || !Files.isExecutable(file)) {
setPermissions(file.toFile(), "rw-r--r--"); setPermissions(file, "rw-r--r--");
} else if (Files.isExecutable(file)) { } else if (Files.isExecutable(file)) {
setPermissions(file.toFile(), "rwxr-xr-x"); setPermissions(file, "rwxr-xr-x");
} }
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
} }
@ -353,7 +352,7 @@ public class LinuxDebBundler extends LinuxPackageBundler {
public FileVisitResult postVisitDirectory(Path dir, IOException e) public FileVisitResult postVisitDirectory(Path dir, IOException e)
throws IOException { throws IOException {
if (e == null) { if (e == null) {
setPermissions(dir.toFile(), "rwxr-xr-x"); setPermissions(dir, "rwxr-xr-x");
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
} else { } else {
// directory iteration failed // directory iteration failed
@ -383,7 +382,7 @@ public class LinuxDebBundler extends LinuxPackageBundler {
.setSubstitutionData(data) .setSubstitutionData(data)
.saveToFile(dstFilePath); .saveToFile(dstFilePath);
if (permissions != null) { if (permissions != null) {
setPermissions(dstFilePath.toFile(), permissions); setPermissions(dstFilePath, permissions);
} }
} }
@ -415,7 +414,7 @@ public class LinuxDebBundler extends LinuxPackageBundler {
if (!StandardBundlerParam.isRuntimeInstaller(params)) { if (!StandardBundlerParam.isRuntimeInstaller(params)) {
debianFiles.add(new DebianFile( debianFiles.add(new DebianFile(
getConfig_CopyrightFile(params).toPath(), getConfig_CopyrightFile(params),
"resource.copyright-file")); "resource.copyright-file"));
} }
@ -440,7 +439,7 @@ public class LinuxDebBundler extends LinuxPackageBundler {
return data; return data;
} }
private File getConfig_CopyrightFile(Map<String, ? super Object> params) { private Path getConfig_CopyrightFile(Map<String, ? super Object> params) {
final String installDir = LINUX_INSTALL_DIR.fetchFrom(params); final String installDir = LINUX_INSTALL_DIR.fetchFrom(params);
final String packageName = PACKAGE_NAME.fetchFrom(params); final String packageName = PACKAGE_NAME.fetchFrom(params);
@ -452,15 +451,15 @@ public class LinuxDebBundler extends LinuxPackageBundler {
} }
return createMetaPackage(params).sourceRoot().resolve( return createMetaPackage(params).sourceRoot().resolve(
Path.of("/").relativize(installPath)).toFile(); Path.of("/").relativize(installPath));
} }
private File buildDeb(Map<String, ? super Object> params, private Path buildDeb(Map<String, ? super Object> params,
File outdir) throws IOException { Path outdir) throws IOException {
File outFile = new File(outdir, Path outFile = outdir.resolve(
FULL_PACKAGE_NAME.fetchFrom(params)+".deb"); FULL_PACKAGE_NAME.fetchFrom(params)+".deb");
Log.verbose(MessageFormat.format(I18N.getString( Log.verbose(MessageFormat.format(I18N.getString(
"message.outputting-to-location"), outFile.getAbsolutePath())); "message.outputting-to-location"), outFile.toAbsolutePath().toString()));
PlatformPackage thePackage = createMetaPackage(params); PlatformPackage thePackage = createMetaPackage(params);
@ -470,13 +469,13 @@ public class LinuxDebBundler extends LinuxPackageBundler {
cmdline.add("--verbose"); cmdline.add("--verbose");
} }
cmdline.addAll(List.of("-b", thePackage.sourceRoot().toString(), cmdline.addAll(List.of("-b", thePackage.sourceRoot().toString(),
outFile.getAbsolutePath())); outFile.toAbsolutePath().toString()));
// run dpkg // run dpkg
Executor.of(cmdline.toArray(String[]::new)).executeExpectSuccess(); Executor.of(cmdline.toArray(String[]::new)).executeExpectSuccess();
Log.verbose(MessageFormat.format(I18N.getString( Log.verbose(MessageFormat.format(I18N.getString(
"message.output-to-location"), outFile.getAbsolutePath())); "message.output-to-location"), outFile.toAbsolutePath().toString()));
return outFile; return outFile;
} }

View File

@ -24,7 +24,6 @@
*/ */
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.InvalidPathException; import java.nio.file.InvalidPathException;
import java.nio.file.Path; import java.nio.file.Path;
@ -104,21 +103,21 @@ abstract class LinuxPackageBundler extends AbstractBundler {
} }
@Override @Override
final public File execute(Map<String, ? super Object> params, final public Path execute(Map<String, ? super Object> params,
File outputParentDir) throws PackagerException { Path outputParentDir) throws PackagerException {
IOUtils.writableOutputDir(outputParentDir.toPath()); IOUtils.writableOutputDir(outputParentDir);
PlatformPackage thePackage = createMetaPackage(params); PlatformPackage thePackage = createMetaPackage(params);
Function<File, ApplicationLayout> initAppImageLayout = imageRoot -> { Function<Path, ApplicationLayout> initAppImageLayout = imageRoot -> {
ApplicationLayout layout = appImageLayout(params); ApplicationLayout layout = appImageLayout(params);
layout.pathGroup().setPath(new Object(), layout.pathGroup().setPath(new Object(),
AppImageFile.getPathInAppImage(Path.of(""))); AppImageFile.getPathInAppImage(Path.of("")));
return layout.resolveAt(imageRoot.toPath()); return layout.resolveAt(imageRoot);
}; };
try { try {
File appImage = StandardBundlerParam.getPredefinedAppImage(params); Path appImage = StandardBundlerParam.getPredefinedAppImage(params);
// we either have an application image or need to build one // we either have an application image or need to build one
if (appImage != null) { if (appImage != null) {
@ -126,7 +125,7 @@ abstract class LinuxPackageBundler extends AbstractBundler {
thePackage.sourceApplicationLayout()); thePackage.sourceApplicationLayout());
} else { } else {
final Path srcAppImageRoot = thePackage.sourceRoot().resolve("src"); final Path srcAppImageRoot = thePackage.sourceRoot().resolve("src");
appImage = appImageBundler.execute(params, srcAppImageRoot.toFile()); appImage = appImageBundler.execute(params, srcAppImageRoot);
ApplicationLayout srcAppLayout = initAppImageLayout.apply( ApplicationLayout srcAppLayout = initAppImageLayout.apply(
appImage); appImage);
if (appImage.equals(PREDEFINED_RUNTIME_IMAGE.fetchFrom(params))) { if (appImage.equals(PREDEFINED_RUNTIME_IMAGE.fetchFrom(params))) {
@ -137,7 +136,7 @@ abstract class LinuxPackageBundler extends AbstractBundler {
// Application image is a newly created directory tree. // Application image is a newly created directory tree.
// Move it. // Move it.
srcAppLayout.move(thePackage.sourceApplicationLayout()); srcAppLayout.move(thePackage.sourceApplicationLayout());
IOUtils.deleteRecursive(srcAppImageRoot.toFile()); IOUtils.deleteRecursive(srcAppImageRoot);
} }
} }
@ -153,10 +152,10 @@ abstract class LinuxPackageBundler extends AbstractBundler {
data.putAll(createReplacementData(params)); data.putAll(createReplacementData(params));
File packageBundle = buildPackageBundle(Collections.unmodifiableMap( Path packageBundle = buildPackageBundle(Collections.unmodifiableMap(
data), params, outputParentDir); data), params, outputParentDir);
verifyOutputBundle(params, packageBundle.toPath()).stream() verifyOutputBundle(params, packageBundle).stream()
.filter(Objects::nonNull) .filter(Objects::nonNull)
.forEachOrdered(ex -> { .forEachOrdered(ex -> {
Log.verbose(ex.getLocalizedMessage()); Log.verbose(ex.getLocalizedMessage());
@ -240,9 +239,9 @@ abstract class LinuxPackageBundler extends AbstractBundler {
abstract protected Map<String, String> createReplacementData( abstract protected Map<String, String> createReplacementData(
Map<String, ? super Object> params) throws IOException; Map<String, ? super Object> params) throws IOException;
abstract protected File buildPackageBundle( abstract protected Path buildPackageBundle(
Map<String, String> replacementData, Map<String, String> replacementData,
Map<String, ? super Object> params, File outputParentDir) throws Map<String, ? super Object> params, Path outputParentDir) throws
PackagerException, IOException; PackagerException, IOException;
final protected PlatformPackage createMetaPackage( final protected PlatformPackage createMetaPackage(
@ -266,7 +265,7 @@ abstract class LinuxPackageBundler extends AbstractBundler {
@Override @Override
public Path sourceRoot() { public Path sourceRoot() {
return IMAGES_ROOT.fetchFrom(params).toPath().toAbsolutePath(); return IMAGES_ROOT.fetchFrom(params).toAbsolutePath();
} }
@Override @Override

View File

@ -25,7 +25,6 @@
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.text.MessageFormat; import java.text.MessageFormat;
@ -147,9 +146,9 @@ public class LinuxRpmBundler extends LinuxPackageBundler {
} }
@Override @Override
protected File buildPackageBundle( protected Path buildPackageBundle(
Map<String, String> replacementData, Map<String, String> replacementData,
Map<String, ? super Object> params, File outputParentDir) throws Map<String, ? super Object> params, Path outputParentDir) throws
PackagerException, IOException { PackagerException, IOException {
Path specFile = specFile(params); Path specFile = specFile(params);
@ -160,7 +159,7 @@ public class LinuxRpmBundler extends LinuxPackageBundler {
.setSubstitutionData(replacementData) .setSubstitutionData(replacementData)
.saveToFile(specFile); .saveToFile(specFile);
return buildRPM(params, outputParentDir.toPath()).toFile(); return buildRPM(params, outputParentDir);
} }
@Override @Override
@ -275,7 +274,7 @@ public class LinuxRpmBundler extends LinuxPackageBundler {
} }
private Path specFile(Map<String, ? super Object> params) { private Path specFile(Map<String, ? super Object> params) {
return TEMP_ROOT.fetchFrom(params).toPath().resolve(Path.of("SPECS", return TEMP_ROOT.fetchFrom(params).resolve(Path.of("SPECS",
PACKAGE_NAME.fetchFrom(params) + ".spec")); PACKAGE_NAME.fetchFrom(params) + ".spec"));
} }
@ -302,7 +301,7 @@ public class LinuxRpmBundler extends LinuxPackageBundler {
"--define", String.format("%%_rpmdir %s", rpmFile.getParent()), "--define", String.format("%%_rpmdir %s", rpmFile.getParent()),
// do not use other system directories to build as current user // do not use other system directories to build as current user
"--define", String.format("%%_topdir %s", "--define", String.format("%%_topdir %s",
TEMP_ROOT.fetchFrom(params).toPath().toAbsolutePath()), TEMP_ROOT.fetchFrom(params).toAbsolutePath()),
"--define", String.format("%%_rpmfilename %s", rpmFile.getFileName()) "--define", String.format("%%_rpmfilename %s", rpmFile.getFileName())
).executeExpectSuccess(); ).executeExpectSuccess();

View File

@ -25,8 +25,6 @@
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.Writer; import java.io.Writer;
@ -120,20 +118,21 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
}, },
(s, p) -> s); (s, p) -> s);
public static final BundlerParamInfo<File> ICON_ICNS = public static final BundlerParamInfo<Path> ICON_ICNS =
new StandardBundlerParam<>( new StandardBundlerParam<>(
"icon.icns", "icon.icns",
File.class, Path.class,
params -> { params -> {
File f = ICON.fetchFrom(params); Path f = ICON.fetchFrom(params);
if (f != null && !f.getName().toLowerCase().endsWith(".icns")) { if (f != null && f.getFileName() != null && !f.getFileName()
.toString().toLowerCase().endsWith(".icns")) {
Log.error(MessageFormat.format( Log.error(MessageFormat.format(
I18N.getString("message.icon-not-icns"), f)); I18N.getString("message.icon-not-icns"), f));
return null; return null;
} }
return f; return f;
}, },
(s, p) -> new File(s)); (s, p) -> Path.of(s));
public static final StandardBundlerParam<Boolean> SIGN_BUNDLE = public static final StandardBundlerParam<Boolean> SIGN_BUNDLE =
new StandardBundlerParam<>( new StandardBundlerParam<>(
@ -242,8 +241,8 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
Map<String, ? super Object> originalParams = new HashMap<>(params); Map<String, ? super Object> originalParams = new HashMap<>(params);
// Generate PkgInfo // Generate PkgInfo
File pkgInfoFile = new File(contentsDir.toFile(), "PkgInfo"); Path pkgInfoFile = contentsDir.resolve("PkgInfo");
pkgInfoFile.createNewFile(); Files.createFile(pkgInfoFile);
writePkgInfo(pkgInfoFile); writePkgInfo(pkgInfoFile);
Path executable = macOSDir.resolve(getLauncherName(params)); Path executable = macOSDir.resolve(getLauncherName(params));
@ -290,11 +289,9 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
// copy file association icons // copy file association icons
for (Map<String, ? for (Map<String, ?
super Object> fa : FILE_ASSOCIATIONS.fetchFrom(params)) { super Object> fa : FILE_ASSOCIATIONS.fetchFrom(params)) {
File f = FA_ICON.fetchFrom(fa); Path f = FA_ICON.fetchFrom(fa);
if (f != null && f.exists()) { if (IOUtils.exists(f)) {
try (InputStream in2 = new FileInputStream(f)) { IOUtils.copyFile(f, resourcesDir.resolve(f.getFileName()));
Files.copy(in2, resourcesDir.resolve(f.getName()));
}
} }
} }
@ -306,11 +303,11 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
private void copyRuntimeFiles(Map<String, ? super Object> params) private void copyRuntimeFiles(Map<String, ? super Object> params)
throws IOException { throws IOException {
// Generate Info.plist // Generate Info.plist
writeInfoPlist(contentsDir.resolve("Info.plist").toFile(), params); writeInfoPlist(contentsDir.resolve("Info.plist"), params);
// generate java runtime info.plist // generate java runtime info.plist
writeRuntimeInfoPlist( writeRuntimeInfoPlist(
runtimeDir.resolve("Contents/Info.plist").toFile(), params); runtimeDir.resolve("Contents/Info.plist"), params);
// copy library // copy library
Path runtimeMacOSDir = Files.createDirectories( Path runtimeMacOSDir = Files.createDirectories(
@ -346,8 +343,8 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
} }
} }
static File getConfig_Entitlements(Map<String, ? super Object> params) { static Path getConfig_Entitlements(Map<String, ? super Object> params) {
return new File(CONFIG_ROOT.fetchFrom(params), return CONFIG_ROOT.fetchFrom(params).resolve(
getLauncherName(params) + ".entitlements"); getLauncherName(params) + ".entitlements");
} }
@ -382,7 +379,7 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
} }
} }
private void writeRuntimeInfoPlist(File file, private void writeRuntimeInfoPlist(Path file,
Map<String, ? super Object> params) throws IOException { Map<String, ? super Object> params) throws IOException {
Map<String, String> data = new HashMap<>(); Map<String, String> data = new HashMap<>();
String identifier = StandardBundlerParam.isRuntimeInstaller(params) ? String identifier = StandardBundlerParam.isRuntimeInstaller(params) ?
@ -427,10 +424,10 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
} }
} }
private void writeInfoPlist(File file, Map<String, ? super Object> params) private void writeInfoPlist(Path file, Map<String, ? super Object> params)
throws IOException { throws IOException {
Log.verbose(MessageFormat.format(I18N.getString( Log.verbose(MessageFormat.format(I18N.getString(
"message.preparing-info-plist"), file.getAbsolutePath())); "message.preparing-info-plist"), file.toAbsolutePath()));
//prepare config for exe //prepare config for exe
//Note: do not need CFBundleDisplayName if we don't support localization //Note: do not need CFBundleDisplayName if we don't support localization
@ -460,7 +457,7 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
+ "." + ((extensions == null || extensions.isEmpty()) + "." + ((extensions == null || extensions.isEmpty())
? "mime" : extensions.get(0)); ? "mime" : extensions.get(0));
String description = FA_DESCRIPTION.fetchFrom(fileAssociation); String description = FA_DESCRIPTION.fetchFrom(fileAssociation);
File icon = FA_ICON.fetchFrom(fileAssociation); Path icon = FA_ICON.fetchFrom(fileAssociation);
bundleDocumentTypes.append(" <dict>\n"); bundleDocumentTypes.append(" <dict>\n");
writeStringArrayPlist(bundleDocumentTypes, "LSItemContentTypes", writeStringArrayPlist(bundleDocumentTypes, "LSItemContentTypes",
@ -482,9 +479,9 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
FA_MAC_LSDOCINPLACE.fetchFrom(fileAssociation)); FA_MAC_LSDOCINPLACE.fetchFrom(fileAssociation));
writeBoolPlist(bundleDocumentTypes, "UISupportsDocumentBrowser", writeBoolPlist(bundleDocumentTypes, "UISupportsDocumentBrowser",
FA_MAC_UIDOCBROWSER.fetchFrom(fileAssociation)); FA_MAC_UIDOCBROWSER.fetchFrom(fileAssociation));
if (icon != null && icon.exists()) { if (IOUtils.exists(icon)) {
writeStringPlist(bundleDocumentTypes, "CFBundleTypeIconFile", writeStringPlist(bundleDocumentTypes, "CFBundleTypeIconFile",
icon.getName()); icon.getFileName().toString());
} }
bundleDocumentTypes.append(" </dict>\n"); bundleDocumentTypes.append(" </dict>\n");
@ -496,8 +493,9 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
writeStringArrayPlist(exportedTypes, "UTTypeConformsTo", writeStringArrayPlist(exportedTypes, "UTTypeConformsTo",
FA_MAC_UTTYPECONFORMSTO.fetchFrom(fileAssociation)); FA_MAC_UTTYPECONFORMSTO.fetchFrom(fileAssociation));
if (icon != null && icon.exists()) { if (IOUtils.exists(icon)) {
writeStringPlist(exportedTypes, "UTTypeIconFile", icon.getName()); writeStringPlist(exportedTypes, "UTTypeIconFile",
icon.getFileName().toString());
} }
exportedTypes.append("\n") exportedTypes.append("\n")
.append(" <key>UTTypeTagSpecification</key>\n") .append(" <key>UTTypeTagSpecification</key>\n")
@ -532,11 +530,11 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
.saveToFile(file); .saveToFile(file);
} }
private void writePkgInfo(File file) throws IOException { private void writePkgInfo(Path file) throws IOException {
//hardcoded as it does not seem we need to change it ever //hardcoded as it does not seem we need to change it ever
String signature = "????"; String signature = "????";
try (Writer out = Files.newBufferedWriter(file.toPath())) { try (Writer out = Files.newBufferedWriter(file)) {
out.write(OS_TYPE_CODE + signature); out.write(OS_TYPE_CODE + signature);
out.flush(); out.flush();
} }
@ -557,7 +555,7 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
} }
// get current keychain list // get current keychain list
String keyChainPath = new File (keyChain).getAbsolutePath().toString(); String keyChainPath = Path.of(keyChain).toAbsolutePath().toString();
List<String> keychainList = new ArrayList<>(); List<String> keychainList = new ArrayList<>();
int ret = IOUtils.getProcessOutput( int ret = IOUtils.getProcessOutput(
keychainList, "security", "list-keychains"); keychainList, "security", "list-keychains");
@ -621,7 +619,7 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
static void signAppBundle( static void signAppBundle(
Map<String, ? super Object> params, Path appLocation, Map<String, ? super Object> params, Path appLocation,
String signingIdentity, String identifierPrefix, File entitlements) String signingIdentity, String identifierPrefix, Path entitlements)
throws IOException { throws IOException {
AtomicReference<IOException> toThrow = new AtomicReference<>(); AtomicReference<IOException> toThrow = new AtomicReference<>();
String appExecutable = "/Contents/MacOS/" + APP_NAME.fetchFrom(params); String appExecutable = "/Contents/MacOS/" + APP_NAME.fetchFrom(params);
@ -683,8 +681,7 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
try { try {
Set<PosixFilePermission> oldPermissions = Set<PosixFilePermission> oldPermissions =
Files.getPosixFilePermissions(p); Files.getPosixFilePermissions(p);
File f = p.toFile(); p.toFile().setWritable(true, true);
f.setWritable(true, true);
ProcessBuilder pb = new ProcessBuilder(args); ProcessBuilder pb = new ProcessBuilder(args);
@ -798,17 +795,15 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
} }
try { try {
File infoPList = new File(PREDEFINED_APP_IMAGE.fetchFrom(params) + Path infoPList = PREDEFINED_APP_IMAGE.fetchFrom(params).resolve("Contents").
File.separator + "Contents" + resolve("Info.plist");
File.separator + "Info.plist");
DocumentBuilderFactory dbf DocumentBuilderFactory dbf
= DocumentBuilderFactory.newDefaultInstance(); = DocumentBuilderFactory.newDefaultInstance();
dbf.setFeature("http://apache.org/xml/features/" + dbf.setFeature("http://apache.org/xml/features/" +
"nonvalidating/load-external-dtd", false); "nonvalidating/load-external-dtd", false);
DocumentBuilder b = dbf.newDocumentBuilder(); DocumentBuilder b = dbf.newDocumentBuilder();
org.w3c.dom.Document doc = b.parse(new FileInputStream( org.w3c.dom.Document doc = b.parse(Files.newInputStream(infoPList));
infoPList.getAbsolutePath()));
XPath xPath = XPathFactory.newInstance().newXPath(); XPath xPath = XPathFactory.newInstance().newXPath();
// Query for the value of <string> element preceding <key> // Query for the value of <string> element preceding <key>

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,7 +25,8 @@
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.File; import java.nio.file.Files;
import java.nio.file.Path;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -103,21 +104,21 @@ public class MacAppStoreBundler extends MacBaseInstallerBundler {
params -> "-MacAppStore", params -> "-MacAppStore",
(s, p) -> s); (s, p) -> s);
public File bundle(Map<String, ? super Object> params, public Path bundle(Map<String, ? super Object> params,
File outdir) throws PackagerException { Path outdir) throws PackagerException {
Log.verbose(MessageFormat.format(I18N.getString( Log.verbose(MessageFormat.format(I18N.getString(
"message.building-bundle"), APP_NAME.fetchFrom(params))); "message.building-bundle"), APP_NAME.fetchFrom(params)));
IOUtils.writableOutputDir(outdir.toPath()); IOUtils.writableOutputDir(outdir);
// first, load in some overrides // first, load in some overrides
// icns needs @2 versions, so load in the @2 default // icns needs @2 versions, so load in the @2 default
params.put(DEFAULT_ICNS_ICON.getID(), TEMPLATE_BUNDLE_ICON_HIDPI); params.put(DEFAULT_ICNS_ICON.getID(), TEMPLATE_BUNDLE_ICON_HIDPI);
// now we create the app // now we create the app
File appImageDir = APP_IMAGE_TEMP_ROOT.fetchFrom(params); Path appImageDir = APP_IMAGE_TEMP_ROOT.fetchFrom(params);
try { try {
appImageDir.mkdirs(); Files.createDirectories(appImageDir);
try { try {
MacAppImageBuilder.addNewKeychain(params); MacAppImageBuilder.addNewKeychain(params);
@ -126,7 +127,7 @@ public class MacAppStoreBundler extends MacBaseInstallerBundler {
} }
// first, make sure we don't use the local signing key // first, make sure we don't use the local signing key
params.put(DEVELOPER_ID_APP_SIGNING_KEY.getID(), null); params.put(DEVELOPER_ID_APP_SIGNING_KEY.getID(), null);
File appLocation = prepareAppBundle(params); Path appLocation = prepareAppBundle(params);
String signingIdentity = String signingIdentity =
MAC_APP_STORE_APP_SIGNING_KEY.fetchFrom(params); MAC_APP_STORE_APP_SIGNING_KEY.fetchFrom(params);
@ -134,7 +135,7 @@ public class MacAppStoreBundler extends MacBaseInstallerBundler {
BUNDLE_ID_SIGNING_PREFIX.fetchFrom(params); BUNDLE_ID_SIGNING_PREFIX.fetchFrom(params);
MacAppImageBuilder.prepareEntitlements(params); MacAppImageBuilder.prepareEntitlements(params);
MacAppImageBuilder.signAppBundle(params, appLocation.toPath(), MacAppImageBuilder.signAppBundle(params, appLocation,
signingIdentity, identifierPrefix, signingIdentity, identifierPrefix,
MacAppImageBuilder.getConfig_Entitlements(params)); MacAppImageBuilder.getConfig_Entitlements(params));
MacAppImageBuilder.restoreKeychainList(params); MacAppImageBuilder.restoreKeychainList(params);
@ -142,10 +143,10 @@ public class MacAppStoreBundler extends MacBaseInstallerBundler {
ProcessBuilder pb; ProcessBuilder pb;
// create the final pkg file // create the final pkg file
File finalPKG = new File(outdir, INSTALLER_NAME.fetchFrom(params) Path finalPKG = outdir.resolve(INSTALLER_NAME.fetchFrom(params)
+ INSTALLER_SUFFIX.fetchFrom(params) + INSTALLER_SUFFIX.fetchFrom(params)
+ ".pkg"); + ".pkg");
outdir.mkdirs(); Files.createDirectories(outdir);
String installIdentify = String installIdentify =
MAC_APP_STORE_PKG_SIGNING_KEY.fetchFrom(params); MAC_APP_STORE_PKG_SIGNING_KEY.fetchFrom(params);
@ -164,7 +165,7 @@ public class MacAppStoreBundler extends MacBaseInstallerBundler {
buildOptions.add("--keychain"); buildOptions.add("--keychain");
buildOptions.add(keychainName); buildOptions.add(keychainName);
} }
buildOptions.add(finalPKG.getAbsolutePath()); buildOptions.add(finalPKG.toAbsolutePath().toString());
pb = new ProcessBuilder(buildOptions); pb = new ProcessBuilder(buildOptions);
@ -243,8 +244,8 @@ public class MacAppStoreBundler extends MacBaseInstallerBundler {
} }
@Override @Override
public File execute(Map<String, ? super Object> params, public Path execute(Map<String, ? super Object> params,
File outputParentDir) throws PackagerException { Path outputParentDir) throws PackagerException {
return bundle(params, outputParentDir); return bundle(params, outputParentDir);
} }

View File

@ -26,10 +26,10 @@
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -43,21 +43,23 @@ import static jdk.incubator.jpackage.internal.StandardBundlerParam.VERSION;
public abstract class MacBaseInstallerBundler extends AbstractBundler { public abstract class MacBaseInstallerBundler extends AbstractBundler {
public final BundlerParamInfo<File> APP_IMAGE_TEMP_ROOT = public final BundlerParamInfo<Path> APP_IMAGE_TEMP_ROOT =
new StandardBundlerParam<>( new StandardBundlerParam<>(
"mac.app.imageRoot", "mac.app.imageRoot",
File.class, Path.class,
params -> { params -> {
File imageDir = IMAGES_ROOT.fetchFrom(params); Path imageDir = IMAGES_ROOT.fetchFrom(params);
if (!imageDir.exists()) imageDir.mkdirs();
try { try {
if (!IOUtils.exists(imageDir)) {
Files.createDirectories(imageDir);
}
return Files.createTempDirectory( return Files.createTempDirectory(
imageDir.toPath(), "image-").toFile(); imageDir, "image-");
} catch (IOException e) { } catch (IOException e) {
return new File(imageDir, getID()+ ".image"); return imageDir.resolve(getID()+ ".image");
} }
}, },
(s, p) -> new File(s)); (s, p) -> Path.of(s));
public static final BundlerParamInfo<String> SIGNING_KEY_USER = public static final BundlerParamInfo<String> SIGNING_KEY_USER =
new StandardBundlerParam<>( new StandardBundlerParam<>(
@ -110,8 +112,8 @@ public abstract class MacBaseInstallerBundler extends AbstractBundler {
protected void validateAppImageAndBundeler( protected void validateAppImageAndBundeler(
Map<String, ? super Object> params) throws ConfigException { Map<String, ? super Object> params) throws ConfigException {
if (PREDEFINED_APP_IMAGE.fetchFrom(params) != null) { if (PREDEFINED_APP_IMAGE.fetchFrom(params) != null) {
File applicationImage = PREDEFINED_APP_IMAGE.fetchFrom(params); Path applicationImage = PREDEFINED_APP_IMAGE.fetchFrom(params);
if (!applicationImage.exists()) { if (!IOUtils.exists(applicationImage)) {
throw new ConfigException( throw new ConfigException(
MessageFormat.format(I18N.getString( MessageFormat.format(I18N.getString(
"message.app-image-dir-does-not-exist"), "message.app-image-dir-does-not-exist"),
@ -132,14 +134,14 @@ public abstract class MacBaseInstallerBundler extends AbstractBundler {
} }
} }
protected File prepareAppBundle(Map<String, ? super Object> params) protected Path prepareAppBundle(Map<String, ? super Object> params)
throws PackagerException { throws PackagerException {
File predefinedImage = Path predefinedImage =
StandardBundlerParam.getPredefinedAppImage(params); StandardBundlerParam.getPredefinedAppImage(params);
if (predefinedImage != null) { if (predefinedImage != null) {
return predefinedImage; return predefinedImage;
} }
File appImageRoot = APP_IMAGE_TEMP_ROOT.fetchFrom(params); Path appImageRoot = APP_IMAGE_TEMP_ROOT.fetchFrom(params);
return appImageBundler.execute(params, appImageRoot); return appImageBundler.execute(params, appImageRoot);
} }

View File

@ -27,11 +27,11 @@ package jdk.incubator.jpackage.internal;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -52,8 +52,8 @@ public final class MacCertificate {
return verifyCertificate(this.certificate); return verifyCertificate(this.certificate);
} }
private static File findCertificate(String certificate) { private static Path findCertificate(String certificate) {
File result = null; Path result = null;
List<String> args = new ArrayList<>(); List<String> args = new ArrayList<>();
args.add("security"); args.add("security");
@ -68,10 +68,10 @@ public final class MacCertificate {
ProcessBuilder security = new ProcessBuilder(args); ProcessBuilder security = new ProcessBuilder(args);
IOUtils.exec(security, false, ps); IOUtils.exec(security, false, ps);
File output = File.createTempFile("tempfile", ".tmp"); Path output = Files.createTempFile("tempfile", ".tmp");
Files.copy(new ByteArrayInputStream(baos.toByteArray()), Files.copy(new ByteArrayInputStream(baos.toByteArray()),
output.toPath(), StandardCopyOption.REPLACE_EXISTING); output, StandardCopyOption.REPLACE_EXISTING);
result = output; result = output;
} }
@ -111,7 +111,7 @@ public final class MacCertificate {
boolean result = false; boolean result = false;
try { try {
File file = null; Path file = null;
Date certificateDate = null; Date certificateDate = null;
try { try {
@ -119,12 +119,12 @@ public final class MacCertificate {
if (file != null) { if (file != null) {
certificateDate = findCertificateDate( certificateDate = findCertificateDate(
file.getCanonicalPath()); file.toFile().getCanonicalPath());
} }
} }
finally { finally {
if (file != null) { if (file != null) {
file.delete(); Files.delete(file);
} }
} }

View File

@ -69,22 +69,22 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
params -> "", params -> "",
(s, p) -> s); (s, p) -> s);
public File bundle(Map<String, ? super Object> params, public Path bundle(Map<String, ? super Object> params,
File outdir) throws PackagerException { Path outdir) throws PackagerException {
Log.verbose(MessageFormat.format(I18N.getString("message.building-dmg"), Log.verbose(MessageFormat.format(I18N.getString("message.building-dmg"),
APP_NAME.fetchFrom(params))); APP_NAME.fetchFrom(params)));
IOUtils.writableOutputDir(outdir.toPath()); IOUtils.writableOutputDir(outdir);
try { try {
File appLocation = prepareAppBundle(params); Path appLocation = prepareAppBundle(params);
if (appLocation != null && prepareConfigFiles(params)) { if (appLocation != null && prepareConfigFiles(params)) {
File configScript = getConfig_Script(params); Path configScript = getConfig_Script(params);
if (configScript.exists()) { if (IOUtils.exists(configScript)) {
Log.verbose(MessageFormat.format( Log.verbose(MessageFormat.format(
I18N.getString("message.running-script"), I18N.getString("message.running-script"),
configScript.getAbsolutePath())); configScript.toAbsolutePath().toString()));
IOUtils.run("bash", configScript); IOUtils.run("bash", configScript);
} }
@ -101,16 +101,19 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
private void prepareDMGSetupScript(Map<String, ? super Object> params) private void prepareDMGSetupScript(Map<String, ? super Object> params)
throws IOException { throws IOException {
File dmgSetup = getConfig_VolumeScript(params); Path dmgSetup = getConfig_VolumeScript(params);
Log.verbose(MessageFormat.format( Log.verbose(MessageFormat.format(
I18N.getString("message.preparing-dmg-setup"), I18N.getString("message.preparing-dmg-setup"),
dmgSetup.getAbsolutePath())); dmgSetup.toAbsolutePath().toString()));
// We need to use URL for DMG to find it. We cannot use volume name, since // We need to use URL for DMG to find it. We cannot use volume name, since
// user might have open DMG with same volume name already. Url should end with // user might have open DMG with same volume name already. Url should end with
// '/' and it should be real path (no symbolic links). // '/' and it should be real path (no symbolic links).
File imageDir = IMAGES_ROOT.fetchFrom(params); Path imageDir = IMAGES_ROOT.fetchFrom(params);
if (!imageDir.exists()) imageDir.mkdirs(); // Create it, since it does not exist if (!Files.exists(imageDir)) {
// Create it, since it does not exist
Files.createDirectories(imageDir);
}
Path rootPath = Path.of(imageDir.toString()).toRealPath(); Path rootPath = Path.of(imageDir.toString()).toRealPath();
Path volumePath = rootPath.resolve(APP_NAME.fetchFrom(params)); Path volumePath = rootPath.resolve(APP_NAME.fetchFrom(params));
String volumeUrl = volumePath.toUri().toString() + File.separator; String volumeUrl = volumePath.toUri().toString() + File.separator;
@ -134,24 +137,24 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
.saveToFile(dmgSetup); .saveToFile(dmgSetup);
} }
private File getConfig_VolumeScript(Map<String, ? super Object> params) { private Path getConfig_VolumeScript(Map<String, ? super Object> params) {
return new File(CONFIG_ROOT.fetchFrom(params), return CONFIG_ROOT.fetchFrom(params).resolve(
APP_NAME.fetchFrom(params) + "-dmg-setup.scpt"); APP_NAME.fetchFrom(params) + "-dmg-setup.scpt");
} }
private File getConfig_VolumeBackground( private Path getConfig_VolumeBackground(
Map<String, ? super Object> params) { Map<String, ? super Object> params) {
return new File(CONFIG_ROOT.fetchFrom(params), return CONFIG_ROOT.fetchFrom(params).resolve(
APP_NAME.fetchFrom(params) + "-background.tiff"); APP_NAME.fetchFrom(params) + "-background.tiff");
} }
private File getConfig_VolumeIcon(Map<String, ? super Object> params) { private Path getConfig_VolumeIcon(Map<String, ? super Object> params) {
return new File(CONFIG_ROOT.fetchFrom(params), return CONFIG_ROOT.fetchFrom(params).resolve(
APP_NAME.fetchFrom(params) + "-volume.icns"); APP_NAME.fetchFrom(params) + "-volume.icns");
} }
private File getConfig_LicenseFile(Map<String, ? super Object> params) { private Path getConfig_LicenseFile(Map<String, ? super Object> params) {
return new File(CONFIG_ROOT.fetchFrom(params), return CONFIG_ROOT.fetchFrom(params).resolve(
APP_NAME.fetchFrom(params) + "-license.plist"); APP_NAME.fetchFrom(params) + "-license.plist");
} }
@ -162,9 +165,9 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
return; return;
} }
File licFile = new File(licFileStr); Path licFile = Path.of(licFileStr);
byte[] licenseContentOriginal = byte[] licenseContentOriginal =
Files.readAllBytes(licFile.toPath()); Files.readAllBytes(licFile);
String licenseInBase64 = String licenseInBase64 =
Base64.getEncoder().encodeToString(licenseContentOriginal); Base64.getEncoder().encodeToString(licenseContentOriginal);
@ -205,8 +208,8 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
} }
// name of post-image script // name of post-image script
private File getConfig_Script(Map<String, ? super Object> params) { private Path getConfig_Script(Map<String, ? super Object> params) {
return new File(CONFIG_ROOT.fetchFrom(params), return CONFIG_ROOT.fetchFrom(params).resolve(
APP_NAME.fetchFrom(params) + "-post-image.sh"); APP_NAME.fetchFrom(params) + "-post-image.sh");
} }
@ -218,9 +221,9 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
"/usr/bin/SetFile", "/Developer/usr/bin/SetFile"}; "/usr/bin/SetFile", "/Developer/usr/bin/SetFile"};
String setFilePath = null; String setFilePath = null;
for (String path: typicalPaths) { for (String path : typicalPaths) {
File f = new File(path); Path f = Path.of(path);
if (f.exists() && f.canExecute()) { if (Files.exists(f) && Files.isExecutable(f)) {
setFilePath = path; setFilePath = path;
break; break;
} }
@ -251,9 +254,9 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
BufferedReader br = new BufferedReader(isr); BufferedReader br = new BufferedReader(isr);
String lineRead = br.readLine(); String lineRead = br.readLine();
if (lineRead != null) { if (lineRead != null) {
File f = new File(lineRead); Path f = Path.of(lineRead);
if (f.exists() && f.canExecute()) { if (Files.exists(f) && Files.isExecutable(f)) {
return f.getAbsolutePath(); return f.toAbsolutePath().toString();
} }
} }
} catch (IOException ignored) {} } catch (IOException ignored) {}
@ -261,31 +264,30 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
return null; return null;
} }
private File buildDMG( Map<String, ? super Object> params, private Path buildDMG( Map<String, ? super Object> params,
File appLocation, File outdir) throws IOException, PackagerException { Path appLocation, Path outdir) throws IOException {
boolean copyAppImage = false; boolean copyAppImage = false;
File imagesRoot = IMAGES_ROOT.fetchFrom(params); Path imagesRoot = IMAGES_ROOT.fetchFrom(params);
if (!imagesRoot.exists()) imagesRoot.mkdirs(); if (!Files.exists(imagesRoot)) {
Files.createDirectories(imagesRoot);
}
File protoDMG = new File(imagesRoot, Path protoDMG = imagesRoot.resolve(APP_NAME.fetchFrom(params) +"-tmp.dmg");
APP_NAME.fetchFrom(params) +"-tmp.dmg"); Path finalDMG = outdir.resolve(INSTALLER_NAME.fetchFrom(params)
File finalDMG = new File(outdir, INSTALLER_NAME.fetchFrom(params)
+ INSTALLER_SUFFIX.fetchFrom(params) + ".dmg"); + INSTALLER_SUFFIX.fetchFrom(params) + ".dmg");
File srcFolder = APP_IMAGE_TEMP_ROOT.fetchFrom(params); Path srcFolder = APP_IMAGE_TEMP_ROOT.fetchFrom(params);
File predefinedImage = Path predefinedImage = StandardBundlerParam.getPredefinedAppImage(params);
StandardBundlerParam.getPredefinedAppImage(params);
if (predefinedImage != null) { if (predefinedImage != null) {
srcFolder = predefinedImage; srcFolder = predefinedImage;
} else if (StandardBundlerParam.isRuntimeInstaller(params)) { } else if (StandardBundlerParam.isRuntimeInstaller(params)) {
Path newRoot = Files.createTempDirectory( Path newRoot = Files.createTempDirectory(TEMP_ROOT.fetchFrom(params),
TEMP_ROOT.fetchFrom(params).toPath(), "root-"); "root-");
// first, is this already a runtime with // first, is this already a runtime with
// <runtime>/Contents/Home - if so we need the Home dir // <runtime>/Contents/Home - if so we need the Home dir
Path original = appLocation.toPath(); Path home = appLocation.resolve("Contents/Home");
Path home = original.resolve("Contents/Home"); Path source = (Files.exists(home)) ? home : appLocation;
Path source = (Files.exists(home)) ? home : original;
// Then we need to put back the <NAME>/Content/Home // Then we need to put back the <NAME>/Content/Home
Path root = newRoot.resolve( Path root = newRoot.resolve(
@ -294,21 +296,23 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
IOUtils.copyRecursive(source, dest); IOUtils.copyRecursive(source, dest);
srcFolder = newRoot.toFile(); srcFolder = newRoot;
} }
Log.verbose(MessageFormat.format(I18N.getString( Log.verbose(MessageFormat.format(I18N.getString(
"message.creating-dmg-file"), finalDMG.getAbsolutePath())); "message.creating-dmg-file"), finalDMG.toAbsolutePath()));
protoDMG.delete(); Files.deleteIfExists(protoDMG);
if (finalDMG.exists() && !finalDMG.delete()) { try {
Files.deleteIfExists(finalDMG);
} catch (IOException ex) {
throw new IOException(MessageFormat.format(I18N.getString( throw new IOException(MessageFormat.format(I18N.getString(
"message.dmg-cannot-be-overwritten"), "message.dmg-cannot-be-overwritten"),
finalDMG.getAbsolutePath())); finalDMG.toAbsolutePath()));
} }
protoDMG.getParentFile().mkdirs(); Files.createDirectories(protoDMG.getParent());
finalDMG.getParentFile().mkdirs(); Files.createDirectories(finalDMG.getParent());
String hdiUtilVerbosityFlag = VERBOSE.fetchFrom(params) ? String hdiUtilVerbosityFlag = VERBOSE.fetchFrom(params) ?
"-verbose" : "-quiet"; "-verbose" : "-quiet";
@ -318,9 +322,9 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
hdiutil, hdiutil,
"create", "create",
hdiUtilVerbosityFlag, hdiUtilVerbosityFlag,
"-srcfolder", srcFolder.getAbsolutePath(), "-srcfolder", srcFolder.toAbsolutePath().toString(),
"-volname", APP_NAME.fetchFrom(params), "-volname", APP_NAME.fetchFrom(params),
"-ov", protoDMG.getAbsolutePath(), "-ov", protoDMG.toAbsolutePath().toString(),
"-fs", "HFS+", "-fs", "HFS+",
"-format", "UDRW"); "-format", "UDRW");
try { try {
@ -332,8 +336,7 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
// DMG and copy files manually. See JDK-8248059. // DMG and copy files manually. See JDK-8248059.
copyAppImage = true; copyAppImage = true;
long size = new PathGroup(Map.of(new Object(), srcFolder.toPath())) long size = new PathGroup(Map.of(new Object(), srcFolder)).sizeInBytes();
.sizeInBytes();
size += 50 * 1024 * 1024; // Add extra 50 megabytes. Actually DMG size will size += 50 * 1024 * 1024; // Add extra 50 megabytes. Actually DMG size will
// not be bigger, but it will able to hold additional 50 megabytes of data. // not be bigger, but it will able to hold additional 50 megabytes of data.
// We need extra room for icons and background image. When we providing // We need extra room for icons and background image. When we providing
@ -344,7 +347,7 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
hdiUtilVerbosityFlag, hdiUtilVerbosityFlag,
"-size", String.valueOf(size), "-size", String.valueOf(size),
"-volname", APP_NAME.fetchFrom(params), "-volname", APP_NAME.fetchFrom(params),
"-ov", protoDMG.getAbsolutePath(), "-ov", protoDMG.toAbsolutePath().toString(),
"-fs", "HFS+"); "-fs", "HFS+");
IOUtils.exec(pb); IOUtils.exec(pb);
} }
@ -353,13 +356,12 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
pb = new ProcessBuilder( pb = new ProcessBuilder(
hdiutil, hdiutil,
"attach", "attach",
protoDMG.getAbsolutePath(), protoDMG.toAbsolutePath().toString(),
hdiUtilVerbosityFlag, hdiUtilVerbosityFlag,
"-mountroot", imagesRoot.getAbsolutePath()); "-mountroot", imagesRoot.toAbsolutePath().toString());
IOUtils.exec(pb, false, null, true); IOUtils.exec(pb, false, null, true);
File mountedRoot = new File(imagesRoot.getAbsolutePath(), Path mountedRoot = imagesRoot.resolve(APP_NAME.fetchFrom(params));
APP_NAME.fetchFrom(params));
// Copy app image, since we did not create DMG with it, but instead we created // Copy app image, since we did not create DMG with it, but instead we created
// empty one. // empty one.
@ -367,36 +369,36 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
// In case of predefine app image srcFolder will point to app bundle, so if // In case of predefine app image srcFolder will point to app bundle, so if
// we use it as is we will copy content of app bundle, but we need app bundle // we use it as is we will copy content of app bundle, but we need app bundle
// folder as well. // folder as well.
if (srcFolder.toPath().toString().toLowerCase().endsWith(".app")) { if (srcFolder.toString().toLowerCase().endsWith(".app")) {
Path destPath = mountedRoot.toPath() Path destPath = mountedRoot
.resolve(srcFolder.toPath().getFileName()); .resolve(srcFolder.getFileName());
Files.createDirectory(destPath); Files.createDirectory(destPath);
IOUtils.copyRecursive(srcFolder.toPath(), destPath); IOUtils.copyRecursive(srcFolder, destPath);
} else { } else {
IOUtils.copyRecursive(srcFolder.toPath(), mountedRoot.toPath()); IOUtils.copyRecursive(srcFolder, mountedRoot);
} }
} }
try { try {
// background image // background image
File bgdir = new File(mountedRoot, BACKGROUND_IMAGE_FOLDER); Path bgdir = mountedRoot.resolve(BACKGROUND_IMAGE_FOLDER);
bgdir.mkdirs(); Files.createDirectories(bgdir);
IOUtils.copyFile(getConfig_VolumeBackground(params), IOUtils.copyFile(getConfig_VolumeBackground(params),
new File(bgdir, BACKGROUND_IMAGE)); bgdir.resolve(BACKGROUND_IMAGE));
// We will not consider setting background image and creating link // We will not consider setting background image and creating link
// to install-dir in DMG as critical error, since it can fail in // to install-dir in DMG as critical error, since it can fail in
// headless enviroment. // headless enviroment.
try { try {
pb = new ProcessBuilder("osascript", pb = new ProcessBuilder("osascript",
getConfig_VolumeScript(params).getAbsolutePath()); getConfig_VolumeScript(params).toAbsolutePath().toString());
IOUtils.exec(pb); IOUtils.exec(pb);
} catch (IOException ex) { } catch (IOException ex) {
Log.verbose(ex); Log.verbose(ex);
} }
// volume icon // volume icon
File volumeIconFile = new File(mountedRoot, ".VolumeIcon.icns"); Path volumeIconFile = mountedRoot.resolve(".VolumeIcon.icns");
IOUtils.copyFile(getConfig_VolumeIcon(params), IOUtils.copyFile(getConfig_VolumeIcon(params),
volumeIconFile); volumeIconFile);
@ -408,7 +410,7 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
if (setFileUtility != null) { if (setFileUtility != null) {
//can not find utility => keep going without icon //can not find utility => keep going without icon
try { try {
volumeIconFile.setWritable(true); volumeIconFile.toFile().setWritable(true);
// The "creator" attribute on a file is a legacy attribute // The "creator" attribute on a file is a legacy attribute
// but it seems Finder excepts these bytes to be // but it seems Finder excepts these bytes to be
// "icnC" for the volume icon // "icnC" for the volume icon
@ -416,14 +418,14 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
pb = new ProcessBuilder( pb = new ProcessBuilder(
setFileUtility, setFileUtility,
"-c", "icnC", "-c", "icnC",
volumeIconFile.getAbsolutePath()); volumeIconFile.toAbsolutePath().toString());
IOUtils.exec(pb); IOUtils.exec(pb);
volumeIconFile.setReadOnly(); volumeIconFile.toFile().setReadOnly();
pb = new ProcessBuilder( pb = new ProcessBuilder(
setFileUtility, setFileUtility,
"-a", "C", "-a", "C",
mountedRoot.getAbsolutePath()); mountedRoot.toAbsolutePath().toString());
IOUtils.exec(pb); IOUtils.exec(pb);
} catch (IOException ex) { } catch (IOException ex) {
Log.error(ex.getMessage()); Log.error(ex.getMessage());
@ -440,7 +442,7 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
"detach", "detach",
"-force", "-force",
hdiUtilVerbosityFlag, hdiUtilVerbosityFlag,
mountedRoot.getAbsolutePath()); mountedRoot.toAbsolutePath().toString());
IOUtils.exec(pb); IOUtils.exec(pb);
} }
@ -448,19 +450,19 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
pb = new ProcessBuilder( pb = new ProcessBuilder(
hdiutil, hdiutil,
"convert", "convert",
protoDMG.getAbsolutePath(), protoDMG.toAbsolutePath().toString(),
hdiUtilVerbosityFlag, hdiUtilVerbosityFlag,
"-format", "UDZO", "-format", "UDZO",
"-o", finalDMG.getAbsolutePath()); "-o", finalDMG.toAbsolutePath().toString());
IOUtils.exec(pb); IOUtils.exec(pb);
//add license if needed //add license if needed
if (getConfig_LicenseFile(params).exists()) { if (Files.exists(getConfig_LicenseFile(params))) {
//hdiutil unflatten your_image_file.dmg //hdiutil unflatten your_image_file.dmg
pb = new ProcessBuilder( pb = new ProcessBuilder(
hdiutil, hdiutil,
"unflatten", "unflatten",
finalDMG.getAbsolutePath() finalDMG.toAbsolutePath().toString()
); );
IOUtils.exec(pb); IOUtils.exec(pb);
@ -468,9 +470,9 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
pb = new ProcessBuilder( pb = new ProcessBuilder(
hdiutil, hdiutil,
"udifrez", "udifrez",
finalDMG.getAbsolutePath(), finalDMG.toAbsolutePath().toString(),
"-xml", "-xml",
getConfig_LicenseFile(params).getAbsolutePath() getConfig_LicenseFile(params).toAbsolutePath().toString()
); );
IOUtils.exec(pb); IOUtils.exec(pb);
@ -478,18 +480,18 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
pb = new ProcessBuilder( pb = new ProcessBuilder(
hdiutil, hdiutil,
"flatten", "flatten",
finalDMG.getAbsolutePath() finalDMG.toAbsolutePath().toString()
); );
IOUtils.exec(pb); IOUtils.exec(pb);
} }
//Delete the temporary image //Delete the temporary image
protoDMG.delete(); Files.deleteIfExists(protoDMG);
Log.verbose(MessageFormat.format(I18N.getString( Log.verbose(MessageFormat.format(I18N.getString(
"message.output-to-location"), "message.output-to-location"),
APP_NAME.fetchFrom(params), finalDMG.getAbsolutePath())); APP_NAME.fetchFrom(params), finalDMG.toAbsolutePath().toString()));
return finalDMG; return finalDMG;
} }
@ -530,8 +532,8 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
} }
@Override @Override
public File execute(Map<String, ? super Object> params, public Path execute(Map<String, ? super Object> params,
File outputParentDir) throws PackagerException { Path outputParentDir) throws PackagerException {
return bundle(params, outputParentDir); return bundle(params, outputParentDir);
} }
@ -545,8 +547,8 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
public static boolean isSupported() { public static boolean isSupported() {
try { try {
for (String s : required) { for (String s : required) {
File f = new File(s); Path f = Path.of(s);
if (!f.exists() || !f.canExecute()) { if (!Files.exists(f) || !Files.isExecutable(f)) {
return false; return false;
} }
} }

View File

@ -25,7 +25,6 @@
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.net.URI; import java.net.URI;
@ -64,30 +63,38 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
private static final String TEMPLATE_POSTINSTALL_SCRIPT = private static final String TEMPLATE_POSTINSTALL_SCRIPT =
"postinstall.template"; "postinstall.template";
private static final BundlerParamInfo<File> PACKAGES_ROOT = private static final BundlerParamInfo<Path> PACKAGES_ROOT =
new StandardBundlerParam<>( new StandardBundlerParam<>(
"mac.pkg.packagesRoot", "mac.pkg.packagesRoot",
File.class, Path.class,
params -> { params -> {
File packagesRoot = Path packagesRoot =
new File(TEMP_ROOT.fetchFrom(params), "packages"); TEMP_ROOT.fetchFrom(params).resolve("packages");
packagesRoot.mkdirs(); try {
Files.createDirectories(packagesRoot);
} catch (IOException ioe) {
return null;
}
return packagesRoot; return packagesRoot;
}, },
(s, p) -> new File(s)); (s, p) -> Path.of(s));
protected final BundlerParamInfo<File> SCRIPTS_DIR = protected final BundlerParamInfo<Path> SCRIPTS_DIR =
new StandardBundlerParam<>( new StandardBundlerParam<>(
"mac.pkg.scriptsDir", "mac.pkg.scriptsDir",
File.class, Path.class,
params -> { params -> {
File scriptsDir = Path scriptsDir =
new File(CONFIG_ROOT.fetchFrom(params), "scripts"); CONFIG_ROOT.fetchFrom(params).resolve("scripts");
scriptsDir.mkdirs(); try {
Files.createDirectories(scriptsDir);
} catch (IOException ioe) {
return null;
}
return scriptsDir; return scriptsDir;
}, },
(s, p) -> new File(s)); (s, p) -> Path.of(s));
public static final public static final
BundlerParamInfo<String> DEVELOPER_ID_INSTALLER_SIGNING_KEY = BundlerParamInfo<String> DEVELOPER_ID_INSTALLER_SIGNING_KEY =
@ -121,23 +128,23 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
params -> "", params -> "",
(s, p) -> s); (s, p) -> s);
public File bundle(Map<String, ? super Object> params, public Path bundle(Map<String, ? super Object> params,
File outdir) throws PackagerException { Path outdir) throws PackagerException {
Log.verbose(MessageFormat.format(I18N.getString("message.building-pkg"), Log.verbose(MessageFormat.format(I18N.getString("message.building-pkg"),
APP_NAME.fetchFrom(params))); APP_NAME.fetchFrom(params)));
IOUtils.writableOutputDir(outdir.toPath()); IOUtils.writableOutputDir(outdir);
try { try {
File appImageDir = prepareAppBundle(params); Path appImageDir = prepareAppBundle(params);
if (appImageDir != null && prepareConfigFiles(params)) { if (appImageDir != null && prepareConfigFiles(params)) {
File configScript = getConfig_Script(params); Path configScript = getConfig_Script(params);
if (configScript.exists()) { if (IOUtils.exists(configScript)) {
Log.verbose(MessageFormat.format(I18N.getString( Log.verbose(MessageFormat.format(I18N.getString(
"message.running-script"), "message.running-script"),
configScript.getAbsolutePath())); configScript.toAbsolutePath().toString()));
IOUtils.run("bash", configScript); IOUtils.run("bash", configScript);
} }
@ -150,33 +157,33 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
} }
} }
private File getPackages_AppPackage(Map<String, ? super Object> params) { private Path getPackages_AppPackage(Map<String, ? super Object> params) {
return new File(PACKAGES_ROOT.fetchFrom(params), return PACKAGES_ROOT.fetchFrom(params).resolve(
APP_NAME.fetchFrom(params) + "-app.pkg"); APP_NAME.fetchFrom(params) + "-app.pkg");
} }
private File getConfig_DistributionXMLFile( private Path getConfig_DistributionXMLFile(
Map<String, ? super Object> params) { Map<String, ? super Object> params) {
return new File(CONFIG_ROOT.fetchFrom(params), "distribution.dist"); return CONFIG_ROOT.fetchFrom(params).resolve("distribution.dist");
} }
private File getConfig_BackgroundImage(Map<String, ? super Object> params) { private Path getConfig_BackgroundImage(Map<String, ? super Object> params) {
return new File(CONFIG_ROOT.fetchFrom(params), return CONFIG_ROOT.fetchFrom(params).resolve(
APP_NAME.fetchFrom(params) + "-background.png"); APP_NAME.fetchFrom(params) + "-background.png");
} }
private File getConfig_BackgroundImageDarkAqua(Map<String, ? super Object> params) { private Path getConfig_BackgroundImageDarkAqua(Map<String, ? super Object> params) {
return new File(CONFIG_ROOT.fetchFrom(params), return CONFIG_ROOT.fetchFrom(params).resolve(
APP_NAME.fetchFrom(params) + "-background-darkAqua.png"); APP_NAME.fetchFrom(params) + "-background-darkAqua.png");
} }
private File getScripts_PreinstallFile(Map<String, ? super Object> params) { private Path getScripts_PreinstallFile(Map<String, ? super Object> params) {
return new File(SCRIPTS_DIR.fetchFrom(params), "preinstall"); return SCRIPTS_DIR.fetchFrom(params).resolve("preinstall");
} }
private File getScripts_PostinstallFile( private Path getScripts_PostinstallFile(
Map<String, ? super Object> params) { Map<String, ? super Object> params) {
return new File(SCRIPTS_DIR.fetchFrom(params), "postinstall"); return SCRIPTS_DIR.fetchFrom(params).resolve("postinstall");
} }
private String getAppIdentifier(Map<String, ? super Object> params) { private String getAppIdentifier(Map<String, ? super Object> params) {
@ -199,13 +206,13 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
.setCategory(I18N.getString("resource.pkg-preinstall-script")) .setCategory(I18N.getString("resource.pkg-preinstall-script"))
.setSubstitutionData(data) .setSubstitutionData(data)
.saveToFile(getScripts_PreinstallFile(params)); .saveToFile(getScripts_PreinstallFile(params));
getScripts_PreinstallFile(params).setExecutable(true, false); getScripts_PreinstallFile(params).toFile().setExecutable(true, false);
createResource(TEMPLATE_POSTINSTALL_SCRIPT, params) createResource(TEMPLATE_POSTINSTALL_SCRIPT, params)
.setCategory(I18N.getString("resource.pkg-postinstall-script")) .setCategory(I18N.getString("resource.pkg-postinstall-script"))
.setSubstitutionData(data) .setSubstitutionData(data)
.saveToFile(getScripts_PostinstallFile(params)); .saveToFile(getScripts_PostinstallFile(params));
getScripts_PostinstallFile(params).setExecutable(true, false); getScripts_PostinstallFile(params).toFile().setExecutable(true, false);
} }
private static String URLEncoding(String pkgName) throws URISyntaxException { private static String URLEncoding(String pkgName) throws URISyntaxException {
@ -215,12 +222,12 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
private void prepareDistributionXMLFile(Map<String, ? super Object> params) private void prepareDistributionXMLFile(Map<String, ? super Object> params)
throws IOException { throws IOException {
File f = getConfig_DistributionXMLFile(params); Path f = getConfig_DistributionXMLFile(params);
Log.verbose(MessageFormat.format(I18N.getString( Log.verbose(MessageFormat.format(I18N.getString(
"message.preparing-distribution-dist"), f.getAbsolutePath())); "message.preparing-distribution-dist"), f.toAbsolutePath().toString()));
IOUtils.createXml(f.toPath(), xml -> { IOUtils.createXml(f, xml -> {
xml.writeStartElement("installer-gui-script"); xml.writeStartElement("installer-gui-script");
xml.writeAttribute("minSpecVersion", "1"); xml.writeAttribute("minSpecVersion", "1");
@ -229,14 +236,16 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
xml.writeEndElement(); xml.writeEndElement();
xml.writeStartElement("background"); xml.writeStartElement("background");
xml.writeAttribute("file", getConfig_BackgroundImage(params).getName()); xml.writeAttribute("file",
getConfig_BackgroundImage(params).getFileName().toString());
xml.writeAttribute("mime-type", "image/png"); xml.writeAttribute("mime-type", "image/png");
xml.writeAttribute("alignment", "bottomleft"); xml.writeAttribute("alignment", "bottomleft");
xml.writeAttribute("scaling", "none"); xml.writeAttribute("scaling", "none");
xml.writeEndElement(); xml.writeEndElement();
xml.writeStartElement("background-darkAqua"); xml.writeStartElement("background-darkAqua");
xml.writeAttribute("file", getConfig_BackgroundImageDarkAqua(params).getName()); xml.writeAttribute("file",
getConfig_BackgroundImageDarkAqua(params).getFileName().toString());
xml.writeAttribute("mime-type", "image/png"); xml.writeAttribute("mime-type", "image/png");
xml.writeAttribute("alignment", "bottomleft"); xml.writeAttribute("alignment", "bottomleft");
xml.writeAttribute("scaling", "none"); xml.writeAttribute("scaling", "none");
@ -244,9 +253,9 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
String licFileStr = LICENSE_FILE.fetchFrom(params); String licFileStr = LICENSE_FILE.fetchFrom(params);
if (licFileStr != null) { if (licFileStr != null) {
File licFile = new File(licFileStr); Path licFile = Path.of(licFileStr);
xml.writeStartElement("license"); xml.writeStartElement("license");
xml.writeAttribute("file", licFile.getAbsolutePath()); xml.writeAttribute("file", licFile.toAbsolutePath().toString());
xml.writeAttribute("mime-type", "text/rtf"); xml.writeAttribute("mime-type", "text/rtf");
xml.writeEndElement(); xml.writeEndElement();
} }
@ -288,7 +297,7 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
xml.writeAttribute("onConclusion", "none"); xml.writeAttribute("onConclusion", "none");
try { try {
xml.writeCharacters(URLEncoding( xml.writeCharacters(URLEncoding(
getPackages_AppPackage(params).getName())); getPackages_AppPackage(params).getFileName().toString()));
} catch (URISyntaxException ex) { } catch (URISyntaxException ex) {
throw new IOException(ex); throw new IOException(ex);
} }
@ -319,16 +328,15 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
} }
// name of post-image script // name of post-image script
private File getConfig_Script(Map<String, ? super Object> params) { private Path getConfig_Script(Map<String, ? super Object> params) {
return new File(CONFIG_ROOT.fetchFrom(params), return CONFIG_ROOT.fetchFrom(params).resolve(
APP_NAME.fetchFrom(params) + "-post-image.sh"); APP_NAME.fetchFrom(params) + "-post-image.sh");
} }
private void patchCPLFile(File cpl) throws IOException { private void patchCPLFile(Path cpl) throws IOException {
String cplData = Files.readString(cpl.toPath()); String cplData = Files.readString(cpl);
String[] lines = cplData.split("\n"); String[] lines = cplData.split("\n");
try (PrintWriter out = new PrintWriter(Files.newBufferedWriter( try (PrintWriter out = new PrintWriter(Files.newBufferedWriter(cpl))) {
cpl.toPath()))) {
int skip = 0; int skip = 0;
// Used to skip Java.runtime bundle, since // Used to skip Java.runtime bundle, since
// pkgbuild with --root will find two bundles app and Java runtime. // pkgbuild with --root will find two bundles app and Java runtime.
@ -360,35 +368,34 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
// So easy aproach will be to copy user provided app-image into temp folder // So easy aproach will be to copy user provided app-image into temp folder
// if root path contains other files. // if root path contains other files.
private String getRoot(Map<String, ? super Object> params, private String getRoot(Map<String, ? super Object> params,
File appLocation) throws IOException { Path appLocation) throws IOException {
String root = appLocation.getParent() == null ? Path rootDir = appLocation.getParent() == null ?
"." : appLocation.getParent(); Path.of(".") : appLocation.getParent();
File rootDir = new File(root);
File[] list = rootDir.listFiles(); Path[] list = Files.list(rootDir).toArray(Path[]::new);
if (list != null) { // Should not happend if (list != null) { // Should not happend
// We should only have app image and/or .DS_Store // We should only have app image and/or .DS_Store
if (list.length == 1) { if (list.length == 1) {
return root; return rootDir.toString();
} else if (list.length == 2) { } else if (list.length == 2) {
// Check case with app image and .DS_Store // Check case with app image and .DS_Store
if (list[0].toString().toLowerCase().endsWith(".ds_store") || if (list[0].toString().toLowerCase().endsWith(".ds_store") ||
list[1].toString().toLowerCase().endsWith(".ds_store")) { list[1].toString().toLowerCase().endsWith(".ds_store")) {
return root; // Only app image and .DS_Store return rootDir.toString(); // Only app image and .DS_Store
} }
} }
} }
// Copy to new root // Copy to new root
Path newRoot = Files.createTempDirectory( Path newRoot = Files.createTempDirectory(
TEMP_ROOT.fetchFrom(params).toPath(), "root-"); TEMP_ROOT.fetchFrom(params), "root-");
Path source, dest; Path source, dest;
if (StandardBundlerParam.isRuntimeInstaller(params)) { if (StandardBundlerParam.isRuntimeInstaller(params)) {
// firs, is this already a runtime with // firs, is this already a runtime with
// <runtime>/Contents/Home - if so we need the Home dir // <runtime>/Contents/Home - if so we need the Home dir
Path original = appLocation.toPath(); Path original = appLocation;
Path home = original.resolve("Contents/Home"); Path home = original.resolve("Contents/Home");
source = (Files.exists(home)) ? home : original; source = (Files.exists(home)) ? home : original;
@ -396,32 +403,31 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
dest = newRoot.resolve( dest = newRoot.resolve(
MAC_CF_BUNDLE_IDENTIFIER.fetchFrom(params) + "/Contents/Home"); MAC_CF_BUNDLE_IDENTIFIER.fetchFrom(params) + "/Contents/Home");
} else { } else {
source = appLocation.toPath(); source = appLocation;
dest = newRoot.resolve(appLocation.getName()); dest = newRoot.resolve(appLocation.getFileName());
} }
IOUtils.copyRecursive(source, dest); IOUtils.copyRecursive(source, dest);
return newRoot.toString(); return newRoot.toString();
} }
private File createPKG(Map<String, ? super Object> params, private Path createPKG(Map<String, ? super Object> params,
File outdir, File appLocation) { Path outdir, Path appLocation) {
// generic find attempt // generic find attempt
try { try {
File appPKG = getPackages_AppPackage(params); Path appPKG = getPackages_AppPackage(params);
String root = getRoot(params, appLocation); String root = getRoot(params, appLocation);
// Generate default CPL file // Generate default CPL file
File cpl = new File(CONFIG_ROOT.fetchFrom(params).getAbsolutePath() Path cpl = CONFIG_ROOT.fetchFrom(params).resolve("cpl.plist");
+ File.separator + "cpl.plist");
ProcessBuilder pb = new ProcessBuilder("pkgbuild", ProcessBuilder pb = new ProcessBuilder("pkgbuild",
"--root", "--root",
root, root,
"--install-location", "--install-location",
getInstallDir(params), getInstallDir(params),
"--analyze", "--analyze",
cpl.getAbsolutePath()); cpl.toAbsolutePath().toString());
IOUtils.exec(pb); IOUtils.exec(pb);
@ -436,25 +442,25 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
"--install-location", "--install-location",
getInstallDir(params), getInstallDir(params),
"--component-plist", "--component-plist",
cpl.getAbsolutePath(), cpl.toAbsolutePath().toString(),
"--scripts", "--scripts",
SCRIPTS_DIR.fetchFrom(params).getAbsolutePath(), SCRIPTS_DIR.fetchFrom(params).toAbsolutePath().toString(),
"--identifier", "--identifier",
MAC_CF_BUNDLE_IDENTIFIER.fetchFrom(params), MAC_CF_BUNDLE_IDENTIFIER.fetchFrom(params),
appPKG.getAbsolutePath()); appPKG.toAbsolutePath().toString());
IOUtils.exec(pb); IOUtils.exec(pb);
// build final package // build final package
File finalPKG = new File(outdir, INSTALLER_NAME.fetchFrom(params) Path finalPKG = outdir.resolve(INSTALLER_NAME.fetchFrom(params)
+ INSTALLER_SUFFIX.fetchFrom(params) + INSTALLER_SUFFIX.fetchFrom(params)
+ ".pkg"); + ".pkg");
outdir.mkdirs(); Files.createDirectories(outdir);
List<String> commandLine = new ArrayList<>(); List<String> commandLine = new ArrayList<>();
commandLine.add("productbuild"); commandLine.add("productbuild");
commandLine.add("--resources"); commandLine.add("--resources");
commandLine.add(CONFIG_ROOT.fetchFrom(params).getAbsolutePath()); commandLine.add(CONFIG_ROOT.fetchFrom(params).toAbsolutePath().toString());
// maybe sign // maybe sign
if (Optional.ofNullable(MacAppImageBuilder. if (Optional.ofNullable(MacAppImageBuilder.
@ -482,11 +488,11 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
commandLine.add("--distribution"); commandLine.add("--distribution");
commandLine.add( commandLine.add(
getConfig_DistributionXMLFile(params).getAbsolutePath()); getConfig_DistributionXMLFile(params).toAbsolutePath().toString());
commandLine.add("--package-path"); commandLine.add("--package-path");
commandLine.add(PACKAGES_ROOT.fetchFrom(params).getAbsolutePath()); commandLine.add(PACKAGES_ROOT.fetchFrom(params).toAbsolutePath().toString());
commandLine.add(finalPKG.getAbsolutePath()); commandLine.add(finalPKG.toAbsolutePath().toString());
pb = new ProcessBuilder(commandLine); pb = new ProcessBuilder(commandLine);
IOUtils.exec(pb); IOUtils.exec(pb);
@ -577,8 +583,8 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
} }
@Override @Override
public File execute(Map<String, ? super Object> params, public Path execute(Map<String, ? super Object> params,
File outputParentDir) throws PackagerException { Path outputParentDir) throws PackagerException {
return bundle(params, outputParentDir); return bundle(params, outputParentDir);
} }

View File

@ -25,7 +25,6 @@
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Path; import java.nio.file.Path;
@ -79,7 +78,7 @@ public abstract class AbstractAppImageBuilder {
} }
public static OverridableResource createIconResource(String defaultIconName, public static OverridableResource createIconResource(String defaultIconName,
BundlerParamInfo<File> iconParam, Map<String, ? super Object> params, BundlerParamInfo<Path> iconParam, Map<String, ? super Object> params,
Map<String, ? super Object> mainParams) throws IOException { Map<String, ? super Object> mainParams) throws IOException {
if (mainParams != null) { if (mainParams != null) {
@ -119,12 +118,12 @@ public abstract class AbstractAppImageBuilder {
private enum IconType { DefaultOrResourceDirIcon, CustomIcon, NoIcon }; private enum IconType { DefaultOrResourceDirIcon, CustomIcon, NoIcon };
private static IconType getLauncherIconType(Map<String, ? super Object> params) { private static IconType getLauncherIconType(Map<String, ? super Object> params) {
File launcherIcon = ICON.fetchFrom(params); Path launcherIcon = ICON.fetchFrom(params);
if (launcherIcon == null) { if (launcherIcon == null) {
return IconType.DefaultOrResourceDirIcon; return IconType.DefaultOrResourceDirIcon;
} }
if (launcherIcon.getName().isEmpty()) { if (launcherIcon.toFile().getName().isEmpty()) {
return IconType.NoIcon; return IconType.NoIcon;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,8 +25,8 @@
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path;
import java.util.Map; import java.util.Map;
@ -39,12 +39,12 @@ import java.util.Map;
*/ */
abstract class AbstractBundler implements Bundler { abstract class AbstractBundler implements Bundler {
static final BundlerParamInfo<File> IMAGES_ROOT = static final BundlerParamInfo<Path> IMAGES_ROOT =
new StandardBundlerParam<>( new StandardBundlerParam<>(
"imagesRoot", "imagesRoot",
File.class, Path.class,
params -> new File( params ->
StandardBundlerParam.TEMP_ROOT.fetchFrom(params), "images"), StandardBundlerParam.TEMP_ROOT.fetchFrom(params).resolve("images"),
(s, p) -> null); (s, p) -> null);
@Override @Override

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,9 +25,9 @@
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.nio.file.Path;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.io.File;
import java.util.List; import java.util.List;
import jdk.incubator.jpackage.internal.Arguments.CLIOptions; import jdk.incubator.jpackage.internal.Arguments.CLIOptions;
@ -116,7 +116,7 @@ class AddLauncherArguments {
String value = getOptionValue(CLIOptions.ICON); String value = getOptionValue(CLIOptions.ICON);
Arguments.putUnlessNull(bundleParams, CLIOptions.ICON.getId(), Arguments.putUnlessNull(bundleParams, CLIOptions.ICON.getId(),
(value == null) ? null : new File(value)); (value == null) ? null : Path.of(value));
// "arguments" and "java-options" even if value is null: // "arguments" and "java-options" even if value is null:
if (allArgs.containsKey(CLIOptions.ARGUMENTS.getId())) { if (allArgs.containsKey(CLIOptions.ARGUMENTS.getId())) {

View File

@ -25,7 +25,6 @@
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@ -82,14 +81,14 @@ class AppImageBundler extends AbstractBundler {
} }
@Override @Override
final public File execute(Map<String, ? super Object> params, final public Path execute(Map<String, ? super Object> params,
File outputParentDir) throws PackagerException { Path outputParentDir) throws PackagerException {
if (StandardBundlerParam.isRuntimeInstaller(params)) { if (StandardBundlerParam.isRuntimeInstaller(params)) {
return PREDEFINED_RUNTIME_IMAGE.fetchFrom(params); return PREDEFINED_RUNTIME_IMAGE.fetchFrom(params);
} }
try { try {
return createAppBundle(params, outputParentDir.toPath()).toFile(); return createAppBundle(params, outputParentDir);
} catch (PackagerException pe) { } catch (PackagerException pe) {
throw pe; throw pe;
} catch (RuntimeException|IOException|ConfigException ex) { } catch (RuntimeException|IOException|ConfigException ex) {

View File

@ -24,8 +24,8 @@
*/ */
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -192,7 +192,7 @@ public class AppImageFile {
"http://apache.org/xml/features/nonvalidating/load-external-dtd", "http://apache.org/xml/features/nonvalidating/load-external-dtd",
false); false);
DocumentBuilder b = dbf.newDocumentBuilder(); DocumentBuilder b = dbf.newDocumentBuilder();
return b.parse(new FileInputStream(path.toFile())); return b.parse(Files.newInputStream(path));
} catch (ParserConfigurationException | SAXException ex) { } catch (ParserConfigurationException | SAXException ex) {
// Let caller sort this out // Let caller sort this out
throw new IOException(ex); throw new IOException(ex);

View File

@ -24,9 +24,10 @@
*/ */
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
@ -89,7 +90,7 @@ public class Arguments {
private List<CLIOptions> allOptions = null; private List<CLIOptions> allOptions = null;
private String input = null; private String input = null;
private String output = null; private Path output = null;
private boolean hasMainJar = false; private boolean hasMainJar = false;
private boolean hasMainClass = false; private boolean hasMainClass = false;
@ -130,8 +131,8 @@ public class Arguments {
addLaunchers = new ArrayList<>(); addLaunchers = new ArrayList<>();
output = Paths.get("").toAbsolutePath().toString(); output = Paths.get("").toAbsolutePath();
deployParams.setOutput(new File(output)); deployParams.setOutput(output);
} }
// CLIOptions is public for DeployParamsTest // CLIOptions is public for DeployParamsTest
@ -146,8 +147,8 @@ public class Arguments {
}), }),
OUTPUT ("dest", "d", OptionCategories.PROPERTY, () -> { OUTPUT ("dest", "d", OptionCategories.PROPERTY, () -> {
context().output = popArg(); context().output = Path.of(popArg());
context().deployParams.setOutput(new File(context().output)); context().deployParams.setOutput(context().output);
}), }),
DESCRIPTION ("description", OptionCategories.PROPERTY), DESCRIPTION ("description", OptionCategories.PROPERTY),
@ -670,7 +671,7 @@ public class Arguments {
Map<String, ? super Object> localParams = new HashMap<>(params); Map<String, ? super Object> localParams = new HashMap<>(params);
try { try {
bundler.validate(localParams); bundler.validate(localParams);
File result = bundler.execute(localParams, deployParams.outdir); Path result = bundler.execute(localParams, deployParams.outdir);
if (result == null) { if (result == null) {
throw new PackagerException("MSG_BundlerFailed", throw new PackagerException("MSG_BundlerFailed",
bundler.getID(), bundler.getName()); bundler.getID(), bundler.getName());
@ -696,7 +697,7 @@ public class Arguments {
if (userProvidedBuildRoot) { if (userProvidedBuildRoot) {
Log.verbose(MessageFormat.format( Log.verbose(MessageFormat.format(
I18N.getString("message.debug-working-directory"), I18N.getString("message.debug-working-directory"),
(new File(buildRoot)).getAbsolutePath())); (Path.of(buildRoot)).toAbsolutePath().toString()));
} else { } else {
// always clean up the temporary directory created // always clean up the temporary directory created
// when --temp option not used. // when --temp option not used.
@ -716,10 +717,9 @@ public class Arguments {
static Map<String, String> getPropertiesFromFile(String filename) { static Map<String, String> getPropertiesFromFile(String filename) {
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
// load properties file // load properties file
File file = new File(filename);
Properties properties = new Properties(); Properties properties = new Properties();
try (FileInputStream in = new FileInputStream(file)) { try (Reader reader = Files.newBufferedReader(Path.of(filename))) {
properties.load(in); properties.load(reader);
} catch (IOException e) { } catch (IOException e) {
Log.error("Exception: " + e.getMessage()); Log.error("Exception: " + e.getMessage());
} }
@ -808,11 +808,11 @@ public class Arguments {
JarFile jf; JarFile jf;
try { try {
File file = new File(input, mainJarPath); Path file = Path.of(input, mainJarPath);
if (!file.exists()) { if (!Files.exists(file)) {
return null; return null;
} }
jf = new JarFile(file); jf = new JarFile(file.toFile());
Manifest m = jf.getManifest(); Manifest m = jf.getManifest();
Attributes attrs = (m != null) ? m.getMainAttributes() : null; Attributes attrs = (m != null) ? m.getMainAttributes() : null;
if (attrs != null) { if (attrs != null) {

View File

@ -25,7 +25,6 @@
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,7 +25,7 @@
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.File; import java.nio.file.Path;
import java.util.Map; import java.util.Map;
/** /**
@ -104,8 +104,8 @@ public interface Bundler {
* forward slashes.</li> * forward slashes.</li>
* </ul> * </ul>
*/ */
public File execute(Map<String, ? super Object> params, public Path execute(Map<String, ? super Object> params,
File outputParentDir) throws PackagerException; Path outputParentDir) throws PackagerException;
/** /**
* Removes temporary files that are used for bundling. * Removes temporary files that are used for bundling.

View File

@ -26,6 +26,7 @@
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.InvalidPathException; import java.nio.file.InvalidPathException;
@ -37,6 +38,8 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* DeployParams * DeployParams
@ -48,20 +51,20 @@ public class DeployParams {
String targetFormat = null; // means default type for this platform String targetFormat = null; // means default type for this platform
File outdir = null; Path outdir = null;
// raw arguments to the bundler // raw arguments to the bundler
Map<String, ? super Object> bundlerArguments = new LinkedHashMap<>(); Map<String, ? super Object> bundlerArguments = new LinkedHashMap<>();
public void setOutput(File output) { public void setOutput(Path output) {
outdir = output; outdir = output;
} }
static class Template { static class Template {
File in; Path in;
File out; Path out;
Template(File in, File out) { Template(Path in, Path out) {
this.in = in; this.in = in;
this.out = out; this.out = out;
} }
@ -72,15 +75,19 @@ public class DeployParams {
// we may get "." as filename and assumption is we include // we may get "." as filename and assumption is we include
// everything in the given folder // everything in the given folder
// (IOUtils.copyfiles() have recursive behavior) // (IOUtils.copyfiles() have recursive behavior)
List<File> expandFileset(File root) { List<Path> expandFileset(Path root) throws IOException {
List<File> files = new LinkedList<>(); List<Path> files = new LinkedList<>();
if (!Files.isSymbolicLink(root.toPath())) { if (!Files.isSymbolicLink(root)) {
if (root.isDirectory()) { if (Files.isDirectory(root)) {
File[] children = root.listFiles(); List<Path> children = Files.list(root).collect(Collectors.toList());
if (children != null && children.length > 0) { if (children != null && children.size() > 0) {
for (File f : children) { children.forEach(f -> {
try {
files.addAll(expandFileset(f)); files.addAll(expandFileset(f));
} catch (IOException ex) {
throw new RuntimeException(ex);
} }
});
} else { } else {
// Include empty folders // Include empty folders
files.add(root); files.add(root);
@ -110,7 +117,7 @@ public class DeployParams {
} }
try { try {
// name must be valid path element for this file system // name must be valid path element for this file system
Path p = (new File(s)).toPath(); Path p = Path.of(s);
// and it must be a single name element in a path // and it must be a single name element in a path
if (p.getNameCount() != 1) { if (p.getNameCount() != 1) {
throw new PackagerException(exceptionKey, s); throw new PackagerException(exceptionKey, s);
@ -198,8 +205,8 @@ public class DeployParams {
String appImage = (String)bundlerArguments.get( String appImage = (String)bundlerArguments.get(
Arguments.CLIOptions.PREDEFINED_APP_IMAGE.getId()); Arguments.CLIOptions.PREDEFINED_APP_IMAGE.getId());
if (appImage != null) { if (appImage != null) {
File appImageDir = new File(appImage); Path appImageDir = Path.of(appImage);
if (!appImageDir.exists() || appImageDir.list().length == 0) { if (!Files.exists(appImageDir) || appImageDir.toFile().list().length == 0) {
throw new PackagerException("ERR_AppImageNotExist", appImage); throw new PackagerException("ERR_AppImageNotExist", appImage);
} }
} }
@ -208,18 +215,23 @@ public class DeployParams {
String root = (String)bundlerArguments.get( String root = (String)bundlerArguments.get(
Arguments.CLIOptions.TEMP_ROOT.getId()); Arguments.CLIOptions.TEMP_ROOT.getId());
if (root != null) { if (root != null) {
String [] contents = (new File(root)).list(); try {
String [] contents = Files.list(Path.of(root))
.toArray(String[]::new);
if (contents != null && contents.length > 0) { if (contents != null && contents.length > 0) {
throw new PackagerException("ERR_BuildRootInvalid", root); throw new PackagerException("ERR_BuildRootInvalid", root);
} }
} catch (IOException ioe) {
throw new PackagerException(ioe);
}
} }
// Validate resource dir // Validate resource dir
String resources = (String)bundlerArguments.get( String resources = (String)bundlerArguments.get(
Arguments.CLIOptions.RESOURCE_DIR.getId()); Arguments.CLIOptions.RESOURCE_DIR.getId());
if (resources != null) { if (resources != null) {
if (!(new File(resources)).exists()) { if (!(Files.exists(Path.of(resources)))) {
throw new PackagerException( throw new PackagerException(
"message.resource-dir-does-not-exist", "message.resource-dir-does-not-exist",
Arguments.CLIOptions.RESOURCE_DIR.getId(), resources); Arguments.CLIOptions.RESOURCE_DIR.getId(), resources);
@ -230,7 +242,7 @@ public class DeployParams {
String runtime = (String)bundlerArguments.get( String runtime = (String)bundlerArguments.get(
Arguments.CLIOptions.PREDEFINED_RUNTIME_IMAGE.getId()); Arguments.CLIOptions.PREDEFINED_RUNTIME_IMAGE.getId());
if (runtime != null) { if (runtime != null) {
if (!(new File(runtime)).exists()) { if (!(Files.exists(Path.of(runtime)))) {
throw new PackagerException( throw new PackagerException(
"message.runtime-image-dir-does-not-exist", "message.runtime-image-dir-does-not-exist",
Arguments.CLIOptions.PREDEFINED_RUNTIME_IMAGE.getId(), Arguments.CLIOptions.PREDEFINED_RUNTIME_IMAGE.getId(),
@ -243,8 +255,7 @@ public class DeployParams {
String license = (String)bundlerArguments.get( String license = (String)bundlerArguments.get(
Arguments.CLIOptions.LICENSE_FILE.getId()); Arguments.CLIOptions.LICENSE_FILE.getId());
if (license != null) { if (license != null) {
File licenseFile = new File(license); if (!(Files.exists(Path.of(license)))) {
if (!licenseFile.exists()) {
throw new PackagerException("ERR_LicenseFileNotExit"); throw new PackagerException("ERR_LicenseFileNotExit");
} }
} }
@ -253,10 +264,9 @@ public class DeployParams {
String icon = (String)bundlerArguments.get( String icon = (String)bundlerArguments.get(
Arguments.CLIOptions.ICON.getId()); Arguments.CLIOptions.ICON.getId());
if (icon != null) { if (icon != null) {
File iconFile = new File(icon); if (!(Files.exists(Path.of(icon)))) {
if (!iconFile.exists()) {
throw new PackagerException("ERR_IconFileNotExit", throw new PackagerException("ERR_IconFileNotExit",
iconFile.getAbsolutePath()); Path.of(icon).toAbsolutePath().toString());
} }
} }
} }

View File

@ -25,10 +25,10 @@
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -82,12 +82,12 @@ final public class Executor {
output = null; output = null;
boolean needProcessOutput = outputConsumer != null || Log.isVerbose() || saveOutput; boolean needProcessOutput = outputConsumer != null || Log.isVerbose() || saveOutput;
File outputFile = null; Path outputFile = null;
if (needProcessOutput) { if (needProcessOutput) {
pb.redirectErrorStream(true); pb.redirectErrorStream(true);
if (writeOutputToFile) { if (writeOutputToFile) {
outputFile = File.createTempFile("jpackageOutputTempFile", ".tmp"); outputFile = Files.createTempFile("jpackageOutputTempFile", ".tmp");
pb.redirectOutput(outputFile); pb.redirectOutput(outputFile.toFile());
} }
} else { } else {
// We are not going to read process output, so need to notify // We are not going to read process output, so need to notify
@ -115,8 +115,8 @@ final public class Executor {
Supplier<Stream<String>> outputStream; Supplier<Stream<String>> outputStream;
if (writeOutputToFile) { if (writeOutputToFile) {
savedOutput = Files.readAllLines(outputFile.toPath()); savedOutput = Files.readAllLines(outputFile);
outputFile.delete(); Files.delete(outputFile);
outputStream = () -> { outputStream = () -> {
if (savedOutput != null) { if (savedOutput != null) {
return savedOutput.stream(); return savedOutput.stream();

View File

@ -25,7 +25,6 @@
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.File;
import java.nio.file.Path; import java.nio.file.Path;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.Collections; import java.util.Collections;
@ -86,9 +85,9 @@ final class FileAssociation {
assoc.mimeTypes = Optional.ofNullable( assoc.mimeTypes = Optional.ofNullable(
FA_CONTENT_TYPE.fetchFrom(fa)).orElse(Collections.emptyList()); FA_CONTENT_TYPE.fetchFrom(fa)).orElse(Collections.emptyList());
File icon = FA_ICON.fetchFrom(fa); Path icon = FA_ICON.fetchFrom(fa);
if (icon != null) { if (icon != null) {
assoc.iconPath = icon.toPath(); assoc.iconPath = icon;
} }
return assoc; return assoc;

View File

@ -28,7 +28,6 @@ package jdk.incubator.jpackage.internal;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.IOException; import java.io.IOException;
import java.io.File;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.Writer; import java.io.Writer;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationHandler;
@ -56,11 +55,11 @@ import javax.xml.stream.XMLStreamWriter;
*/ */
public class IOUtils { public class IOUtils {
public static void deleteRecursive(File path) throws IOException { public static void deleteRecursive(Path directory) throws IOException {
if (!path.exists()) { if (!Files.exists(directory)) {
return; return;
} }
Path directory = path.toPath();
Files.walkFileTree(directory, new SimpleFileVisitor<Path>() { Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
@Override @Override
public FileVisitResult visitFile(Path file, public FileVisitResult visitFile(Path file,
@ -119,22 +118,30 @@ public class IOUtils {
}); });
} }
public static void copyFile(File sourceFile, File destFile) public static void copyFile(Path sourceFile, Path destFile)
throws IOException { throws IOException {
Files.createDirectories(destFile.getParentFile().toPath()); Files.createDirectories(destFile.getParent());
Files.copy(sourceFile.toPath(), destFile.toPath(), Files.copy(sourceFile, destFile,
StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.REPLACE_EXISTING,
StandardCopyOption.COPY_ATTRIBUTES); StandardCopyOption.COPY_ATTRIBUTES);
} }
public static boolean exists(Path path) {
if (path == null) {
return false;
}
return Files.exists(path);
}
// run "launcher paramfile" in the directory where paramfile is kept // run "launcher paramfile" in the directory where paramfile is kept
public static void run(String launcher, File paramFile) public static void run(String launcher, Path paramFile)
throws IOException { throws IOException {
if (paramFile != null && paramFile.exists()) { if (IOUtils.exists(paramFile)) {
ProcessBuilder pb = ProcessBuilder pb =
new ProcessBuilder(launcher, paramFile.getName()); new ProcessBuilder(launcher, paramFile.getFileName().toString());
pb = pb.directory(paramFile.getParentFile()); pb = pb.directory(paramFile.getParent().toFile());
exec(pb); exec(pb);
} }
} }
@ -222,15 +229,18 @@ public class IOUtils {
} }
static void writableOutputDir(Path outdir) throws PackagerException { static void writableOutputDir(Path outdir) throws PackagerException {
File file = outdir.toFile(); if (!Files.isDirectory(outdir)) {
try {
if (!file.isDirectory() && !file.mkdirs()) { Files.createDirectories(outdir);
} catch (IOException ex) {
throw new PackagerException("error.cannot-create-output-dir", throw new PackagerException("error.cannot-create-output-dir",
file.getAbsolutePath()); outdir.toAbsolutePath().toString());
} }
if (!file.canWrite()) { }
if (!Files.isWritable(outdir)) {
throw new PackagerException("error.cannot-write-to-output-dir", throw new PackagerException("error.cannot-write-to-output-dir",
file.getAbsolutePath()); outdir.toAbsolutePath().toString());
} }
} }

View File

@ -145,7 +145,7 @@ final class LauncherData {
// Failed to find module in the specified module path list and // Failed to find module in the specified module path list and
// there is external runtime given to jpackage. // there is external runtime given to jpackage.
// Lookup module in this runtime. // Lookup module in this runtime.
Path cookedRuntime = PREDEFINED_RUNTIME_IMAGE.fetchFrom(params).toPath(); Path cookedRuntime = PREDEFINED_RUNTIME_IMAGE.fetchFrom(params);
launcherData.moduleInfo = ModuleInfo.fromCookedRuntime(moduleName, launcherData.moduleInfo = ModuleInfo.fromCookedRuntime(moduleName,
cookedRuntime); cookedRuntime);
} }
@ -293,7 +293,7 @@ final class LauncherData {
List<Path> modulePath = getPathListParameter(Arguments.CLIOptions.MODULE_PATH.getId(), params); List<Path> modulePath = getPathListParameter(Arguments.CLIOptions.MODULE_PATH.getId(), params);
if (params.containsKey(PREDEFINED_RUNTIME_IMAGE.getID())) { if (params.containsKey(PREDEFINED_RUNTIME_IMAGE.getID())) {
Path runtimePath = PREDEFINED_RUNTIME_IMAGE.fetchFrom(params).toPath(); Path runtimePath = PREDEFINED_RUNTIME_IMAGE.fetchFrom(params);
runtimePath = runtimePath.resolve("lib"); runtimePath = runtimePath.resolve("lib");
modulePath = Stream.of(modulePath, List.of(runtimePath)) modulePath = Stream.of(modulePath, List.of(runtimePath))
.flatMap(List::stream) .flatMap(List::stream)

View File

@ -24,7 +24,6 @@
*/ */
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@ -200,7 +199,7 @@ final class PathGroup {
for (var action: entries) { for (var action: entries) {
Path src = action.getKey(); Path src = action.getKey();
Path dst = action.getValue(); Path dst = action.getValue();
if (src.toFile().isDirectory()) { if (Files.isDirectory(src)) {
try (Stream<Path> stream = Files.walk(src)) { try (Stream<Path> stream = Files.walk(src)) {
stream.sequential().forEach(path -> actions.put(dst.resolve( stream.sequential().forEach(path -> actions.put(dst.resolve(
src.relativize(path)).normalize(), path)); src.relativize(path)).normalize(), path));
@ -222,7 +221,7 @@ final class PathGroup {
continue; continue;
} }
if (src.toFile().isDirectory()) { if (Files.isDirectory(src)) {
handler.createDirectory(dst); handler.createDirectory(dst);
} else { } else {
handler.copyFile(src, dst); handler.copyFile(src, dst);
@ -232,8 +231,8 @@ final class PathGroup {
if (move) { if (move) {
// Delete source dirs. // Delete source dirs.
for (var entry: entries) { for (var entry: entries) {
File srcFile = entry.getKey().toFile(); Path srcFile = entry.getKey();
if (srcFile.isDirectory()) { if (Files.isDirectory(srcFile)) {
IOUtils.deleteRecursive(srcFile); IOUtils.deleteRecursive(srcFile);
} }
} }

View File

@ -76,7 +76,7 @@ class ScriptRunner {
public void run(Map<String, ? super Object> params) throws IOException { public void run(Map<String, ? super Object> params) throws IOException {
String scriptName = String.format("%s-%s%s", APP_NAME.fetchFrom(params), String scriptName = String.format("%s-%s%s", APP_NAME.fetchFrom(params),
scriptNameSuffix, scriptSuffix()); scriptNameSuffix, scriptSuffix());
Path scriptPath = CONFIG_ROOT.fetchFrom(params).toPath().resolve( Path scriptPath = CONFIG_ROOT.fetchFrom(params).resolve(
scriptName); scriptName);
createResource(null, params) createResource(null, params)
.setCategory(I18N.getString(resourceCategoryId)) .setCategory(I18N.getString(resourceCategoryId))

View File

@ -120,12 +120,12 @@ class StandardBundlerParam<T> extends BundlerParamInfo<T> {
(s, p) -> s (s, p) -> s
); );
static final StandardBundlerParam<File> PREDEFINED_RUNTIME_IMAGE = static final StandardBundlerParam<Path> PREDEFINED_RUNTIME_IMAGE =
new StandardBundlerParam<>( new StandardBundlerParam<>(
Arguments.CLIOptions.PREDEFINED_RUNTIME_IMAGE.getId(), Arguments.CLIOptions.PREDEFINED_RUNTIME_IMAGE.getId(),
File.class, Path.class,
params -> null, params -> null,
(s, p) -> new File(s) (s, p) -> Path.of(s)
); );
static final StandardBundlerParam<String> APP_NAME = static final StandardBundlerParam<String> APP_NAME =
@ -141,9 +141,9 @@ class StandardBundlerParam<T> extends BundlerParamInfo<T> {
} }
return s; return s;
} else if (isRuntimeInstaller(params)) { } else if (isRuntimeInstaller(params)) {
File f = PREDEFINED_RUNTIME_IMAGE.fetchFrom(params); Path f = PREDEFINED_RUNTIME_IMAGE.fetchFrom(params);
if (f != null) { if (f != null) {
return f.getName(); return f.getFileName().toString();
} }
} }
return null; return null;
@ -151,12 +151,12 @@ class StandardBundlerParam<T> extends BundlerParamInfo<T> {
(s, p) -> s (s, p) -> s
); );
static final StandardBundlerParam<File> ICON = static final StandardBundlerParam<Path> ICON =
new StandardBundlerParam<>( new StandardBundlerParam<>(
Arguments.CLIOptions.ICON.getId(), Arguments.CLIOptions.ICON.getId(),
File.class, Path.class,
params -> null, params -> null,
(s, p) -> new File(s) (s, p) -> Path.of(s)
); );
static final StandardBundlerParam<String> VENDOR = static final StandardBundlerParam<String> VENDOR =
@ -229,29 +229,31 @@ class StandardBundlerParam<T> extends BundlerParamInfo<T> {
(s, p) -> s (s, p) -> s
); );
static final StandardBundlerParam<File> TEMP_ROOT = static final StandardBundlerParam<Path> TEMP_ROOT =
new StandardBundlerParam<>( new StandardBundlerParam<>(
Arguments.CLIOptions.TEMP_ROOT.getId(), Arguments.CLIOptions.TEMP_ROOT.getId(),
File.class, Path.class,
params -> { params -> {
try { try {
return Files.createTempDirectory( return Files.createTempDirectory("jdk.incubator.jpackage");
"jdk.incubator.jpackage").toFile();
} catch (IOException ioe) { } catch (IOException ioe) {
return null; return null;
} }
}, },
(s, p) -> new File(s) (s, p) -> Path.of(s)
); );
public static final StandardBundlerParam<File> CONFIG_ROOT = public static final StandardBundlerParam<Path> CONFIG_ROOT =
new StandardBundlerParam<>( new StandardBundlerParam<>(
"configRoot", "configRoot",
File.class, Path.class,
params -> { params -> {
File root = Path root = TEMP_ROOT.fetchFrom(params).resolve("config");
new File(TEMP_ROOT.fetchFrom(params), "config"); try {
root.mkdirs(); Files.createDirectories(root);
} catch (IOException ioe) {
return null;
}
return root; return root;
}, },
(s, p) -> null (s, p) -> null
@ -277,12 +279,12 @@ class StandardBundlerParam<T> extends BundlerParamInfo<T> {
true : Boolean.valueOf(s) true : Boolean.valueOf(s)
); );
static final StandardBundlerParam<File> RESOURCE_DIR = static final StandardBundlerParam<Path> RESOURCE_DIR =
new StandardBundlerParam<>( new StandardBundlerParam<>(
Arguments.CLIOptions.RESOURCE_DIR.getId(), Arguments.CLIOptions.RESOURCE_DIR.getId(),
File.class, Path.class,
params -> null, params -> null,
(s, p) -> new File(s) (s, p) -> Path.of(s)
); );
static final BundlerParamInfo<String> INSTALL_DIR = static final BundlerParamInfo<String> INSTALL_DIR =
@ -293,12 +295,12 @@ class StandardBundlerParam<T> extends BundlerParamInfo<T> {
(s, p) -> s (s, p) -> s
); );
static final StandardBundlerParam<File> PREDEFINED_APP_IMAGE = static final StandardBundlerParam<Path> PREDEFINED_APP_IMAGE =
new StandardBundlerParam<>( new StandardBundlerParam<>(
Arguments.CLIOptions.PREDEFINED_APP_IMAGE.getId(), Arguments.CLIOptions.PREDEFINED_APP_IMAGE.getId(),
File.class, Path.class,
params -> null, params -> null,
(s, p) -> new File(s)); (s, p) -> Path.of(s));
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
static final StandardBundlerParam<List<Map<String, ? super Object>>> ADD_LAUNCHERS = static final StandardBundlerParam<List<Map<String, ? super Object>>> ADD_LAUNCHERS =
@ -346,16 +348,16 @@ class StandardBundlerParam<T> extends BundlerParamInfo<T> {
new StandardBundlerParam<>( new StandardBundlerParam<>(
"fileAssociation.description", "fileAssociation.description",
String.class, String.class,
params -> APP_NAME.fetchFrom(params) + " File", params -> APP_NAME.fetchFrom(params) + " Path",
null null
); );
static final StandardBundlerParam<File> FA_ICON = static final StandardBundlerParam<Path> FA_ICON =
new StandardBundlerParam<>( new StandardBundlerParam<>(
"fileAssociation.icon", "fileAssociation.icon",
File.class, Path.class,
ICON::fetchFrom, ICON::fetchFrom,
(s, p) -> new File(s) (s, p) -> Path.of(s)
); );
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -449,9 +451,9 @@ class StandardBundlerParam<T> extends BundlerParamInfo<T> {
return params.containsKey(PREDEFINED_RUNTIME_IMAGE.getID()); return params.containsKey(PREDEFINED_RUNTIME_IMAGE.getID());
} }
static File getPredefinedAppImage(Map<String, ? super Object> params) { static Path getPredefinedAppImage(Map<String, ? super Object> params) {
File applicationImage = PREDEFINED_APP_IMAGE.fetchFrom(params); Path applicationImage = PREDEFINED_APP_IMAGE.fetchFrom(params);
if (applicationImage != null && !applicationImage.exists()) { if (applicationImage != null && !IOUtils.exists(applicationImage)) {
throw new RuntimeException( throw new RuntimeException(
MessageFormat.format(I18N.getString( MessageFormat.format(I18N.getString(
"message.app-image-dir-does-not-exist"), "message.app-image-dir-does-not-exist"),
@ -463,8 +465,8 @@ class StandardBundlerParam<T> extends BundlerParamInfo<T> {
static void copyPredefinedRuntimeImage(Map<String, ? super Object> params, static void copyPredefinedRuntimeImage(Map<String, ? super Object> params,
ApplicationLayout appLayout) throws IOException, ConfigException { ApplicationLayout appLayout) throws IOException, ConfigException {
File topImage = PREDEFINED_RUNTIME_IMAGE.fetchFrom(params); Path topImage = PREDEFINED_RUNTIME_IMAGE.fetchFrom(params);
if (!topImage.exists()) { if (!IOUtils.exists(topImage)) {
throw new ConfigException( throw new ConfigException(
MessageFormat.format(I18N.getString( MessageFormat.format(I18N.getString(
"message.runtime-image-dir-does-not-exist"), "message.runtime-image-dir-does-not-exist"),
@ -477,17 +479,17 @@ class StandardBundlerParam<T> extends BundlerParamInfo<T> {
if (Platform.isMac()) { if (Platform.isMac()) {
// On Mac topImage can be runtime root or runtime home. // On Mac topImage can be runtime root or runtime home.
Path runtimeHome = topImage.toPath().resolve("Contents/Home"); Path runtimeHome = topImage.resolve("Contents/Home");
if (Files.isDirectory(runtimeHome)) { if (Files.isDirectory(runtimeHome)) {
// topImage references runtime root, adjust it to pick data from // topImage references runtime root, adjust it to pick data from
// runtime home // runtime home
topImage = runtimeHome.toFile(); topImage = runtimeHome;
} }
} }
// copy whole runtime, need to skip jmods and src.zip // copy whole runtime, need to skip jmods and src.zip
final List<String> excludes = Arrays.asList("jmods", "src.zip"); final List<String> excludes = Arrays.asList("jmods", "src.zip");
IOUtils.copyRecursive(topImage.toPath(), IOUtils.copyRecursive(topImage,
appLayout.runtimeHomeDirectory(), excludes); appLayout.runtimeHomeDirectory(), excludes);
// if module-path given - copy modules to appDir/mods // if module-path given - copy modules to appDir/mods

View File

@ -108,7 +108,8 @@ final class ExecutableRebrander {
private void rebrandExecutable(Map<String, ? super Object> params, private void rebrandExecutable(Map<String, ? super Object> params,
Path target, UpdateResourceAction action) throws IOException { Path target, UpdateResourceAction action) throws IOException {
try { try {
String tempDirectory = TEMP_ROOT.fetchFrom(params).getAbsolutePath(); String tempDirectory = TEMP_ROOT.fetchFrom(params)
.toAbsolutePath().toString();
if (WindowsDefender.isThereAPotentialWindowsDefenderIssue( if (WindowsDefender.isThereAPotentialWindowsDefenderIssue(
tempDirectory)) { tempDirectory)) {
Log.verbose(MessageFormat.format(I18N.getString( Log.verbose(MessageFormat.format(I18N.getString(

View File

@ -24,12 +24,10 @@
*/ */
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.Map; import java.util.Map;
@ -39,16 +37,20 @@ public class WinExeBundler extends AbstractBundler {
System.loadLibrary("jpackage"); System.loadLibrary("jpackage");
} }
public static final BundlerParamInfo<File> EXE_IMAGE_DIR public static final BundlerParamInfo<Path> EXE_IMAGE_DIR
= new StandardBundlerParam<>( = new StandardBundlerParam<>(
"win.exe.imageDir", "win.exe.imageDir",
File.class, Path.class,
params -> { params -> {
File imagesRoot = IMAGES_ROOT.fetchFrom(params); Path imagesRoot = IMAGES_ROOT.fetchFrom(params);
if (!imagesRoot.exists()) { if (!Files.exists(imagesRoot)) {
imagesRoot.mkdirs(); try {
Files.createDirectories(imagesRoot);
} catch (IOException ioe) {
return null;
} }
return new File(imagesRoot, "win-exe.image"); }
return imagesRoot.resolve("win-exe.image");
}, },
(s, p) -> null); (s, p) -> null);
@ -70,8 +72,8 @@ public class WinExeBundler extends AbstractBundler {
} }
@Override @Override
public File execute(Map<String, ? super Object> params, public Path execute(Map<String, ? super Object> params,
File outputParentDir) throws PackagerException { Path outputParentDir) throws PackagerException {
return bundle(params, outputParentDir); return bundle(params, outputParentDir);
} }
@ -91,22 +93,22 @@ public class WinExeBundler extends AbstractBundler {
return msiBundler.validate(params); return msiBundler.validate(params);
} }
public File bundle(Map<String, ? super Object> params, File outdir) public Path bundle(Map<String, ? super Object> params, Path outdir)
throws PackagerException { throws PackagerException {
IOUtils.writableOutputDir(outdir.toPath()); IOUtils.writableOutputDir(outdir);
File exeImageDir = EXE_IMAGE_DIR.fetchFrom(params); Path exeImageDir = EXE_IMAGE_DIR.fetchFrom(params);
// Write msi to temporary directory. // Write msi to temporary directory.
File msi = msiBundler.execute(params, exeImageDir); Path msi = msiBundler.execute(params, exeImageDir);
try { try {
new ScriptRunner() new ScriptRunner()
.setDirectory(msi.toPath().getParent()) .setDirectory(msi.getParent())
.setResourceCategoryId("resource.post-msi-script") .setResourceCategoryId("resource.post-msi-script")
.setScriptNameSuffix("post-msi") .setScriptNameSuffix("post-msi")
.setEnvironmentVariable("JpMsiFile", msi.getAbsolutePath().toString()) .setEnvironmentVariable("JpMsiFile", msi.toAbsolutePath().toString())
.run(params); .run(params);
return buildEXE(params, msi, outdir); return buildEXE(params, msi, outdir);
@ -116,35 +118,34 @@ public class WinExeBundler extends AbstractBundler {
} }
} }
private File buildEXE(Map<String, ? super Object> params, File msi, private Path buildEXE(Map<String, ? super Object> params, Path msi,
File outdir) throws IOException { Path outdir) throws IOException {
Log.verbose(MessageFormat.format( Log.verbose(MessageFormat.format(
I18N.getString("message.outputting-to-location"), I18N.getString("message.outputting-to-location"),
outdir.getAbsolutePath())); outdir.toAbsolutePath().toString()));
// Copy template msi wrapper next to msi file // Copy template msi wrapper next to msi file
final Path exePath = IOUtils.replaceSuffix(msi.toPath(), ".exe"); final Path exePath = IOUtils.replaceSuffix(msi, ".exe");
try (InputStream is = OverridableResource.readDefault(EXE_WRAPPER_NAME)) { try (InputStream is = OverridableResource.readDefault(EXE_WRAPPER_NAME)) {
Files.copy(is, exePath); Files.copy(is, exePath);
} }
new ExecutableRebrander().addAction((resourceLock) -> { new ExecutableRebrander().addAction((resourceLock) -> {
// Embed msi in msi wrapper exe. // Embed msi in msi wrapper exe.
embedMSI(resourceLock, msi.getAbsolutePath()); embedMSI(resourceLock, msi.toAbsolutePath().toString());
}).rebrandInstaller(params, exePath); }).rebrandInstaller(params, exePath);
Path dstExePath = Paths.get(outdir.getAbsolutePath(), Path dstExePath = outdir.toAbsolutePath().resolve(exePath.getFileName());
exePath.getFileName().toString());
Files.deleteIfExists(dstExePath); Files.deleteIfExists(dstExePath);
Files.copy(exePath, dstExePath); Files.copy(exePath, dstExePath);
Log.verbose(MessageFormat.format( Log.verbose(MessageFormat.format(
I18N.getString("message.output-location"), I18N.getString("message.output-location"),
outdir.getAbsolutePath())); outdir.toAbsolutePath().toString()));
return dstExePath.toFile(); return dstExePath;
} }
private final WinMsiBundler msiBundler = new WinMsiBundler(); private final WinMsiBundler msiBundler = new WinMsiBundler();

View File

@ -25,8 +25,6 @@
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.Writer; import java.io.Writer;
@ -101,21 +99,27 @@ import static jdk.incubator.jpackage.internal.StandardBundlerParam.VERSION;
*/ */
public class WinMsiBundler extends AbstractBundler { public class WinMsiBundler extends AbstractBundler {
public static final BundlerParamInfo<File> MSI_IMAGE_DIR = public static final BundlerParamInfo<Path> MSI_IMAGE_DIR =
new StandardBundlerParam<>( new StandardBundlerParam<>(
"win.msi.imageDir", "win.msi.imageDir",
File.class, Path.class,
params -> { params -> {
File imagesRoot = IMAGES_ROOT.fetchFrom(params); Path imagesRoot = IMAGES_ROOT.fetchFrom(params);
if (!imagesRoot.exists()) imagesRoot.mkdirs(); if (!Files.exists(imagesRoot)) {
return new File(imagesRoot, "win-msi.image"); try {
Files.createDirectories(imagesRoot);
} catch (IOException ioe) {
return null;
}
}
return imagesRoot.resolve("win-msi.image");
}, },
(s, p) -> null); (s, p) -> null);
public static final BundlerParamInfo<File> WIN_APP_IMAGE = public static final BundlerParamInfo<Path> WIN_APP_IMAGE =
new StandardBundlerParam<>( new StandardBundlerParam<>(
"win.app.image", "win.app.image",
File.class, Path.class,
null, null,
(s, p) -> null); (s, p) -> null);
@ -284,15 +288,14 @@ public class WinMsiBundler extends AbstractBundler {
private void prepareProto(Map<String, ? super Object> params) private void prepareProto(Map<String, ? super Object> params)
throws PackagerException, IOException { throws PackagerException, IOException {
File appImage = StandardBundlerParam.getPredefinedAppImage(params); Path appImage = StandardBundlerParam.getPredefinedAppImage(params);
File appDir = null; Path appDir;
// we either have an application image or need to build one // we either have an application image or need to build one
if (appImage != null) { if (appImage != null) {
appDir = new File(MSI_IMAGE_DIR.fetchFrom(params), appDir = MSI_IMAGE_DIR.fetchFrom(params).resolve(APP_NAME.fetchFrom(params));
APP_NAME.fetchFrom(params));
// copy everything from appImage dir into appDir/name // copy everything from appImage dir into appDir/name
IOUtils.copyRecursive(appImage.toPath(), appDir.toPath()); IOUtils.copyRecursive(appImage, appDir);
} else { } else {
appDir = appImageBundler.execute(params, MSI_IMAGE_DIR.fetchFrom( appDir = appImageBundler.execute(params, MSI_IMAGE_DIR.fetchFrom(
params)); params));
@ -305,12 +308,12 @@ public class WinMsiBundler extends AbstractBundler {
// Ignore custom icon if any as we don't want to copy anything in // Ignore custom icon if any as we don't want to copy anything in
// Java Runtime image. // Java Runtime image.
installerIcon = ApplicationLayout.javaRuntime() installerIcon = ApplicationLayout.javaRuntime()
.resolveAt(appDir.toPath()) .resolveAt(appDir)
.runtimeDirectory() .runtimeDirectory()
.resolve(Path.of("bin", "java.exe")); .resolve(Path.of("bin", "java.exe"));
} else { } else {
installerIcon = ApplicationLayout.windowsAppImage() installerIcon = ApplicationLayout.windowsAppImage()
.resolveAt(appDir.toPath()) .resolveAt(appDir)
.launchersDirectory() .launchersDirectory()
.resolve(APP_NAME.fetchFrom(params) + ".exe"); .resolve(APP_NAME.fetchFrom(params) + ".exe");
} }
@ -322,31 +325,31 @@ public class WinMsiBundler extends AbstractBundler {
if (licenseFile != null) { if (licenseFile != null) {
// need to copy license file to the working directory // need to copy license file to the working directory
// and convert to rtf if needed // and convert to rtf if needed
File lfile = new File(licenseFile); Path lfile = Path.of(licenseFile);
File destFile = new File(CONFIG_ROOT.fetchFrom(params), Path destFile = CONFIG_ROOT.fetchFrom(params)
lfile.getName()); .resolve(lfile.getFileName());
IOUtils.copyFile(lfile, destFile); IOUtils.copyFile(lfile, destFile);
destFile.setWritable(true); destFile.toFile().setWritable(true);
ensureByMutationFileIsRTF(destFile); ensureByMutationFileIsRTF(destFile);
} }
} }
@Override @Override
public File execute(Map<String, ? super Object> params, public Path execute(Map<String, ? super Object> params,
File outputParentDir) throws PackagerException { Path outputParentDir) throws PackagerException {
IOUtils.writableOutputDir(outputParentDir.toPath()); IOUtils.writableOutputDir(outputParentDir);
Path imageDir = MSI_IMAGE_DIR.fetchFrom(params).toPath(); Path imageDir = MSI_IMAGE_DIR.fetchFrom(params);
try { try {
Files.createDirectories(imageDir); Files.createDirectories(imageDir);
prepareProto(params); prepareProto(params);
wixSourcesBuilder wixSourcesBuilder
.initFromParams(WIN_APP_IMAGE.fetchFrom(params).toPath(), params) .initFromParams(WIN_APP_IMAGE.fetchFrom(params), params)
.createMainFragment(CONFIG_ROOT.fetchFrom(params).toPath().resolve( .createMainFragment(CONFIG_ROOT.fetchFrom(params).resolve(
"bundle.wxf")); "bundle.wxf"));
Map<String, String> wixVars = prepareMainProjectFile(params); Map<String, String> wixVars = prepareMainProjectFile(params);
@ -389,7 +392,7 @@ public class WinMsiBundler extends AbstractBundler {
data.put("JpAppVersion", PRODUCT_VERSION.fetchFrom(params)); data.put("JpAppVersion", PRODUCT_VERSION.fetchFrom(params));
data.put("JpIcon", installerIcon.toString()); data.put("JpIcon", installerIcon.toString());
final Path configDir = CONFIG_ROOT.fetchFrom(params).toPath(); final Path configDir = CONFIG_ROOT.fetchFrom(params);
data.put("JpConfigDir", configDir.toAbsolutePath().toString()); data.put("JpConfigDir", configDir.toAbsolutePath().toString());
@ -399,9 +402,9 @@ public class WinMsiBundler extends AbstractBundler {
String licenseFile = LICENSE_FILE.fetchFrom(params); String licenseFile = LICENSE_FILE.fetchFrom(params);
if (licenseFile != null) { if (licenseFile != null) {
String lname = new File(licenseFile).getName(); String lname = Path.of(licenseFile).getFileName().toString();
File destFile = new File(CONFIG_ROOT.fetchFrom(params), lname); Path destFile = CONFIG_ROOT.fetchFrom(params).resolve(lname);
data.put("JpLicenseRtf", destFile.getAbsolutePath()); data.put("JpLicenseRtf", destFile.toAbsolutePath().toString());
} }
// Copy CA dll to include with installer // Copy CA dll to include with installer
@ -409,9 +412,7 @@ public class WinMsiBundler extends AbstractBundler {
data.put("JpInstallDirChooser", "yes"); data.put("JpInstallDirChooser", "yes");
String fname = "wixhelper.dll"; String fname = "wixhelper.dll";
try (InputStream is = OverridableResource.readDefault(fname)) { try (InputStream is = OverridableResource.readDefault(fname)) {
Files.copy(is, Paths.get( Files.copy(is, CONFIG_ROOT.fetchFrom(params).resolve(fname));
CONFIG_ROOT.fetchFrom(params).getAbsolutePath(),
fname));
} }
} }
@ -419,9 +420,7 @@ public class WinMsiBundler extends AbstractBundler {
for (String loc : Arrays.asList("en", "ja", "zh_CN")) { for (String loc : Arrays.asList("en", "ja", "zh_CN")) {
String fname = "MsiInstallerStrings_" + loc + ".wxl"; String fname = "MsiInstallerStrings_" + loc + ".wxl";
try (InputStream is = OverridableResource.readDefault(fname)) { try (InputStream is = OverridableResource.readDefault(fname)) {
Files.copy(is, Paths.get( Files.copy(is, CONFIG_ROOT.fetchFrom(params).resolve(fname));
CONFIG_ROOT.fetchFrom(params).getAbsolutePath(),
fname));
} }
} }
@ -436,28 +435,28 @@ public class WinMsiBundler extends AbstractBundler {
return data; return data;
} }
private File buildMSI(Map<String, ? super Object> params, private Path buildMSI(Map<String, ? super Object> params,
Map<String, String> wixVars, File outdir) Map<String, String> wixVars, Path outdir)
throws IOException { throws IOException {
File msiOut = new File( Path msiOut = outdir.resolve(INSTALLER_FILE_NAME.fetchFrom(params) + ".msi");
outdir, INSTALLER_FILE_NAME.fetchFrom(params) + ".msi");
Log.verbose(MessageFormat.format(I18N.getString( Log.verbose(MessageFormat.format(I18N.getString(
"message.preparing-msi-config"), msiOut.getAbsolutePath())); "message.preparing-msi-config"), msiOut.toAbsolutePath()
.toString()));
WixPipeline wixPipeline = new WixPipeline() WixPipeline wixPipeline = new WixPipeline()
.setToolset(wixToolset.entrySet().stream().collect( .setToolset(wixToolset.entrySet().stream().collect(
Collectors.toMap( Collectors.toMap(
entry -> entry.getKey(), entry -> entry.getKey(),
entry -> entry.getValue().path))) entry -> entry.getValue().path)))
.setWixObjDir(TEMP_ROOT.fetchFrom(params).toPath().resolve("wixobj")) .setWixObjDir(TEMP_ROOT.fetchFrom(params).resolve("wixobj"))
.setWorkDir(WIN_APP_IMAGE.fetchFrom(params).toPath()) .setWorkDir(WIN_APP_IMAGE.fetchFrom(params))
.addSource(CONFIG_ROOT.fetchFrom(params).toPath().resolve("main.wxs"), wixVars) .addSource(CONFIG_ROOT.fetchFrom(params).resolve("main.wxs"), wixVars)
.addSource(CONFIG_ROOT.fetchFrom(params).toPath().resolve("bundle.wxf"), null); .addSource(CONFIG_ROOT.fetchFrom(params).resolve("bundle.wxf"), null);
Log.verbose(MessageFormat.format(I18N.getString( Log.verbose(MessageFormat.format(I18N.getString(
"message.generating-msi"), msiOut.getAbsolutePath())); "message.generating-msi"), msiOut.toAbsolutePath().toString()));
boolean enableLicenseUI = (LICENSE_FILE.fetchFrom(params) != null); boolean enableLicenseUI = (LICENSE_FILE.fetchFrom(params) != null);
boolean enableInstalldirUI = INSTALLDIR_CHOOSER.fetchFrom(params); boolean enableInstalldirUI = INSTALLDIR_CHOOSER.fetchFrom(params);
@ -472,26 +471,27 @@ public class WinMsiBundler extends AbstractBundler {
} }
wixPipeline.addLightOptions("-loc", wixPipeline.addLightOptions("-loc",
CONFIG_ROOT.fetchFrom(params).toPath().resolve(I18N.getString( CONFIG_ROOT.fetchFrom(params).resolve(I18N.getString(
"resource.wxl-file-name")).toAbsolutePath().toString()); "resource.wxl-file-name")).toAbsolutePath().toString());
// Only needed if we using CA dll, so Wix can find it // Only needed if we using CA dll, so Wix can find it
if (enableInstalldirUI) { if (enableInstalldirUI) {
wixPipeline.addLightOptions("-b", CONFIG_ROOT.fetchFrom(params).getAbsolutePath()); wixPipeline.addLightOptions("-b", CONFIG_ROOT.fetchFrom(params)
.toAbsolutePath().toString());
} }
wixPipeline.buildMsi(msiOut.toPath().toAbsolutePath()); wixPipeline.buildMsi(msiOut.toAbsolutePath());
return msiOut; return msiOut;
} }
private static void ensureByMutationFileIsRTF(File f) { private static void ensureByMutationFileIsRTF(Path f) {
if (f == null || !f.isFile()) return; if (f == null || !Files.isRegularFile(f)) return;
try { try {
boolean existingLicenseIsRTF = false; boolean existingLicenseIsRTF = false;
try (FileInputStream fin = new FileInputStream(f)) { try (InputStream fin = Files.newInputStream(f)) {
byte[] firstBits = new byte[7]; byte[] firstBits = new byte[7];
if (fin.read(firstBits) == firstBits.length) { if (fin.read(firstBits) == firstBits.length) {
@ -501,9 +501,9 @@ public class WinMsiBundler extends AbstractBundler {
} }
if (!existingLicenseIsRTF) { if (!existingLicenseIsRTF) {
List<String> oldLicense = Files.readAllLines(f.toPath()); List<String> oldLicense = Files.readAllLines(f);
try (Writer w = Files.newBufferedWriter( try (Writer w = Files.newBufferedWriter(
f.toPath(), Charset.forName("Windows-1252"))) { f, Charset.forName("Windows-1252"))) {
w.write("{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033" w.write("{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033"
+ "{\\fonttbl{\\f0\\fnil\\fcharset0 Arial;}}\n" + "{\\fonttbl{\\f0\\fnil\\fcharset0 Arial;}}\n"
+ "\\viewkind4\\uc1\\pard\\sa200\\sl276" + "\\viewkind4\\uc1\\pard\\sa200\\sl276"

View File

@ -25,7 +25,6 @@
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Files; import java.nio.file.Files;
@ -45,20 +44,21 @@ public class WindowsAppImageBuilder extends AbstractAppImageBuilder {
private static final String TEMPLATE_APP_ICON ="java48.ico"; private static final String TEMPLATE_APP_ICON ="java48.ico";
public static final BundlerParamInfo<File> ICON_ICO = public static final BundlerParamInfo<Path> ICON_ICO =
new StandardBundlerParam<>( new StandardBundlerParam<>(
"icon.ico", "icon.ico",
File.class, Path.class,
params -> { params -> {
File f = ICON.fetchFrom(params); Path f = ICON.fetchFrom(params);
if (f != null && !f.getName().toLowerCase().endsWith(".ico")) { if (f != null && f.getFileName() != null && !f.getFileName()
.toString().toLowerCase().endsWith(".ico")) {
Log.error(MessageFormat.format( Log.error(MessageFormat.format(
I18N.getString("message.icon-not-ico"), f)); I18N.getString("message.icon-not-ico"), f));
return null; return null;
} }
return f; return f;
}, },
(s, p) -> new File(s)); (s, p) -> Path.of(s));
public static final StandardBundlerParam<Boolean> CONSOLE_HINT = public static final StandardBundlerParam<Boolean> CONSOLE_HINT =
new StandardBundlerParam<>( new StandardBundlerParam<>(

View File

@ -28,6 +28,7 @@ package jdk.incubator.jpackage.internal;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Files;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -160,7 +161,7 @@ class WixSourcesBuilder {
fa.launcherPath = addExeSuffixToPath( fa.launcherPath = addExeSuffixToPath(
installedAppImage.launchersDirectory().resolve(fa.launcherPath)); installedAppImage.launchersDirectory().resolve(fa.launcherPath));
if (fa.iconPath != null && !fa.iconPath.toFile().exists()) { if (fa.iconPath != null && !Files.exists(fa.iconPath)) {
fa.iconPath = null; fa.iconPath = null;
} }

View File

@ -84,7 +84,7 @@ public enum WixTool {
for (var dir : findWixInstallDirs()) { for (var dir : findWixInstallDirs()) {
Path path = dir.resolve(toolFileName); Path path = dir.resolve(toolFileName);
if (path.toFile().exists()) { if (Files.exists(path)) {
reason = createToolValidator(path, version).get(); reason = createToolValidator(path, version).get();
if (reason != null) { if (reason != null) {
throw reason; throw reason;

View File

@ -22,7 +22,7 @@
*/ */
package jdk.incubator.jpackage.internal; package jdk.incubator.jpackage.internal;
import java.io.File; import java.nio.file.Path;
import java.io.IOException; import java.io.IOException;
import org.hamcrest.BaseMatcher; import org.hamcrest.BaseMatcher;
import org.hamcrest.Description; import org.hamcrest.Description;
@ -45,7 +45,7 @@ public class DeployParamsTest {
@Before @Before
public void setUp() throws IOException { public void setUp() throws IOException {
testRoot = tempFolder.newFolder(); testRoot = tempFolder.newFolder().toPath();
} }
@Test @Test
@ -131,6 +131,6 @@ public class DeployParamsTest {
params.validate(); params.validate();
} }
private File testRoot = null; private Path testRoot = null;
private DeployParams params; private DeployParams params;
} }