net.dongliu.jlink.JPackageMojo Maven / Gradle / Ivy
package net.dongliu.jlink;
import net.dongliu.commons.Joiner;
import net.dongliu.commons.collection.Collections2;
import net.dongliu.jlink.model.JPackageLauncher;
import net.dongliu.jlink.model.LinuxPackageSetting;
import net.dongliu.jlink.model.MacPackageSetting;
import net.dongliu.jlink.model.WindowsPackageSetting;
import net.dongliu.jlink.util.ModuleInfo;
import net.dongliu.jlink.util.ProcessResult;
import net.dongliu.jlink.util.ProcessUtils;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.*;
import org.apache.maven.project.MavenProject;
import org.apache.maven.toolchain.Toolchain;
import org.apache.maven.toolchain.ToolchainManager;
import org.codehaus.plexus.util.Os;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
/**
* JPackage mojo, require jdk 14+, Only support modular apps
*
* @author dongliu
*/
@Mojo(name = "package", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME)
public class JPackageMojo extends AbstractMojo {
@Parameter(defaultValue = "${project}", readonly = true)
private MavenProject project;
@Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}.${project.packaging}")
private File projectArtifact;
@Parameter
private List jvmOptions;
@Component
private ToolchainManager toolchainManager;
@Parameter(defaultValue = "${session}", readonly = true)
private MavenSession mavenSession;
@Parameter(defaultValue = "${project.name}")
private String name;
@Parameter(required = true)
private String type;
@Parameter(defaultValue = "${project.version}")
private String appVersion;
@Parameter(defaultValue = "${project.description}")
private String description;
@Parameter
private String copyright;
@Parameter
private String licenseFile;
@Parameter(defaultValue = "${project.build.directory}")
private String destination;
@Parameter(defaultValue = "${project.groupId}")
private String vendor;
@Parameter
private boolean verbose;
@Parameter
private boolean bindServices;
@Parameter
private List addModules;
@Parameter
private List modulePaths;
@Parameter
private String runtimeImage;
@Parameter
private String icon;
@Parameter
private List launchers;
@Parameter
private List fileAssociations;
@Parameter
private List arguments;
@Parameter
private List javaOptions;
@Parameter
private String module;
// mac parameters
@Parameter(name = "mac")
private MacPackageSetting macPackageSetting;
// linux parameters
@Parameter(name = "linux")
private LinuxPackageSetting linuxPackageSetting;
@Parameter(name = "win")
private WindowsPackageSetting windowsPackageSetting;
@Override
public void execute() throws MojoExecutionException {
String packaging = project.getModel().getPackaging();
if (!packaging.equalsIgnoreCase("jar")) {
getLog().error("require packaging type to be jar or jmod, '" + packaging + " not supported'");
return;
}
DescribeModule describeModule = new DescribeModule(getTools("jar"), getTools("jmod"), projectArtifact.toPath());
if (module == null) {
ModuleInfo projectModuleInfo = describeModule.describe();
if (projectModuleInfo != null && projectModuleInfo.mainClass() != null) {
module = projectModuleInfo.name() + "/" + projectModuleInfo.mainClass();
getLog().info("using main module: " + module);
}
}
if (module == null) {
throw new RuntimeException("main module required");
}
if (icon == null) {
Path path = project.getBasedir().toPath();
Path fileName;
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
fileName = Paths.get("windows", "icon.ico");
} else if (Os.isFamily(Os.FAMILY_MAC)) {
fileName = Paths.get("osx", "icon.icns");
} else if (Os.isFamily(Os.FAMILY_UNIX)) {
fileName = Paths.get("linux", "icon.png");
} else {
throw new RuntimeException("unsupported os");
}
Path iconPath = path.resolve("src").resolve("main").resolve("deploy").resolve(fileName);
if (Files.exists(iconPath)) {
icon = iconPath.toString();
getLog().info("using icon: " + icon);
}
}
getLog().info("creating jpackage image at " + destination + File.separator + name);
runJPackage();
}
private Path getTools(String toolName) {
Toolchain toolchain = toolchainManager.getToolchainFromBuildContext("jdk", mavenSession);
Path toolPath;
if (toolchain != null) {
String toolPathStr = toolchain.findTool(toolName);
if (toolPathStr != null) {
toolPath = Paths.get(toolPathStr);
} else {
throw new RuntimeException("tools not found in tool chain: " + toolchain);
}
} else {
String javaHome = System.getProperty("java.home");
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
toolName = toolName + ".exe";
}
toolPath = Paths.get(javaHome, "bin", toolName);
}
return toolPath;
}
private void runJPackage() throws AssertionError {
List command = new ArrayList<>();
command.add(getTools("jpackage").toString());
command.add("--name");
command.add(name);
command.add("--type");
command.add(type);
command.add("--app-version");
command.add(appVersion);
command.add("--dest");
command.add(destination);
command.add("--vendor");
command.add(vendor);
if (description != null) {
command.add("--description");
command.add(description);
}
if (copyright != null) {
command.add("--copyright");
command.add(copyright);
}
if (licenseFile != null) {
command.add("-license-file");
command.add(licenseFile);
}
if (icon != null) {
command.add("--icon");
command.add(icon);
}
if (verbose) {
command.add("--verbose");
}
command.add("--module");
command.add(module);
if (bindServices) {
command.add("--bind-services");
}
if (addModules != null && !addModules.isEmpty()) {
command.add(" --add-modules");
command.add(String.join(",", addModules));
}
if (modulePaths != null && !modulePaths.isEmpty()) {
command.add("--module-path");
command.add(String.join(":", modulePaths));
}
if (runtimeImage != null) {
command.add("--runtime-image");
command.add(runtimeImage);
}
if (arguments != null && !arguments.isEmpty()) {
for (String argument : arguments) {
command.add("--arguments");
command.add(argument);
}
}
if (javaOptions != null && !javaOptions.isEmpty()) {
for (String javaOption : javaOptions) {
command.add("--arguments");
command.add(javaOption);
}
}
if (fileAssociations != null && !fileAssociations.isEmpty()) {
for (File fileAssociation : fileAssociations) {
command.add("--file-associations");
command.add(fileAssociation.toString());
}
}
if (launchers != null && !launchers.isEmpty()) {
for (JPackageLauncher launcher : launchers) {
command.add("--add-launcher");
command.add(String.format("%s=%s", launcher.getName(), launcher.getFile()));
}
}
if (Os.isFamily(Os.FAMILY_MAC) && macPackageSetting != null) {
addMacParameters(command);
}
if (Os.isFamily(Os.FAMILY_UNIX) && linuxPackageSetting != null) {
addLinuxParameters(command);
}
if (Os.isFamily(Os.FAMILY_WINDOWS) && windowsPackageSetting != null) {
addWindowsParameters(command);
}
getLog().debug("run jpackage: " + Joiner.of(" ").join(command));
ProcessResult result = ProcessUtils.execute(Collections2.toArray(command, String[]::new));
if (result.exitCode() != 0) {
String message = result.stderr().isEmpty() ? result.stdout() : result.stderr();
getLog().error("jpackage error: " + message);
}
}
private void addWindowsParameters(List command) {
if (windowsPackageSetting.isConsole()) {
command.add("--win-console");
}
if (windowsPackageSetting.isDirChooser()) {
command.add("--win-dir-chooser");
}
if (windowsPackageSetting.isMenu()) {
command.add("--win-menu");
}
if (windowsPackageSetting.getMenuGroup() != null) {
command.add("--win-menu-group");
command.add(windowsPackageSetting.getMenuGroup());
}
if (windowsPackageSetting.isPerUserInstall()) {
command.add("--win-per-user-install");
}
if (windowsPackageSetting.isShortcut()) {
command.add("--win-shortcut");
}
if (windowsPackageSetting.getUpgradeUuid() != null) {
command.add("--win-upgrade-uuid");
command.add(windowsPackageSetting.getUpgradeUuid());
}
if (windowsPackageSetting.getInstallDir() != null) {
command.add("--install-dir");
command.add(windowsPackageSetting.getInstallDir());
}
}
private void addLinuxParameters(List command) {
if (linuxPackageSetting.getPackageName() != null) {
command.add("--linux-package-name");
command.add(linuxPackageSetting.getPackageName());
}
if (linuxPackageSetting.getDebMaintainer() != null) {
command.add("--linux-deb-maintainer");
command.add(linuxPackageSetting.getDebMaintainer());
}
if (linuxPackageSetting.getMenuGroup() != null) {
command.add("--linux-menu-group");
command.add(linuxPackageSetting.getMenuGroup());
}
if (linuxPackageSetting.getPackageDeps() != null) {
command.add("--linux-package-deps");
command.add(linuxPackageSetting.getPackageDeps());
}
if (linuxPackageSetting.getRpmLicenseType() != null) {
command.add("--linux-rpm-license-type");
command.add(linuxPackageSetting.getRpmLicenseType());
}
if (linuxPackageSetting.getAppRelease() != null) {
command.add("--linux-app-release");
command.add(linuxPackageSetting.getAppRelease());
}
if (linuxPackageSetting.getAppCategory() != null) {
command.add("--linux-app-category");
command.add(linuxPackageSetting.getAppCategory());
}
if (linuxPackageSetting.isShortcut()) {
command.add("--linux-shortcut");
}
if (linuxPackageSetting.getInstallDir() != null) {
command.add("--install-dir");
command.add(linuxPackageSetting.getInstallDir());
}
}
private void addMacParameters(List command) {
if (macPackageSetting.getPackageIdentifier() != null) {
command.add("--mac-package-identifier");
command.add(macPackageSetting.getPackageIdentifier());
}
if (macPackageSetting.getPackageName() != null) {
command.add("--mac-package-name");
command.add(macPackageSetting.getPackageName());
}
if (macPackageSetting.getPackageSigningPrefix() != null) {
command.add("--mac-package-signing-prefix");
command.add(macPackageSetting.getPackageSigningPrefix());
}
if (macPackageSetting.isSign()) {
command.add("--mac-sign");
}
if (macPackageSetting.getSigningKeychain() != null) {
command.add("--mac-signing-keychain");
command.add(macPackageSetting.getSigningKeychain());
}
if (macPackageSetting.getSigningKeyUserName() != null) {
command.add("--mac-signing-key-user-name");
command.add(macPackageSetting.getSigningKeyUserName());
}
if (macPackageSetting.getInstallDir() != null) {
command.add("--install-dir");
command.add(macPackageSetting.getInstallDir());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy