8357930: Amendment for JDK-8333664

Reviewed-by: almatvee
This commit is contained in:
Alexey Semenyuk 2025-05-28 16:18:46 +00:00
parent e579cca619
commit 8949c07484
20 changed files with 342 additions and 203 deletions

View File

@ -26,12 +26,13 @@ package jdk.jpackage.internal;
import static jdk.jpackage.internal.AppImageFile.getBooleanExtraFieldValue;
import jdk.jpackage.internal.model.ExternalApplication;
import jdk.jpackage.internal.model.MacApplication.ExtraAppImageFileField;
record MacAppImageFileExtras(boolean signed, boolean appStore) {
MacAppImageFileExtras(AppImageFile appImageFile) {
this(getBooleanExtraFieldValue(ExtraAppImageFileField.SIGNED.fieldName(), appImageFile),
getBooleanExtraFieldValue(ExtraAppImageFileField.APP_STORE.fieldName(), appImageFile));
MacAppImageFileExtras(ExternalApplication app) {
this(getBooleanExtraFieldValue(ExtraAppImageFileField.SIGNED.fieldName(), app),
getBooleanExtraFieldValue(ExtraAppImageFileField.APP_STORE.fieldName(), app));
}
}

View File

@ -47,6 +47,7 @@ import jdk.internal.util.OperatingSystem;
import jdk.jpackage.internal.model.Application;
import jdk.jpackage.internal.model.ApplicationLayout;
import jdk.jpackage.internal.model.ConfigException;
import jdk.jpackage.internal.model.ExternalApplication;
import jdk.jpackage.internal.model.Launcher;
import jdk.jpackage.internal.util.XmlUtils;
import org.w3c.dom.Document;
@ -55,7 +56,7 @@ import org.w3c.dom.Node;
import org.xml.sax.SAXException;
final class AppImageFile {
final class AppImageFile implements ExternalApplication {
AppImageFile(Application app) {
this(new ApplicationData(app));
@ -72,47 +73,33 @@ final class AppImageFile {
addLauncherInfos = app.additionalLaunchers;
}
/**
* Returns list of additional launchers configured for the application.
*
* Returns empty list for application without additional launchers.
*/
List<LauncherInfo> getAddLaunchers() {
@Override
public List<LauncherInfo> getAddLaunchers() {
return addLauncherInfos;
}
/**
* Returns application version. Never returns null or empty value.
*/
String getAppVersion() {
@Override
public String getAppVersion() {
return appVersion;
}
/**
* Returns application name. Never returns null or empty value.
*/
String getAppName() {
@Override
public String getAppName() {
return launcherName;
}
/**
* Returns main application launcher name. Never returns null or empty value.
*/
String getLauncherName() {
@Override
public String getLauncherName() {
return launcherName;
}
/**
* Returns main class name. Never returns null or empty value.
*/
String getMainClass() {
@Override
public String getMainClass() {
return mainClass;
}
/**
* Returns additional properties. Never returns null.
*/
Map<String, String> getExtra() {
@Override
public Map<String, String> getExtra() {
return extra;
}
@ -223,7 +210,7 @@ final class AppImageFile {
}
}
static boolean getBooleanExtraFieldValue(String fieldId, AppImageFile appImageFile) {
static boolean getBooleanExtraFieldValue(String fieldId, ExternalApplication appImageFile) {
Objects.requireNonNull(fieldId);
Objects.requireNonNull(appImageFile);
return Optional.ofNullable(appImageFile.getExtra().get(fieldId)).map(Boolean::parseBoolean).orElse(false);
@ -318,16 +305,6 @@ final class AppImageFile {
}
}
record LauncherInfo(String name, boolean service, Map<String, String> extra) {
LauncherInfo {
Objects.requireNonNull(name);
Objects.requireNonNull(extra);
if (name.isBlank()) {
throw new IllegalArgumentException();
}
}
}
private record ApplicationData(String version, String mainLauncherName, String mainLauncherMainClassName,
Map<String, String> extra, List<LauncherInfo> additionalLaunchers) {

View File

@ -33,11 +33,12 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import jdk.jpackage.internal.AppImageFile.LauncherInfo;
import jdk.jpackage.internal.model.AppImageLayout;
import jdk.jpackage.internal.model.Application;
import jdk.jpackage.internal.model.ApplicationLaunchers;
import jdk.jpackage.internal.model.ConfigException;
import jdk.jpackage.internal.model.ExternalApplication;
import jdk.jpackage.internal.model.ExternalApplication.LauncherInfo;
import jdk.jpackage.internal.model.Launcher;
import jdk.jpackage.internal.model.LauncherStartupInfo;
import jdk.jpackage.internal.model.RuntimeBuilder;
@ -83,21 +84,21 @@ final class ApplicationBuilder {
return this;
}
ApplicationBuilder initFromAppImage(AppImageFile appImageFile,
ApplicationBuilder initFromExternalApplication(ExternalApplication app,
Function<LauncherInfo, Launcher> mapper) {
if (version == null) {
version = appImageFile.getAppVersion();
version = app.getAppVersion();
}
if (name == null) {
name = appImageFile.getAppName();
name = app.getAppName();
}
runtimeBuilder = null;
var mainLauncherInfo = new LauncherInfo(appImageFile.getLauncherName(), false, Map.of());
var mainLauncherInfo = new LauncherInfo(app.getLauncherName(), false, Map.of());
launchers = new ApplicationLaunchers(
mapper.apply(mainLauncherInfo),
appImageFile.getAddLaunchers().stream().map(mapper).toList());
app.getAddLaunchers().stream().map(mapper).toList());
return this;
}

View File

@ -34,7 +34,6 @@ import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.stream.Stream;
import jdk.jpackage.internal.model.FileAssociation;
import jdk.jpackage.internal.util.CollectionUtils;
final record FileAssociationGroup(List<FileAssociation> items) {
@ -113,12 +112,12 @@ final record FileAssociationGroup(List<FileAssociation> items) {
}
Builder mimeTypes(Collection<String> v) {
mimeTypes = CollectionUtils.toSet(v);
mimeTypes = Set.copyOf(v);
return this;
}
Builder extensions(Collection<String> v) {
extensions = CollectionUtils.toSet(v);
extensions = Set.copyOf(v);
return this;
}

View File

@ -57,11 +57,11 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import jdk.jpackage.internal.AppImageFile.LauncherInfo;
import jdk.jpackage.internal.model.Application;
import jdk.jpackage.internal.model.ApplicationLaunchers;
import jdk.jpackage.internal.model.ApplicationLayout;
import jdk.jpackage.internal.model.ConfigException;
import jdk.jpackage.internal.model.ExternalApplication.LauncherInfo;
import jdk.jpackage.internal.model.Launcher;
import jdk.jpackage.internal.model.PackageType;
import jdk.jpackage.internal.model.RuntimeLayout;
@ -103,7 +103,7 @@ final class FromParams {
if (hasPredefinedAppImage(params)) {
final var appImageFile = PREDEFINED_APP_IMAGE_FILE.fetchFrom(params);
appBuilder.initFromAppImage(appImageFile, launcherInfo -> {
appBuilder.initFromExternalApplication(appImageFile, launcherInfo -> {
var launcherParams = mapLauncherInfo(launcherInfo);
return launcherMapper.apply(mergeParams(params, launcherParams));
});

View File

@ -24,12 +24,9 @@
*/
package jdk.jpackage.internal;
import jdk.internal.util.OperatingSystem;
import jdk.jpackage.internal.model.ConfigException;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleReference;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
@ -38,9 +35,7 @@ import java.text.MessageFormat;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.function.Supplier;
import java.util.jar.Attributes;
@ -76,7 +71,7 @@ final class LauncherData {
String moduleName() {
verifyIsModular(true);
return moduleInfo.name;
return moduleInfo.name();
}
List<Path> modulePath() {
@ -95,7 +90,7 @@ final class LauncherData {
String getAppVersion() {
if (isModular()) {
return moduleInfo.version;
return moduleInfo.version().orElse(null);
}
return null;
@ -145,15 +140,14 @@ final class LauncherData {
launcherData.modulePath).find(moduleName).orElse(null);
if (moduleRef != null) {
launcherData.moduleInfo = ModuleInfo.fromModuleDescriptor(
moduleRef.descriptor());
launcherData.moduleInfo = ModuleInfo.fromModuleReference(moduleRef);
} else if (params.containsKey(PREDEFINED_RUNTIME_IMAGE.getID())) {
// Failed to find module in the specified module path list and
// there is external runtime given to jpackage.
// Lookup module in this runtime.
Path cookedRuntime = PREDEFINED_RUNTIME_IMAGE.fetchFrom(params);
launcherData.moduleInfo = ModuleInfo.fromCookedRuntime(moduleName,
cookedRuntime);
cookedRuntime).orElse(null);
}
if (launcherData.moduleInfo == null) {
@ -162,7 +156,7 @@ final class LauncherData {
}
if (launcherData.qualifiedClassName == null) {
launcherData.qualifiedClassName = launcherData.moduleInfo.mainClass;
launcherData.qualifiedClassName = launcherData.moduleInfo.mainClass().orElse(null);
if (launcherData.qualifiedClassName == null) {
throw new ConfigException(I18N.getString("ERR_NoMainClass"), null);
}
@ -310,76 +304,4 @@ final class LauncherData {
private List<Path> classPath;
private List<Path> modulePath;
private ModuleInfo moduleInfo;
private static final class ModuleInfo {
String name;
String version;
String mainClass;
static ModuleInfo fromModuleDescriptor(ModuleDescriptor md) {
ModuleInfo result = new ModuleInfo();
result.name = md.name();
result.mainClass = md.mainClass().orElse(null);
ModuleDescriptor.Version ver = md.version().orElse(null);
if (ver != null) {
result.version = ver.toString();
} else {
result.version = md.rawVersion().orElse(null);
}
return result;
}
static ModuleInfo fromCookedRuntime(String moduleName,
Path cookedRuntime) {
Objects.requireNonNull(moduleName);
// We can't extract info about version and main class of a module
// linked in external runtime without running ModuleFinder in that
// runtime. But this is too much work as the runtime might have been
// coocked without native launchers. So just make sure the module
// is linked in the runtime by simply analysing the data
// of `release` file.
final Path releaseFile;
if (!OperatingSystem.isMacOS()) {
releaseFile = cookedRuntime.resolve("release");
} else {
// On Mac `cookedRuntime` can be runtime root or runtime home.
Path runtimeHome = cookedRuntime.resolve("Contents/Home");
if (!Files.isDirectory(runtimeHome)) {
runtimeHome = cookedRuntime;
}
releaseFile = runtimeHome.resolve("release");
}
try (Reader reader = Files.newBufferedReader(releaseFile)) {
Properties props = new Properties();
props.load(reader);
String moduleList = props.getProperty("MODULES");
if (moduleList == null) {
return null;
}
if ((moduleList.startsWith("\"") && moduleList.endsWith("\""))
|| (moduleList.startsWith("\'") && moduleList.endsWith(
"\'"))) {
moduleList = moduleList.substring(1, moduleList.length() - 1);
}
if (!List.of(moduleList.split("\\s+")).contains(moduleName)) {
return null;
}
} catch (IOException|IllegalArgumentException ex) {
Log.verbose(ex);
return null;
}
ModuleInfo result = new ModuleInfo();
result.name = moduleName;
return result;
}
}
}

View File

@ -43,8 +43,7 @@ final class LauncherStartupInfoBuilder {
LauncherStartupInfoBuilder launcherData(LauncherData launcherData) {
if (launcherData.isModular()) {
decorator = new ModuleStartupInfo(launcherData.moduleName(),
launcherData.modulePath());
decorator = new ModuleStartupInfo(launcherData.moduleName());
} else {
decorator = new JarStartupInfo(launcherData.mainJarName(),
launcherData.isClassNameFromMainJar());
@ -64,14 +63,12 @@ final class LauncherStartupInfoBuilder {
return this;
}
private static record ModuleStartupInfo(String moduleName,
List<Path> modulePath) implements UnaryOperator<LauncherStartupInfo> {
private static record ModuleStartupInfo(String moduleName) implements UnaryOperator<LauncherStartupInfo> {
@Override
public LauncherStartupInfo apply(LauncherStartupInfo base) {
return LauncherModularStartupInfo.create(base,
new LauncherModularStartupInfoMixin.Stub(moduleName,
modulePath));
new LauncherModularStartupInfoMixin.Stub(moduleName));
}
}

View File

@ -0,0 +1,100 @@
/*
* Copyright (c) 2025, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package jdk.jpackage.internal;
import java.io.IOException;
import java.io.Reader;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleReference;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import jdk.internal.util.OperatingSystem;
record ModuleInfo(String name, Optional<String> version, Optional<String> mainClass, Optional<URI> location) {
Optional<Path> fileLocation() {
return location.filter(loc -> {
return loc.getScheme().equals("file");
}).map(Path::of);
}
static ModuleInfo fromModuleReference(ModuleReference mr) {
final var md = mr.descriptor();
return new ModuleInfo(md.name(), md.version().map(ModuleDescriptor.Version::toString).or(md::rawVersion), md.mainClass(), mr.location());
}
static Optional<ModuleInfo> fromCookedRuntime(String moduleName, Path cookedRuntime) {
Objects.requireNonNull(moduleName);
Objects.requireNonNull(cookedRuntime);
// We can't extract info about version and main class of a module
// linked in external runtime without running ModuleFinder in that
// runtime. But this is too much work as the runtime might have been
// coocked without native launchers. So just make sure the module
// is linked in the runtime by simply analysing the data
// of `release` file.
final Path releaseFile;
if (!OperatingSystem.isMacOS()) {
releaseFile = cookedRuntime.resolve("release");
} else {
// On Mac `cookedRuntime` can be runtime root or runtime home.
Path runtimeHome = cookedRuntime.resolve("Contents/Home");
if (!Files.isDirectory(runtimeHome)) {
runtimeHome = cookedRuntime;
}
releaseFile = runtimeHome.resolve("release");
}
try (Reader reader = Files.newBufferedReader(releaseFile)) {
Properties props = new Properties();
props.load(reader);
String moduleList = props.getProperty("MODULES");
if (moduleList == null) {
return Optional.empty();
}
if ((moduleList.startsWith("\"") && moduleList.endsWith("\""))
|| (moduleList.startsWith("\'") && moduleList.endsWith(
"\'"))) {
moduleList = moduleList.substring(1, moduleList.length() - 1);
}
if (!List.of(moduleList.split("\\s+")).contains(moduleName)) {
return Optional.empty();
}
} catch (IOException|IllegalArgumentException ex) {
Log.verbose(ex);
return Optional.empty();
}
return Optional.of(new ModuleInfo(moduleName, Optional.empty(), Optional.empty(), Optional.empty()));
}
}

View File

@ -41,6 +41,7 @@ import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
import jdk.jpackage.internal.model.ConfigException;
import jdk.jpackage.internal.model.ExternalApplication;
import static jdk.jpackage.internal.ApplicationLayoutUtils.PLATFORM_APPLICATION_LAYOUT;
import static jdk.jpackage.internal.model.RuntimeBuilder.getDefaultModulePath;
@ -93,8 +94,8 @@ final class StandardBundlerParam {
null
);
static final BundlerParamInfo<AppImageFile> PREDEFINED_APP_IMAGE_FILE = BundlerParamInfo.createBundlerParam(
AppImageFile.class, params -> {
static final BundlerParamInfo<ExternalApplication> PREDEFINED_APP_IMAGE_FILE = BundlerParamInfo.createBundlerParam(
ExternalApplication.class, params -> {
if (hasPredefinedAppImage(params)) {
var appImage = getPredefinedAppImage(params);
return AppImageFile.load(appImage, PLATFORM_APPLICATION_LAYOUT);

View File

@ -40,7 +40,7 @@ import java.util.stream.Stream;
*
* @see Package
*/
public interface Application {
public interface Application extends BundleSpec {
/**
* Gets the name of this application.

View File

@ -30,20 +30,18 @@ import java.nio.file.Path;
/**
* Creates app image directory from the given {@link Application} object.
*
* @ see PackageWriter
* Creates a bundle from the given specification.
*/
@FunctionalInterface
public interface ApplicationWriter {
public interface BundleCreator<T extends BundleSpec> {
/**
* Creates app image directory from the given {@link Application} object in the given directory.
* Creates a bundle from the given specification in the given directory.
*
* @param app the source application
* @param dst the directory where to create app image of the source application
* @param spec the bundle specification
* @param dst the directory where to create the bundle
* @throws PackagerException if packaging error occurs
* @throws IOException if an I/O error occurs
*/
void write(Application app, Path dst) throws PackagerException, IOException;
void create(T spec, Path dst) throws PackagerException, IOException;
}

View File

@ -22,26 +22,10 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.jpackage.internal.model;
import java.io.IOException;
import java.nio.file.Path;
/**
* Creates native package from the given {@link jdk.jpackage.internal.model.Package} object.
*
* @ see ApplicationWriter
* A generic bundle specification.
*/
@FunctionalInterface
public interface PackageWriter {
/**
* Creates native package from the given {@link jdk.jpackage.internal.model.Package} object in the given directory.
* @param pkg the source package
* @param dst the directory where to create a native package
* @throws PackagerException if packaging error occurs
* @throws IOException if an I/O error occurs
*/
void write(Package pkg, Path dst) throws PackagerException, IOException;
public interface BundleSpec {
}

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2025, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package jdk.jpackage.internal.model;
import java.util.Set;
/**
* Bundling environment. Defines available bundling operations.
*/
public interface BundlingEnvironment {
/**
* Returns the default bundling operation.
* <p>
* The returned value should be one of the elements in the collection returned by {@link #enabledOperations()} method.
* @return the default bundling operation
* @throws ConfigException in not a single bundling operation can be performed.
*/
BundlingOperation defaultOperation() throws ConfigException;
/**
* Returns supported bundling operations.
* @return the supported bundling operations
*/
Set<BundlingOperation> supportedOperations();
/**
* Returns enabled bundling operations.
* <p>
* The returned value should be a subset of the set returned by {@link #supportedOperations()} method.
* @return the enabled bundling operations
*/
default Set<BundlingOperation> enabledOperations() {
return supportedOperations();
}
/**
* Returns a bundle creator corresponding to the given bundling operation in this bundling environment.
* @param op the bundling operation
* @return bundle creator corresponding to the given bundling operation in this bundling environment
* @throws IllegalArgumentException if the given bundling operation is not enabled in this bundling environment
*/
BundleCreator<?> getBundleCreator(BundlingOperation op);
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2025, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package jdk.jpackage.internal.model;
/**
* Generic bundling operation.
* <p>
* Bundling operation is comprised of creating of {@link BundleSpec} instance
* and using it as an input for {@link BundleCreator#create()} method to create
* a bundle.
*/
public interface BundlingOperation {
}

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2025, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package jdk.jpackage.internal.model;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* Description of an external application image.
*/
public interface ExternalApplication {
/**
* Returns the list of additional launchers configured for the application.
* <p>
* Returns an empty list for an application without additional launchers.
* @return the list of additional launchers configured for the application
*/
List<LauncherInfo> getAddLaunchers();
/**
* Returns application version.
* @return the application version
*/
String getAppVersion();
/**
* Returns application name.
* @return the application name
*/
String getAppName();
/**
* Returns main launcher name.
* @return the main launcher name
*/
String getLauncherName();
/**
* Returns main class name.
* @return the main class name
*/
String getMainClass();
/**
* Returns additional properties.
* @return the additional properties
*/
Map<String, String> getExtra();
/**
* Additional launcher description.
*/
record LauncherInfo(String name, boolean service, Map<String, String> extra) {
public LauncherInfo {
Objects.requireNonNull(name);
Objects.requireNonNull(extra);
if (name.isBlank()) {
throw new IllegalArgumentException();
}
}
}
}

View File

@ -24,9 +24,6 @@
*/
package jdk.jpackage.internal.model;
import java.nio.file.Path;
import java.util.List;
/**
* Details of application launcher startup configuration using Java module.
*/
@ -38,16 +35,10 @@ public interface LauncherModularStartupInfoMixin {
*/
String moduleName();
/**
* Gets the path to the input module location.
* @return the path to the input module location
*/
List<Path> modulePath();
/**
* Default implementation of {@link LauncherModularStartupInfoMixin} interface.
*/
record Stub(String moduleName, List<Path> modulePath) implements LauncherModularStartupInfoMixin {
record Stub(String moduleName) implements LauncherModularStartupInfoMixin {
}
}

View File

@ -78,7 +78,7 @@ import java.util.Optional;
* </tr>
* </table>
*/
public interface Package {
public interface Package extends BundleSpec {
/**
* Gets the application of this package.

View File

@ -25,10 +25,6 @@
package jdk.jpackage.internal.util;
import java.util.Collection;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* This class consists exclusively of static methods that operate on or return collections.
@ -64,20 +60,4 @@ public final class CollectionUtils {
Collection<?> tmp = v;
return (C) tmp;
}
/**
* Converts the given collection to {@link Set}.
*
* @param <T> the type of elements in this output collection
* @param col the input collection. Null is permitted.
* @return the input collection if it is of type {@link Set} or a new
* {@link Set} instance created from the input collection
*/
public static <T> Set<T> toSet(Collection<T> col) {
if (col instanceof Set<T> set) {
return set;
} else {
return Optional.ofNullable(col).map(Collection::stream).orElseGet(Stream::of).collect(Collectors.toSet());
}
}
}

View File

@ -199,5 +199,5 @@ public final class TokenReplace {
private final String[] tokens;
private final transient List<Pattern> regexps;
private final static Object NULL_SUPPLIED = new Object();
private static final Object NULL_SUPPLIED = new Object();
}

View File

@ -39,11 +39,11 @@ import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.jpackage.internal.AppImageFile.LauncherInfo;
import jdk.jpackage.internal.model.Application;
import jdk.jpackage.internal.model.ApplicationLaunchers;
import jdk.jpackage.internal.model.ApplicationLayout;
import jdk.jpackage.internal.model.ConfigException;
import jdk.jpackage.internal.model.ExternalApplication.LauncherInfo;
import jdk.jpackage.internal.model.Launcher;
import jdk.jpackage.internal.model.LauncherStartupInfo;
import org.junit.jupiter.api.Assertions;