8287971: Throw exception for missing values in .jpackage.xml
Reviewed-by: asemenyuk
This commit is contained in:
parent
d7b43af591
commit
70008da6b4
src/jdk.jpackage
macosx/classes/jdk/jpackage/internal
share/classes/jdk/jpackage/internal
test/jdk/tools/jpackage
helpers/jdk/jpackage/test
junit/jdk/jpackage/internal
share
@ -140,14 +140,9 @@ public abstract class MacBaseInstallerBundler extends AbstractBundler {
|
||||
SIGN_BUNDLE.fetchFrom(params)).orElse(Boolean.FALSE)) {
|
||||
// if signing bundle with app-image, warn user if app-image
|
||||
// is not already signed.
|
||||
try {
|
||||
if (!(AppImageFile.load(applicationImage).isSigned())) {
|
||||
Log.info(MessageFormat.format(I18N.getString(
|
||||
"warning.unsigned.app.image"), getID()));
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
// Ignore - In case of a forign or tampered with app-image,
|
||||
// user is notified of this when the name is extracted.
|
||||
if (!(AppImageFile.load(applicationImage).isSigned())) {
|
||||
Log.info(MessageFormat.format(I18N.getString(
|
||||
"warning.unsigned.app.image"), getID()));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -73,14 +73,47 @@ public final class AppImageFile {
|
||||
Platform.LINUX, "linux", Platform.WINDOWS, "windows", Platform.MAC,
|
||||
"macOS");
|
||||
|
||||
|
||||
private AppImageFile() {
|
||||
this(null, null, null, null, null, null, null);
|
||||
}
|
||||
|
||||
private AppImageFile(String launcherName, String mainClass,
|
||||
private AppImageFile(Path appImageDir, String launcherName, String mainClass,
|
||||
List<LauncherInfo> launcherInfos, String creatorVersion,
|
||||
String creatorPlatform, String signedStr, String appStoreStr) {
|
||||
boolean isValid = true;
|
||||
if (!Objects.equals(getVersion(), creatorVersion)) {
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
if (!Objects.equals(getPlatform(), creatorPlatform)) {
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
if (launcherName == null || launcherName.length() == 0) {
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
if (mainClass == null || mainClass.length() == 0) {
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
for (var launcher : launcherInfos) {
|
||||
if ("".equals(launcher.getName())) {
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (signedStr == null ||
|
||||
!("true".equals(signedStr) || "false".equals(signedStr))) {
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
if (appStoreStr == null ||
|
||||
!("true".equals(appStoreStr) || "false".equals(appStoreStr))) {
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
if (!isValid) {
|
||||
throw new RuntimeException(MessageFormat.format(I18N.getString(
|
||||
"error.invalid-app-image"), appImageDir));
|
||||
}
|
||||
|
||||
this.launcherName = launcherName;
|
||||
this.mainClass = mainClass;
|
||||
this.addLauncherInfos = launcherInfos;
|
||||
@ -121,10 +154,6 @@ public final class AppImageFile {
|
||||
return appStore;
|
||||
}
|
||||
|
||||
void verifyCompatible() throws ConfigException {
|
||||
// Just do nothing for now.
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns path to application image info file.
|
||||
* @param appImageDir - path to application image
|
||||
@ -189,7 +218,7 @@ public final class AppImageFile {
|
||||
* @return valid info about application image or null
|
||||
* @throws IOException
|
||||
*/
|
||||
static AppImageFile load(Path appImageDir) throws IOException {
|
||||
static AppImageFile load(Path appImageDir) {
|
||||
try {
|
||||
Document doc = readXml(appImageDir);
|
||||
|
||||
@ -197,17 +226,9 @@ public final class AppImageFile {
|
||||
|
||||
String mainLauncher = xpathQueryNullable(xPath,
|
||||
"/jpackage-state/main-launcher/text()", doc);
|
||||
if (mainLauncher == null) {
|
||||
// No main launcher, this is fatal.
|
||||
return new AppImageFile();
|
||||
}
|
||||
|
||||
String mainClass = xpathQueryNullable(xPath,
|
||||
"/jpackage-state/main-class/text()", doc);
|
||||
if (mainClass == null) {
|
||||
// No main class, this is fatal.
|
||||
return new AppImageFile();
|
||||
}
|
||||
|
||||
List<LauncherInfo> launcherInfos = new ArrayList<>();
|
||||
|
||||
@ -231,15 +252,17 @@ public final class AppImageFile {
|
||||
launcherInfos.add(new LauncherInfo(launcherNodes.item(i)));
|
||||
}
|
||||
|
||||
AppImageFile file = new AppImageFile(mainLauncher, mainClass,
|
||||
return new AppImageFile(appImageDir, mainLauncher, mainClass,
|
||||
launcherInfos, version, platform, signedStr, appStoreStr);
|
||||
if (!file.isValid()) {
|
||||
file = new AppImageFile();
|
||||
}
|
||||
return file;
|
||||
} catch (XPathExpressionException ex) {
|
||||
// This should never happen as XPath expressions should be correct
|
||||
throw new RuntimeException(ex);
|
||||
} catch (NoSuchFileException nsfe) {
|
||||
// non jpackage generated app-image (no app/.jpackage.xml)
|
||||
throw new RuntimeException(MessageFormat.format(I18N.getString(
|
||||
"error.foreign-app-image"), appImageDir));
|
||||
} catch (IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
@ -275,23 +298,11 @@ public final class AppImageFile {
|
||||
Map<String, Object> params) {
|
||||
List<LauncherInfo> launchers = new ArrayList<>();
|
||||
if (appImageDir != null) {
|
||||
try {
|
||||
AppImageFile appImageInfo = AppImageFile.load(appImageDir);
|
||||
if (appImageInfo != null) {
|
||||
launchers.add(new LauncherInfo(
|
||||
appImageInfo.getLauncherName(), params));
|
||||
AppImageFile appImageInfo = AppImageFile.load(appImageDir);
|
||||
launchers.add(new LauncherInfo(
|
||||
appImageInfo.getLauncherName(), params));
|
||||
launchers.addAll(appImageInfo.getAddLaunchers());
|
||||
return launchers;
|
||||
}
|
||||
} catch (NoSuchFileException nsfe) {
|
||||
// non jpackage generated app-image (no app/.jpackage.xml)
|
||||
Log.info(MessageFormat.format(I18N.getString(
|
||||
"warning.foreign-app-image"), appImageDir));
|
||||
} catch (IOException ioe) {
|
||||
Log.verbose(ioe);
|
||||
Log.info(MessageFormat.format(I18N.getString(
|
||||
"warning.invalid-app-image"), appImageDir));
|
||||
}
|
||||
return launchers;
|
||||
}
|
||||
|
||||
launchers.add(new LauncherInfo(params));
|
||||
@ -302,23 +313,11 @@ public final class AppImageFile {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
return AppImageFile.load(appImageDir).getLauncherName();
|
||||
}
|
||||
|
||||
public static String extractMainClass(Path appImageDir) {
|
||||
try {
|
||||
return AppImageFile.load(appImageDir).getMainClass();
|
||||
} catch (IOException ioe) {
|
||||
Log.verbose(MessageFormat.format(I18N.getString(
|
||||
"warning.foreign-app-image"), appImageDir));
|
||||
return null;
|
||||
}
|
||||
return AppImageFile.load(appImageDir).getMainClass();
|
||||
}
|
||||
|
||||
private static String xpathQueryNullable(XPath xPath, String xpathExpr,
|
||||
@ -331,36 +330,14 @@ public final class AppImageFile {
|
||||
return null;
|
||||
}
|
||||
|
||||
static String getVersion() {
|
||||
return "1.0";
|
||||
public static String getVersion() {
|
||||
return System.getProperty("java.version");
|
||||
}
|
||||
|
||||
static String getPlatform() {
|
||||
public static String getPlatform() {
|
||||
return PLATFORM_LABELS.get(Platform.getPlatform());
|
||||
}
|
||||
|
||||
private boolean isValid() {
|
||||
if (launcherName == null || launcherName.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var launcher : addLauncherInfos) {
|
||||
if ("".equals(launcher.getName())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Objects.equals(getVersion(), creatorVersion)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Objects.equals(getPlatform(), creatorPlatform)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static class LauncherInfo {
|
||||
private final String name;
|
||||
private final boolean shortcut;
|
||||
|
@ -531,12 +531,8 @@ class StandardBundlerParam<T> extends BundlerParamInfo<T> {
|
||||
Boolean.class,
|
||||
params -> {
|
||||
if (hasPredefinedAppImage(params)) {
|
||||
try {
|
||||
return AppImageFile.load(getPredefinedAppImage(params))
|
||||
.isAppStore();
|
||||
} catch (IOException ex) {
|
||||
return false;
|
||||
}
|
||||
return AppImageFile.load(getPredefinedAppImage(params))
|
||||
.isAppStore();
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
@ -77,8 +77,9 @@ 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.
|
||||
warning.invalid-app-image=Warning: cannot parse .jpackage.xml in app-image dir ({0})
|
||||
|
||||
error.foreign-app-image=Error: Missing .jpackage.xml file in app-image dir ({0})
|
||||
error.invalid-app-image=Error: app-image dir ({0}) generated by another jpackage version or malformed .jpackage.xml
|
||||
|
||||
MSG_BundlerFailed=Error: Bundler "{1}" ({0}) failed to produce a package
|
||||
MSG_BundlerConfigException=Bundler {0} skipped because of a configuration problem: {1} \n\
|
||||
|
@ -75,8 +75,9 @@ error.blocked.option=jlink-Option [{0}] ist in --jlink-options nicht zul\u00E4ss
|
||||
error.no.name=Name nicht mit --name angegeben. Es kann auch kein Name aus app-image abgeleitet werden
|
||||
|
||||
warning.no.jdk.modules.found=Warnung: Keine JDK-Module gefunden
|
||||
warning.foreign-app-image=Warnung: app-image-Verzeichnis ({0}) wurde von jpackage nicht generiert.
|
||||
warning.invalid-app-image=Warnung: .jpackage.xml kann in app-image-Verzeichnis ({0}) nicht geparst werden
|
||||
|
||||
error.foreign-app-image=Error: Missing .jpackage.xml file in app-image dir ({0})
|
||||
error.invalid-app-image=Error: app-image dir ({0}) generated by another jpackage version or malformed .jpackage.xml
|
||||
|
||||
MSG_BundlerFailed=Fehler: Bundler "{1}" ({0}) konnte kein Package generieren
|
||||
MSG_BundlerConfigException=Bundler {0} aufgrund eines Konfigurationsproblems \u00FCbersprungen: {1} \nEmpfehlung zur Behebung: {2}
|
||||
|
@ -75,8 +75,9 @@ error.blocked.option=jlink\u30AA\u30D7\u30B7\u30E7\u30F3[{0}]\u306F--jlink-optio
|
||||
error.no.name=\u540D\u524D\u304C--name\u3067\u6307\u5B9A\u3055\u308C\u3066\u304A\u3089\u305A\u3001app-image\u304B\u3089\u63A8\u8AD6\u3067\u304D\u307E\u305B\u3093
|
||||
|
||||
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=\u8B66\u544A: app-image\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA({0})\u306Fjpackage\u3067\u751F\u6210\u3055\u308C\u307E\u305B\u3093\u3002
|
||||
warning.invalid-app-image=\u8B66\u544A: app-image\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA({0})\u306E.jpackage.xml\u3092\u89E3\u6790\u3067\u304D\u307E\u305B\u3093
|
||||
|
||||
error.foreign-app-image=Error: Missing .jpackage.xml file in app-image dir ({0})
|
||||
error.invalid-app-image=Error: app-image dir ({0}) generated by another jpackage version or malformed .jpackage.xml
|
||||
|
||||
MSG_BundlerFailed=\u30A8\u30E9\u30FC: \u30D0\u30F3\u30C9\u30E9"{1}" ({0})\u304C\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u751F\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F
|
||||
MSG_BundlerConfigException=\u69CB\u6210\u306E\u554F\u984C\u306E\u305F\u3081\u3001\u30D0\u30F3\u30C9\u30E9{0}\u304C\u30B9\u30AD\u30C3\u30D7\u3055\u308C\u307E\u3057\u305F: {1} \n\u6B21\u306E\u4FEE\u6B63\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044: {2}
|
||||
|
@ -75,8 +75,9 @@ error.blocked.option=\u4E0D\u5141\u8BB8\u5728 --jlink-options \u4E2D\u4F7F\u7528
|
||||
error.no.name=\u672A\u4F7F\u7528 --name \u6307\u5B9A\u540D\u79F0\uFF0C\u65E0\u6CD5\u4ECE app-image \u63A8\u65AD\u540D\u79F0
|
||||
|
||||
warning.no.jdk.modules.found=\u8B66\u544A: \u672A\u627E\u5230 JDK \u6A21\u5757
|
||||
warning.foreign-app-image=\u8B66\u544A\uFF1Ajpackage \u672A\u751F\u6210 app-image \u76EE\u5F55 ({0})\u3002
|
||||
warning.invalid-app-image=\u8B66\u544A\uFF1A\u65E0\u6CD5\u89E3\u6790 app-image \u76EE\u5F55 ({0}) \u4E2D\u7684 .jpackage.xml
|
||||
|
||||
error.foreign-app-image=Error: Missing .jpackage.xml file in app-image dir ({0})
|
||||
error.invalid-app-image=Error: app-image dir ({0}) generated by another jpackage version or malformed .jpackage.xml
|
||||
|
||||
MSG_BundlerFailed=\u9519\u8BEF\uFF1A\u6253\u5305\u7A0B\u5E8F "{1}" ({0}) \u65E0\u6CD5\u751F\u6210\u7A0B\u5E8F\u5305
|
||||
MSG_BundlerConfigException=\u7531\u4E8E\u914D\u7F6E\u95EE\u9898, \u8DF3\u8FC7\u4E86\u6253\u5305\u7A0B\u5E8F{0}: {1} \n\u4FEE\u590D\u5EFA\u8BAE: {2}
|
||||
|
@ -45,6 +45,7 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import jdk.jpackage.internal.IOUtils;
|
||||
import jdk.jpackage.internal.AppImageFile;
|
||||
import jdk.jpackage.internal.ApplicationLayout;
|
||||
import jdk.jpackage.internal.PackageFile;
|
||||
@ -298,6 +299,42 @@ public final class JPackageCommand extends CommandArguments<JPackageCommand> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public void createJPackageXMLFile(String mainLauncher, String mainClass)
|
||||
throws IOException {
|
||||
Path jpackageXMLFile = AppImageFile.getPathInAppImage(
|
||||
Optional.ofNullable(getArgumentValue("--app-image")).map(
|
||||
Path::of).orElseThrow(() -> {
|
||||
return new RuntimeException(
|
||||
"Error: --app-image expected");
|
||||
}));
|
||||
|
||||
IOUtils.createXml(jpackageXMLFile, xml -> {
|
||||
xml.writeStartElement("jpackage-state");
|
||||
xml.writeAttribute("version", AppImageFile.getVersion());
|
||||
xml.writeAttribute("platform", AppImageFile.getPlatform());
|
||||
|
||||
xml.writeStartElement("app-version");
|
||||
xml.writeCharacters("1.0");
|
||||
xml.writeEndElement();
|
||||
|
||||
xml.writeStartElement("main-launcher");
|
||||
xml.writeCharacters(mainLauncher);
|
||||
xml.writeEndElement();
|
||||
|
||||
xml.writeStartElement("main-class");
|
||||
xml.writeCharacters(mainClass);
|
||||
xml.writeEndElement();
|
||||
|
||||
xml.writeStartElement("signed");
|
||||
xml.writeCharacters("false");
|
||||
xml.writeEndElement();
|
||||
|
||||
xml.writeStartElement("app-store");
|
||||
xml.writeCharacters("false");
|
||||
xml.writeEndElement();
|
||||
});
|
||||
}
|
||||
|
||||
JPackageCommand addPrerequisiteAction(ThrowingConsumer<JPackageCommand> action) {
|
||||
verifyMutable();
|
||||
prerequisiteActions.add(action);
|
||||
|
@ -35,6 +35,7 @@ import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.junit.function.ThrowingRunnable;
|
||||
|
||||
public class AppImageFileTest {
|
||||
|
||||
@ -74,19 +75,19 @@ public class AppImageFileTest {
|
||||
|
||||
@Test
|
||||
public void testInavlidXml() throws IOException {
|
||||
assertInvalid(createFromXml("<foo/>"));
|
||||
assertInvalid(createFromXml("<jpackage-state/>"));
|
||||
assertInvalid(createFromXml(JPACKAGE_STATE_OPEN, "</jpackage-state>"));
|
||||
assertInvalid(createFromXml(
|
||||
assertInvalid(() -> createFromXml("<foo/>"));
|
||||
assertInvalid(() -> createFromXml("<jpackage-state/>"));
|
||||
assertInvalid(() -> createFromXml(JPACKAGE_STATE_OPEN, "</jpackage-state>"));
|
||||
assertInvalid(() -> createFromXml(
|
||||
JPACKAGE_STATE_OPEN,
|
||||
"<main-launcher></main-launcher>",
|
||||
"</jpackage-state>"));
|
||||
assertInvalid(createFromXml(
|
||||
assertInvalid(() -> createFromXml(
|
||||
JPACKAGE_STATE_OPEN,
|
||||
"<main-launcher>Foo</main-launcher>",
|
||||
"<main-class></main-class>",
|
||||
"</jpackage-state>"));
|
||||
assertInvalid(createFromXml(
|
||||
assertInvalid(() -> createFromXml(
|
||||
JPACKAGE_STATE_OPEN,
|
||||
"<launcher>A</launcher>",
|
||||
"<launcher>B</launcher>",
|
||||
@ -99,6 +100,8 @@ public class AppImageFileTest {
|
||||
JPACKAGE_STATE_OPEN,
|
||||
"<main-launcher>Foo</main-launcher>",
|
||||
"<main-class>main.Class</main-class>",
|
||||
"<signed>false</signed>",
|
||||
"<app-store>false</app-store>",
|
||||
"</jpackage-state>")).getLauncherName());
|
||||
|
||||
Assert.assertEquals("Boo", (createFromXml(
|
||||
@ -106,12 +109,16 @@ public class AppImageFileTest {
|
||||
"<main-launcher>Boo</main-launcher>",
|
||||
"<main-launcher>Bar</main-launcher>",
|
||||
"<main-class>main.Class</main-class>",
|
||||
"<signed>false</signed>",
|
||||
"<app-store>false</app-store>",
|
||||
"</jpackage-state>")).getLauncherName());
|
||||
|
||||
var file = createFromXml(
|
||||
JPACKAGE_STATE_OPEN,
|
||||
"<main-launcher>Foo</main-launcher>",
|
||||
"<main-class>main.Class</main-class>",
|
||||
"<signed>false</signed>",
|
||||
"<app-store>false</app-store>",
|
||||
"<launcher></launcher>",
|
||||
"</jpackage-state>");
|
||||
Assert.assertEquals("Foo", file.getLauncherName());
|
||||
@ -199,9 +206,10 @@ public class AppImageFileTest {
|
||||
return AppImageFile.load(tempFolder.getRoot().toPath());
|
||||
}
|
||||
|
||||
private void assertInvalid(AppImageFile file) {
|
||||
Assert.assertNull(file.getLauncherName());
|
||||
Assert.assertNull(file.getAddLaunchers());
|
||||
private void assertInvalid(ThrowingRunnable action) {
|
||||
Exception ex = Assert.assertThrows(RuntimeException.class, action);
|
||||
Assert.assertTrue(ex instanceof RuntimeException);
|
||||
Assert.assertTrue(ex.getMessage().contains("malformed .jpackage.xml"));
|
||||
}
|
||||
|
||||
private AppImageFile createFromXml(String... xmlData) throws IOException {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2022, 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
|
||||
@ -87,6 +87,7 @@ public class AppImagePackageTest {
|
||||
cmd.addArguments("--icon", iconPath("icon"));
|
||||
}
|
||||
cmd.removeArgumentWithValue("--input");
|
||||
cmd.createJPackageXMLFile("EmptyAppImagePackageTest", "Hello");
|
||||
|
||||
// on mac, with --app-image and without --mac-package-identifier,
|
||||
// will try to infer it from the image, so foreign image needs it.
|
||||
@ -101,4 +102,5 @@ public class AppImagePackageTest {
|
||||
return TKit.TEST_SRC_ROOT.resolve(Path.of("resources", name
|
||||
+ TKit.ICON_SUFFIX));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -113,6 +113,7 @@ public final class PredefinedAppImageErrorTest {
|
||||
Files.createFile(dummyAppFile);
|
||||
|
||||
cmd.addArguments("--app-image", dummyAppFolder.toString());
|
||||
cmd.createJPackageXMLFile("PredefinedAppImageErrorTest", "Hello");
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user