8223955: Eliminate or reduce mixing of old File API and new Path/Files APIs
Reviewed-by: herrick, asemenyuk
This commit is contained in:
parent
c782d0e486
commit
ed05d57603
@ -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);
|
||||||
|
@ -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";
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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())) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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.
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
|
@ -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
|
||||||
|
@ -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(
|
||||||
|
@ -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();
|
||||||
|
@ -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"
|
||||||
|
@ -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<>(
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user