8256475: Fix Behavior when Installer name differs from application name.
Reviewed-by: asemenyuk, almatvee, kizune
This commit is contained in:
parent
fa3cfcd0cd
commit
303631e3d5
@ -47,6 +47,7 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import static jdk.jpackage.internal.OverridableResource.createResource;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.INSTALLER_NAME;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.VERSION;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.RELEASE;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.VENDOR;
|
||||
@ -71,8 +72,7 @@ public class LinuxDebBundler extends LinuxPackageBundler {
|
||||
Arguments.CLIOptions.LINUX_BUNDLE_NAME.getId(),
|
||||
String.class,
|
||||
params -> {
|
||||
String nm = APP_NAME.fetchFrom(params);
|
||||
|
||||
String nm = INSTALLER_NAME.fetchFrom(params);
|
||||
if (nm == null) return null;
|
||||
|
||||
// make sure to lower case and spaces/underscores become dashes
|
||||
|
@ -38,6 +38,7 @@ import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.INSTALLER_NAME;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.LICENSE_FILE;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.VERSION;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.RELEASE;
|
||||
@ -73,7 +74,7 @@ public class LinuxRpmBundler extends LinuxPackageBundler {
|
||||
Arguments.CLIOptions.LINUX_BUNDLE_NAME.getId(),
|
||||
String.class,
|
||||
params -> {
|
||||
String nm = APP_NAME.fetchFrom(params);
|
||||
String nm = INSTALLER_NAME.fetchFrom(params);
|
||||
if (nm == null) return null;
|
||||
|
||||
// make sure to lower case and spaces become dashes
|
||||
|
@ -143,7 +143,7 @@ public class MacAppStoreBundler extends MacBaseInstallerBundler {
|
||||
ProcessBuilder pb;
|
||||
|
||||
// create the final pkg file
|
||||
Path finalPKG = outdir.resolve(INSTALLER_NAME.fetchFrom(params)
|
||||
Path finalPKG = outdir.resolve(MAC_INSTALLER_NAME.fetchFrom(params)
|
||||
+ INSTALLER_SUFFIX.fetchFrom(params)
|
||||
+ ".pkg");
|
||||
Files.createDirectories(outdir);
|
||||
|
@ -37,6 +37,7 @@ import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.INSTALLER_NAME;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.INSTALL_DIR;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.PREDEFINED_APP_IMAGE;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.VERSION;
|
||||
@ -75,12 +76,12 @@ public abstract class MacBaseInstallerBundler extends AbstractBundler {
|
||||
params -> "",
|
||||
null);
|
||||
|
||||
public static final BundlerParamInfo<String> INSTALLER_NAME =
|
||||
public static final BundlerParamInfo<String> MAC_INSTALLER_NAME =
|
||||
new StandardBundlerParam<> (
|
||||
"mac.installerName",
|
||||
String.class,
|
||||
params -> {
|
||||
String nm = APP_NAME.fetchFrom(params);
|
||||
String nm = INSTALLER_NAME.fetchFrom(params);
|
||||
if (nm == null) return null;
|
||||
|
||||
String version = VERSION.fetchFrom(params);
|
||||
|
@ -270,7 +270,7 @@ public class MacDmgBundler extends MacBaseInstallerBundler {
|
||||
}
|
||||
|
||||
Path protoDMG = imagesRoot.resolve(APP_NAME.fetchFrom(params) +"-tmp.dmg");
|
||||
Path finalDMG = outdir.resolve(INSTALLER_NAME.fetchFrom(params)
|
||||
Path finalDMG = outdir.resolve(MAC_INSTALLER_NAME.fetchFrom(params)
|
||||
+ INSTALLER_SUFFIX.fetchFrom(params) + ".dmg");
|
||||
|
||||
Path srcFolder = APP_IMAGE_TEMP_ROOT.fetchFrom(params);
|
||||
|
@ -448,7 +448,7 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
|
||||
IOUtils.exec(pb);
|
||||
|
||||
// build final package
|
||||
Path finalPKG = outdir.resolve(INSTALLER_NAME.fetchFrom(params)
|
||||
Path finalPKG = outdir.resolve(MAC_INSTALLER_NAME.fetchFrom(params)
|
||||
+ INSTALLER_SUFFIX.fetchFrom(params)
|
||||
+ ".pkg");
|
||||
Files.createDirectories(outdir);
|
||||
|
@ -31,6 +31,7 @@ import java.util.Map;
|
||||
import java.util.List;
|
||||
import jdk.jpackage.internal.Arguments.CLIOptions;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.LAUNCHER_DATA;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME;
|
||||
|
||||
/*
|
||||
* AddLauncherArguments
|
||||
@ -158,8 +159,10 @@ class AddLauncherArguments {
|
||||
Map<String, ? super Object> tmp = new HashMap<>(original);
|
||||
List.of(exclude).forEach(tmp::remove);
|
||||
|
||||
// remove LauncherData from map so it will re-run the defaultValueFunction
|
||||
// remove LauncherData from map so it will be re-computed
|
||||
tmp.remove(LAUNCHER_DATA.getID());
|
||||
// remove "application-name" so it will be re-computed
|
||||
tmp.remove(APP_NAME.getID());
|
||||
|
||||
if (additional.containsKey(CLIOptions.MODULE.getId())) {
|
||||
tmp.remove(CLIOptions.MAIN_JAR.getId());
|
||||
|
@ -233,6 +233,16 @@ public class AppImageFile {
|
||||
return launchers;
|
||||
}
|
||||
|
||||
public static String extractAppName(Path appImageDir) {
|
||||
try {
|
||||
return AppImageFile.load(appImageDir).getLauncherName();
|
||||
} catch (IOException ioe) {
|
||||
Log.verbose(MessageFormat.format(I18N.getString(
|
||||
"warning.foreign-app-image"), appImageDir));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static String xpathQueryNullable(XPath xPath, String xpathExpr,
|
||||
Document xml) throws XPathExpressionException {
|
||||
NodeList nodes = (NodeList) xPath.evaluate(xpathExpr, xml,
|
||||
|
@ -128,25 +128,59 @@ class StandardBundlerParam<T> extends BundlerParamInfo<T> {
|
||||
(s, p) -> Path.of(s)
|
||||
);
|
||||
|
||||
static final StandardBundlerParam<String> APP_NAME =
|
||||
static final StandardBundlerParam<Path> PREDEFINED_APP_IMAGE =
|
||||
new StandardBundlerParam<>(
|
||||
Arguments.CLIOptions.PREDEFINED_APP_IMAGE.getId(),
|
||||
Path.class,
|
||||
params -> null,
|
||||
(s, p) -> Path.of(s));
|
||||
|
||||
// this is the raw --app-name arg - used in APP_NAME and INSTALLER_NAME
|
||||
static final StandardBundlerParam<String> NAME =
|
||||
new StandardBundlerParam<>(
|
||||
Arguments.CLIOptions.NAME.getId(),
|
||||
String.class,
|
||||
params -> null,
|
||||
(s, p) -> s
|
||||
);
|
||||
|
||||
// this is the application name, either from the app-image (if given),
|
||||
// the name (if given) derived from the main-class, or the runtime image
|
||||
static final StandardBundlerParam<String> APP_NAME =
|
||||
new StandardBundlerParam<>(
|
||||
"application-name",
|
||||
String.class,
|
||||
params -> {
|
||||
String s = MAIN_CLASS.fetchFrom(params);
|
||||
if (s != null) {
|
||||
int idx = s.lastIndexOf(".");
|
||||
if (idx >= 0) {
|
||||
return s.substring(idx+1);
|
||||
}
|
||||
return s;
|
||||
} else if (isRuntimeInstaller(params)) {
|
||||
Path f = PREDEFINED_RUNTIME_IMAGE.fetchFrom(params);
|
||||
if (f != null) {
|
||||
return f.getFileName().toString();
|
||||
Path appImage = PREDEFINED_APP_IMAGE.fetchFrom(params);
|
||||
String appName = NAME.fetchFrom(params);
|
||||
if (appImage != null) {
|
||||
String name = AppImageFile.extractAppName(appImage);
|
||||
appName = (name != null) ? name : appName;
|
||||
} else if (appName == null) {
|
||||
String s = MAIN_CLASS.fetchFrom(params);
|
||||
if (s != null) {
|
||||
int idx = s.lastIndexOf(".");
|
||||
appName = (idx < 0) ? s : s.substring(idx+1);
|
||||
} else if (isRuntimeInstaller(params)) {
|
||||
Path f = PREDEFINED_RUNTIME_IMAGE.fetchFrom(params);
|
||||
if (f != null) {
|
||||
appName = f.getFileName().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return appName;
|
||||
},
|
||||
(s, p) -> s
|
||||
);
|
||||
|
||||
static final StandardBundlerParam<String> INSTALLER_NAME =
|
||||
new StandardBundlerParam<>(
|
||||
"installer-name",
|
||||
String.class,
|
||||
params -> {
|
||||
String installerName = NAME.fetchFrom(params);
|
||||
return (installerName != null) ? installerName :
|
||||
APP_NAME.fetchFrom(params);
|
||||
},
|
||||
(s, p) -> s
|
||||
);
|
||||
@ -285,12 +319,6 @@ class StandardBundlerParam<T> extends BundlerParamInfo<T> {
|
||||
(s, p) -> s
|
||||
);
|
||||
|
||||
static final StandardBundlerParam<Path> PREDEFINED_APP_IMAGE =
|
||||
new StandardBundlerParam<>(
|
||||
Arguments.CLIOptions.PREDEFINED_APP_IMAGE.getId(),
|
||||
Path.class,
|
||||
params -> null,
|
||||
(s, p) -> Path.of(s));
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static final StandardBundlerParam<List<Map<String, ? super Object>>> ADD_LAUNCHERS =
|
||||
|
@ -72,6 +72,7 @@ error.tool-old-version=Can not find {0} {1} or newer
|
||||
error.tool-old-version.advice=Please install {0} {1} or newer
|
||||
error.jlink.failed=jlink failed with: {0}
|
||||
error.blocked.option=jlink option [{0}] is not permitted in --jlink-options
|
||||
error.no.name=Name not specified with --name and cannot infer one from app-image
|
||||
|
||||
warning.no.jdk.modules.found=Warning: No JDK Modules found
|
||||
warning.foreign-app-image=Warning: app-image dir ({0}) not generated by jpackage.
|
||||
|
@ -72,6 +72,7 @@ error.tool-old-version={0} {1}\u4EE5\u964D\u304C\u898B\u3064\u304B\u308A\u307E\u
|
||||
error.tool-old-version.advice={0} {1}\u4EE5\u964D\u3092\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3057\u3066\u304F\u3060\u3055\u3044
|
||||
error.jlink.failed=jlink\u304C\u6B21\u3067\u5931\u6557\u3057\u307E\u3057\u305F: {0}
|
||||
error.blocked.option=jlink\u30AA\u30D7\u30B7\u30E7\u30F3[{0}]\u306F--jlink-options\u3067\u306F\u8A31\u53EF\u3055\u308C\u307E\u305B\u3093
|
||||
error.no.name=Name not specified with --name and cannot infer one from app-image
|
||||
|
||||
warning.no.jdk.modules.found=\u8B66\u544A: JDK\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093
|
||||
warning.foreign-app-image=Warning: app-image dir ({0}) not generated by jpackage.
|
||||
|
@ -72,6 +72,7 @@ error.tool-old-version=\u627E\u4E0D\u5230 {0} {1}\u6216\u66F4\u65B0\u7248\u672C
|
||||
error.tool-old-version.advice=\u8BF7\u5B89\u88C5 {0} {1}\u6216\u66F4\u65B0\u7248\u672C
|
||||
error.jlink.failed=jlink \u5931\u8D25\uFF0C\u51FA\u73B0 {0}
|
||||
error.blocked.option=\u4E0D\u5141\u8BB8\u5728 --jlink-options \u4E2D\u4F7F\u7528 jlink \u9009\u9879 [{0}]
|
||||
error.no.name=Name not specified with --name and cannot infer one from app-image
|
||||
|
||||
warning.no.jdk.modules.found=\u8B66\u544A: \u672A\u627E\u5230 JDK \u6A21\u5757
|
||||
warning.foreign-app-image=Warning: app-image dir ({0}) not generated by jpackage.
|
||||
|
@ -56,6 +56,7 @@ import javax.xml.xpath.XPathFactory;
|
||||
|
||||
import static jdk.jpackage.internal.OverridableResource.createResource;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.INSTALLER_NAME;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.CONFIG_ROOT;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.DESCRIPTION;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.LICENSE_FILE;
|
||||
@ -171,7 +172,7 @@ public class WinMsiBundler extends AbstractBundler {
|
||||
"win.installerName",
|
||||
String.class,
|
||||
params -> {
|
||||
String nm = APP_NAME.fetchFrom(params);
|
||||
String nm = INSTALLER_NAME.fetchFrom(params);
|
||||
if (nm == null) return null;
|
||||
|
||||
String version = VERSION.fetchFrom(params);
|
||||
@ -305,23 +306,21 @@ public class WinMsiBundler extends AbstractBundler {
|
||||
private void prepareProto(Map<String, ? super Object> params)
|
||||
throws PackagerException, IOException {
|
||||
Path appImage = StandardBundlerParam.getPredefinedAppImage(params);
|
||||
String appName = APP_NAME.fetchFrom(params);
|
||||
Path appDir;
|
||||
String appName;
|
||||
if (appName == null) {
|
||||
// Can happen when no name is given, and using a foreign app-image
|
||||
throw new PackagerException("error.no.name");
|
||||
}
|
||||
|
||||
// we either have an application image or need to build one
|
||||
if (appImage != null) {
|
||||
appDir = MSI_IMAGE_DIR.fetchFrom(params).resolve(APP_NAME.fetchFrom(params));
|
||||
appDir = MSI_IMAGE_DIR.fetchFrom(params).resolve(appName);
|
||||
// copy everything from appImage dir into appDir/name
|
||||
IOUtils.copyRecursive(appImage, appDir);
|
||||
try {
|
||||
appName = AppImageFile.load(appDir).getLauncherName();
|
||||
} catch (Exception e) {
|
||||
appName = APP_NAME.fetchFrom(params);
|
||||
}
|
||||
} else {
|
||||
appDir = appImageBundler.execute(params, MSI_IMAGE_DIR.fetchFrom(
|
||||
params));
|
||||
appName = APP_NAME.fetchFrom(params);
|
||||
}
|
||||
|
||||
// Configure installer icon
|
||||
|
@ -209,9 +209,28 @@ public final class JPackageCommand extends CommandArguments<JPackageCommand> {
|
||||
}
|
||||
|
||||
public String name() {
|
||||
String appImage = getArgumentValue("--app-image", () -> null);
|
||||
if (appImage != null) {
|
||||
String name = AppImageFile.extractAppName(Path.of(appImage));
|
||||
// can be null if using foreign app-image
|
||||
return ((name != null) ? name : getArgumentValue("--name"));
|
||||
}
|
||||
return getArgumentValue("--name", () -> getArgumentValue("--main-class"));
|
||||
}
|
||||
|
||||
public String installerName() {
|
||||
verifyIsOfType(PackageType.NATIVE);
|
||||
String installerName = getArgumentValue("--name",
|
||||
() -> getArgumentValue("--main-class", () -> null));
|
||||
if (installerName == null) {
|
||||
String appImage = getArgumentValue("--app-image");
|
||||
if (appImage != null) {
|
||||
installerName = AppImageFile.extractAppName(Path.of(appImage));
|
||||
}
|
||||
}
|
||||
return installerName;
|
||||
}
|
||||
|
||||
public boolean isRuntime() {
|
||||
return hasArgument("--runtime-image")
|
||||
&& !hasArgument("--main-jar")
|
||||
|
@ -51,7 +51,7 @@ public class LinuxHelper {
|
||||
public static String getPackageName(JPackageCommand cmd) {
|
||||
cmd.verifyIsOfType(PackageType.LINUX);
|
||||
return cmd.getArgumentValue("--linux-package-name",
|
||||
() -> cmd.name().toLowerCase());
|
||||
() -> cmd.installerName().toLowerCase());
|
||||
}
|
||||
|
||||
public static Path getDesktopFile(JPackageCommand cmd) {
|
||||
|
@ -194,7 +194,7 @@ public class MacHelper {
|
||||
|
||||
private static String getPackageName(JPackageCommand cmd) {
|
||||
return cmd.getArgumentValue("--mac-package-name",
|
||||
() -> cmd.name());
|
||||
() -> cmd.installerName());
|
||||
}
|
||||
|
||||
public static final class PListWrapper {
|
||||
|
@ -40,7 +40,7 @@ public class WindowsHelper {
|
||||
|
||||
static String getBundleName(JPackageCommand cmd) {
|
||||
cmd.verifyIsOfType(PackageType.WINDOWS);
|
||||
return String.format("%s-%s%s", cmd.name(), cmd.version(),
|
||||
return String.format("%s-%s%s", cmd.installerName(), cmd.version(),
|
||||
cmd.packageType().getSuffix());
|
||||
}
|
||||
|
||||
|
99
test/jdk/tools/jpackage/share/MultiNameTwoPhaseTest.java
Normal file
99
test/jdk/tools/jpackage/share/MultiNameTwoPhaseTest.java
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.io.IOException;
|
||||
import jdk.jpackage.test.PackageTest;
|
||||
import jdk.jpackage.test.PackageType;
|
||||
import jdk.jpackage.test.TKit;
|
||||
import jdk.jpackage.test.Annotations.Test;
|
||||
import jdk.jpackage.test.Annotations.Parameter;
|
||||
import jdk.jpackage.test.JPackageCommand;
|
||||
|
||||
/**
|
||||
* Test creation of packages in tho phases with different names.
|
||||
* The first phase creates and app image, and the second phase uses that image.
|
||||
* If the first phase has no --name, it will derive name from main-class.
|
||||
* If the second phase has no --name, will derive it from the app-image content.
|
||||
* The resulting name may differ, and all should still work
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Multiple names in two phases
|
||||
* @library ../helpers
|
||||
* @library /test/lib
|
||||
* @key jpackagePlatformPackage
|
||||
* @requires (jpackage.test.SQETest == null)
|
||||
* @build jdk.jpackage.test.*
|
||||
* @modules jdk.jpackage/jdk.jpackage.internal
|
||||
* @compile MultiNameTwoPhaseTest.java
|
||||
* @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main
|
||||
* --jpt-run=MultiNameTwoPhaseTest
|
||||
*/
|
||||
|
||||
public class MultiNameTwoPhaseTest {
|
||||
|
||||
@Test
|
||||
@Parameter({"MultiNameTest", "MultiNameTest"})
|
||||
@Parameter({"MultiNameTest", "MultiNameTestInstaller"})
|
||||
@Parameter({"MultiNameTest", ""})
|
||||
@Parameter({"", "MultiNameTestInstaller"})
|
||||
@Parameter({"", ""})
|
||||
public static void test(String... testArgs) throws IOException {
|
||||
String appName = testArgs[0];
|
||||
String installName = testArgs[1];
|
||||
|
||||
Path appimageOutput = TKit.createTempDirectory("appimage");
|
||||
|
||||
JPackageCommand appImageCmd = JPackageCommand.helloAppImage()
|
||||
.setArgumentValue("--dest", appimageOutput)
|
||||
.removeArgumentWithValue("--name");
|
||||
if (!appName.isEmpty()) {
|
||||
appImageCmd.addArguments("--name", appName);
|
||||
}
|
||||
|
||||
PackageTest packageTest = new PackageTest()
|
||||
.addRunOnceInitializer(() -> appImageCmd.execute())
|
||||
.addBundleDesktopIntegrationVerifier(true)
|
||||
.addInitializer(cmd -> {
|
||||
cmd.addArguments("--app-image", appImageCmd.outputBundle());
|
||||
cmd.removeArgumentWithValue("--input");
|
||||
cmd.removeArgumentWithValue("--name");
|
||||
if (!installName.isEmpty()) {
|
||||
cmd.addArguments("--name", installName);
|
||||
}
|
||||
})
|
||||
.forTypes(PackageType.WINDOWS)
|
||||
.addInitializer(cmd -> {
|
||||
cmd.addArguments("--win-shortcut", "--win-menu",
|
||||
"--win-menu-group", "MultiNameTwoPhaseTest");
|
||||
})
|
||||
.forTypes(PackageType.LINUX)
|
||||
.addInitializer(cmd -> {
|
||||
cmd.addArguments("--linux-shortcut");
|
||||
});
|
||||
|
||||
packageTest.run();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user