From 6549451c2eadd15fea7f2708a647123b1768f006 Mon Sep 17 00:00:00 2001 From: Lukasz Lenart Date: Sat, 19 Nov 2022 10:17:49 +0100 Subject: [PATCH 1/4] Upgrades to Launch4j 3.50 Closes #199 --- pom.xml | 9 ++- .../akathist/maven/plugins/launch4j/Jre.java | 79 +++++++++++++++---- .../maven/plugins/launch4j/Launch4jMojo.java | 9 ++- .../maven/plugins/launch4j/Messages.java | 6 +- 4 files changed, 81 insertions(+), 22 deletions(-) diff --git a/pom.xml b/pom.xml index dd7609e..575cd99 100644 --- a/pom.xml +++ b/pom.xml @@ -22,14 +22,14 @@ com.akathist.maven.plugins.launch4j launch4j-maven-plugin maven-plugin - 2.1.4-SNAPSHOT + 2.2.0-SNAPSHOT Maven Launch4j Plugin This plugin creates Windows executables from Java jar files using the Launch4j utility. http://9stmaryrd.com/tools/launch4j-maven-plugin/ - 3.14 + 3.50 1.8 1.8 @@ -68,21 +68,25 @@ org.apache.maven maven-plugin-api 3.8.6 + provided org.apache.maven maven-model 3.8.6 + provided org.apache.maven maven-artifact 3.8.6 + provided org.apache.maven maven-core 3.8.6 + provided org.apache.maven.plugin-tools @@ -99,6 +103,7 @@ junit junit 4.13.2 + test diff --git a/src/main/java/com/akathist/maven/plugins/launch4j/Jre.java b/src/main/java/com/akathist/maven/plugins/launch4j/Jre.java index 222e80d..07d927e 100644 --- a/src/main/java/com/akathist/maven/plugins/launch4j/Jre.java +++ b/src/main/java/com/akathist/maven/plugins/launch4j/Jre.java @@ -20,6 +20,7 @@ import java.util.List; +import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugins.annotations.Parameter; /** @@ -28,29 +29,44 @@ public class Jre { /** - * Use this property when you are bundling a jre with your application. It holds the path to the jre. - * If relative, this path is from the executable. - *

- * If you specify path only and not minVersion, then the executable will show an error if the jre is not found. - *

- * If you specify path along with minVersion, then the executable will check the path first, and if no jre - * is found there, it will search the local system for a jre matching minVersion. If it still doesn't - * find anything, it will show the java download page. You may also specify maxVersion to further - * constrain the search. + * The property is used to specify absolute or relative JRE paths, it does not rely + * on the current directory or . + * Note: the path is not checked until the actual application execution. + * The is now required and always used for searching before the registry, + * to ensure compatibility with the latest runtimes, which by default + * do not add registry keys during installation. */ + @Parameter(required = true) String path; /** * Sets jre's bundledJre64Bit flag + * + * @deprecated Replaced with which works during path and registry search. + * @since using Launch4j 3.50 */ @Parameter(defaultValue = "false") - boolean bundledJre64Bit; + @Deprecated + String bundledJre64Bit; /** * Sets jre's bundledJreAsFallback flag + * + * @deprecated Removed, path search is always first and registry search second + * in order to improve compatibility with modern runtimes + * @since using Launch4j 3.50 + */ + @Parameter(defaultValue = "false") + @Deprecated + String bundledJreAsFallback; + + /** + * When set to "true", limits the runtimes to 64-Bit only, "false" will use 64-Bit or 32-Bit + * depending on which is found. This option works with path and registry search. + * @since version 2.2.0 */ @Parameter(defaultValue = "false") - boolean bundledJreAsFallback; + boolean requires64Bit; /** * Use this property if you want the executable to search the system for a jre. @@ -93,10 +109,22 @@ public class Jre { * Always use a private JDK runtime (fails if there is no JDK installed) * * + * + * @deprecated Replaces with which works during path and registry search. + * @since using Launch4j 3.50 */ @Parameter(defaultValue = "preferJre") + @Deprecated String jdkPreference; + /** + * When set to "true" only a JDK will be used for execution. An additional check will be performed + * if javac is available during path and registry search. + * @since version 2.2.0 + */ + @Parameter(defaultValue = "false") + boolean requiresJdk; + /** * Sets java's initial heap size in MB, like the -Xms flag. */ @@ -133,25 +161,27 @@ public class Jre { * Sets JVM version to use: 32 bits, 64 bits or 64/32 bits * Possible values: 32, 64, 64/32 - it will fallback to default value if different option was used * Default value is: 64/32 + * + * @deprecated Replaced with which works during path and registry search. + * @since using Launch4j 3.50 */ @Parameter(defaultValue = "64/32") + @Deprecated String runtimeBits; net.sf.launch4j.config.Jre toL4j() { net.sf.launch4j.config.Jre ret = new net.sf.launch4j.config.Jre(); ret.setPath(path); - ret.setBundledJre64Bit(bundledJre64Bit); - ret.setBundledJreAsFallback(bundledJreAsFallback); + ret.setRequires64Bit(requires64Bit); ret.setMinVersion(minVersion); ret.setMaxVersion(maxVersion); - ret.setJdkPreference(jdkPreference); + ret.setRequiresJdk(requiresJdk); ret.setInitialHeapSize(initialHeapSize); ret.setInitialHeapPercent(initialHeapPercent); ret.setMaxHeapSize(maxHeapSize); ret.setMaxHeapPercent(maxHeapPercent); ret.setOptions(opts); - ret.setRuntimeBits(runtimeBits); return ret; } @@ -160,15 +190,30 @@ net.sf.launch4j.config.Jre toL4j() { public String toString() { return "Jre{" + "path='" + path + '\'' + + ", requires64Bit=" + requires64Bit + ", minVersion='" + minVersion + '\'' + ", maxVersion='" + maxVersion + '\'' + - ", jdkPreference='" + jdkPreference + '\'' + + ", requiresJdk=" + requiresJdk + ", initialHeapSize=" + initialHeapSize + ", initialHeapPercent=" + initialHeapPercent + ", maxHeapSize=" + maxHeapSize + ", maxHeapPercent=" + maxHeapPercent + ", opts=" + opts + - ", runtimeBits='" + runtimeBits + '\'' + '}'; } + + public void deprecationWarning(Log log) { + if (this.bundledJreAsFallback != null) { + log.warn(" has been removed! It has not effect!"); + } + if (this.bundledJre64Bit != null) { + log.warn(" is deprecated, use instead!"); + } + if (this.runtimeBits != null) { + log.warn(" is deprecated, use instead!"); + } + if (this.jdkPreference != null) { + log.warn(" is deprecated, use instead!"); + } + } } diff --git a/src/main/java/com/akathist/maven/plugins/launch4j/Launch4jMojo.java b/src/main/java/com/akathist/maven/plugins/launch4j/Launch4jMojo.java index e175243..57960f8 100644 --- a/src/main/java/com/akathist/maven/plugins/launch4j/Launch4jMojo.java +++ b/src/main/java/com/akathist/maven/plugins/launch4j/Launch4jMojo.java @@ -423,6 +423,7 @@ private void doExecute() throws MojoExecutionException { c.setClassPath(classPath.toL4j(dependencies)); } if (jre != null) { + jre.deprecationWarning(getLog()); c.setJre(jre.toL4j()); } if (singleInstance != null) { @@ -435,6 +436,9 @@ private void doExecute() throws MojoExecutionException { c.setVersionInfo(versionInfo.toL4j()); } if (messages != null) { + if (messages.bundledJreErr != null) { + getLog().warn(" is deprecated, use instead!"); + } c.setMessages(messages.toL4j()); } ConfigPersister.getInstance().setAntConfig(c, getBaseDir()); @@ -708,7 +712,8 @@ private void printState() { log.debug("jre.path = " + c.getJre().getPath()); log.debug("jre.minVersion = " + c.getJre().getMinVersion()); log.debug("jre.maxVersion = " + c.getJre().getMaxVersion()); - log.debug("jre.jdkPreference = " + c.getJre().getJdkPreference()); + log.debug("jre.requiresJdk = " + c.getJre().getRequiresJdk()); + log.debug("jre.requires64Bit = " + c.getJre().getRequires64Bit()); log.debug("jre.initialHeapSize = " + c.getJre().getInitialHeapSize()); log.debug("jre.initialHeapPercent = " + c.getJre().getInitialHeapPercent()); log.debug("jre.maxHeapSize = " + c.getJre().getMaxHeapSize()); @@ -755,7 +760,7 @@ private void printState() { } if (c.getMessages() != null) { log.debug("messages.startupErr = " + c.getMessages().getStartupErr()); - log.debug("messages.bundledJreErr = " + c.getMessages().getBundledJreErr()); + log.debug("messages.jreNotFoundErr = " + c.getMessages().getJreNotFoundErr()); log.debug("messages.jreVersionErr = " + c.getMessages().getJreVersionErr()); log.debug("messages.launcherErr = " + c.getMessages().getLauncherErr()); log.debug("messages.instanceAlreadyExistsMsg = " + c.getMessages().getInstanceAlreadyExistsMsg()); diff --git a/src/main/java/com/akathist/maven/plugins/launch4j/Messages.java b/src/main/java/com/akathist/maven/plugins/launch4j/Messages.java index 99aecc7..2dd4f5d 100644 --- a/src/main/java/com/akathist/maven/plugins/launch4j/Messages.java +++ b/src/main/java/com/akathist/maven/plugins/launch4j/Messages.java @@ -28,6 +28,7 @@ public class Messages { String startupErr; + @Deprecated String bundledJreErr; String jreVersionErr; @@ -36,16 +37,19 @@ public class Messages { String instanceAlreadyExistsMsg; + String jreNotFoundErr; + Msg toL4j() { Msg ret = new Msg(); ret.setStartupErr(startupErr); - ret.setBundledJreErr(bundledJreErr); ret.setJreVersionErr(jreVersionErr); ret.setLauncherErr(launcherErr); ret.setInstanceAlreadyExistsMsg(instanceAlreadyExistsMsg); + /* since Launch4j 3.50 */ + ret.setJreNotFoundErr(jreNotFoundErr); return ret; } From 6a93654960cb2baab2550dc57a7c42f7a9932b71 Mon Sep 17 00:00:00 2001 From: Lukasz Lenart Date: Sat, 19 Nov 2022 18:33:44 +0100 Subject: [PATCH 2/4] Adds a basic unit test --- pom.xml | 30 +++++++ .../maven/plugins/launch4j/Launch4jMojo.java | 35 +++++++- .../maven/plugins/launch4j/Messages.java | 19 ++++- .../plugins/launch4j/SingleInstance.java | 3 + .../maven/plugins/launch4j/Splash.java | 10 +++ .../maven/plugins/launch4j/VersionInfo.java | 15 +++- .../plugins/launch4j/Launch4jMojoTest.java | 84 +++++++++++++++++++ .../launch4j-default-plugin-config.xml | 60 +++++++++++++ 8 files changed, 252 insertions(+), 4 deletions(-) create mode 100644 src/test/java/com/akathist/maven/plugins/launch4j/Launch4jMojoTest.java create mode 100644 src/test/resources/unit/launch4j-default/launch4j-default-plugin-config.xml diff --git a/pom.xml b/pom.xml index 575cd99..ffe7283 100644 --- a/pom.xml +++ b/pom.xml @@ -62,8 +62,26 @@ abeille net.java.abeille + + com.thoughtworks.xstream + xstream + + + org.apache.ant + ant + + + org.apache.ant + ant + 1.10.12 + + + com.thoughtworks.xstream + xstream + 1.4.19 + org.apache.maven maven-plugin-api @@ -105,6 +123,18 @@ 4.13.2 test + + org.apache.maven.plugin-testing + maven-plugin-testing-harness + 3.3.0 + test + + + org.apache.maven + maven-compat + 3.8.2 + test + diff --git a/src/main/java/com/akathist/maven/plugins/launch4j/Launch4jMojo.java b/src/main/java/com/akathist/maven/plugins/launch4j/Launch4jMojo.java index 57960f8..f84add3 100644 --- a/src/main/java/com/akathist/maven/plugins/launch4j/Launch4jMojo.java +++ b/src/main/java/com/akathist/maven/plugins/launch4j/Launch4jMojo.java @@ -262,7 +262,7 @@ public class Launch4jMojo extends AbstractMojo { * Details about the classpath your application should have. * This is required if you are not wrapping a jar. */ - @Parameter + @Parameter() private ClassPath classPath; /** @@ -809,4 +809,37 @@ private boolean skipExecution() { return skip || System.getProperty("skipLaunch4j") != null; } + @Override + public String toString() { + return "Launch4jMojo{" + + "headerType='" + headerType + '\'' + + ", infile=" + infile + + ", outfile=" + outfile + + ", jar='" + jar + '\'' + + ", dontWrapJar=" + dontWrapJar + + ", errTitle='" + errTitle + '\'' + + ", downloadUrl='" + downloadUrl + '\'' + + ", supportUrl='" + supportUrl + '\'' + + ", cmdLine='" + cmdLine + '\'' + + ", chdir='" + chdir + '\'' + + ", priority='" + priority + '\'' + + ", stayAlive=" + stayAlive + + ", restartOnCrash=" + restartOnCrash + + ", icon=" + icon + + ", objs=" + objs + + ", libs=" + libs + + ", vars=" + vars + + ", jre=" + jre + + ", classPath=" + classPath + + ", singleInstance=" + singleInstance + + ", splash=" + splash + + ", versionInfo=" + versionInfo + + ", messages=" + messages + + ", manifest=" + manifest + + ", saveConfig=" + saveConfig + + ", configOutfile=" + configOutfile + + ", parallelExecution=" + parallelExecution + + ", skip=" + skip + + '}'; + } } diff --git a/src/main/java/com/akathist/maven/plugins/launch4j/Messages.java b/src/main/java/com/akathist/maven/plugins/launch4j/Messages.java index 2dd4f5d..5d6f38a 100644 --- a/src/main/java/com/akathist/maven/plugins/launch4j/Messages.java +++ b/src/main/java/com/akathist/maven/plugins/launch4j/Messages.java @@ -19,27 +19,32 @@ package com.akathist.maven.plugins.launch4j; import net.sf.launch4j.config.Msg; - +import org.apache.maven.plugins.annotations.Parameter; /** * Details about messages you can pass. */ public class Messages { + @Parameter String startupErr; + @Parameter @Deprecated String bundledJreErr; + @Parameter String jreVersionErr; + @Parameter String launcherErr; + @Parameter String instanceAlreadyExistsMsg; + @Parameter String jreNotFoundErr; - Msg toL4j() { Msg ret = new Msg(); @@ -53,4 +58,14 @@ Msg toL4j() { return ret; } + @Override + public String toString() { + return "Messages{" + + "startupErr='" + startupErr + '\'' + + ", jreVersionErr='" + jreVersionErr + '\'' + + ", launcherErr='" + launcherErr + '\'' + + ", instanceAlreadyExistsMsg='" + instanceAlreadyExistsMsg + '\'' + + ", jreNotFoundErr='" + jreNotFoundErr + '\'' + + '}'; + } } diff --git a/src/main/java/com/akathist/maven/plugins/launch4j/SingleInstance.java b/src/main/java/com/akathist/maven/plugins/launch4j/SingleInstance.java index a52cc40..f0cf2ee 100644 --- a/src/main/java/com/akathist/maven/plugins/launch4j/SingleInstance.java +++ b/src/main/java/com/akathist/maven/plugins/launch4j/SingleInstance.java @@ -18,14 +18,17 @@ */ package com.akathist.maven.plugins.launch4j; +import org.apache.maven.plugins.annotations.Parameter; /** * Details about running your application as a single instance. */ public class SingleInstance { + @Parameter String mutexName; + @Parameter String windowTitle; net.sf.launch4j.config.SingleInstance toL4j() { diff --git a/src/main/java/com/akathist/maven/plugins/launch4j/Splash.java b/src/main/java/com/akathist/maven/plugins/launch4j/Splash.java index a25c567..ea0aae3 100644 --- a/src/main/java/com/akathist/maven/plugins/launch4j/Splash.java +++ b/src/main/java/com/akathist/maven/plugins/launch4j/Splash.java @@ -27,6 +27,7 @@ public class Splash { /** * The path (relative to the executable when distributed) to the splash page image. */ + @Parameter File file; /** @@ -61,4 +62,13 @@ net.sf.launch4j.config.Splash toL4j() { return ret; } + @Override + public String toString() { + return "Splash{" + + "file=" + file + + ", waitForWindow=" + waitForWindow + + ", timeout=" + timeout + + ", timeoutErr=" + timeoutErr + + '}'; + } } diff --git a/src/main/java/com/akathist/maven/plugins/launch4j/VersionInfo.java b/src/main/java/com/akathist/maven/plugins/launch4j/VersionInfo.java index 80e6596..88e8116 100644 --- a/src/main/java/com/akathist/maven/plugins/launch4j/VersionInfo.java +++ b/src/main/java/com/akathist/maven/plugins/launch4j/VersionInfo.java @@ -19,6 +19,7 @@ package com.akathist.maven.plugins.launch4j; import net.sf.launch4j.config.LanguageID; +import org.apache.maven.plugins.annotations.Parameter; import java.util.HashMap; import java.util.Map; @@ -28,7 +29,7 @@ */ public class VersionInfo { - private static Map LANGUAGE_TO_LANGUAGE_ID; + private static final Map LANGUAGE_TO_LANGUAGE_ID; static { LANGUAGE_TO_LANGUAGE_ID = new HashMap<>(); @@ -40,61 +41,73 @@ public class VersionInfo { /** * Version number in x.x.x.x format. */ + @Parameter String fileVersion; /** * Free-form version number, like "1.20.RC1." */ + @Parameter String txtFileVersion; /** * File description shown to the user. */ + @Parameter String fileDescription; /** * Legal copyright. */ + @Parameter String copyright; /** * Version number in x.x.x.x format. */ + @Parameter String productVersion; /** * Free-form version number, like "1.20.RC1." */ + @Parameter String txtProductVersion; /** * The product name. */ + @Parameter String productName; /** * The company name. */ + @Parameter String companyName; /** * The internal name. For instance, you could use the filename without extension or the module name. */ + @Parameter String internalName; /** * The original filename without path. Setting this lets you determine whether a user has renamed the file. */ + @Parameter String originalFilename; /** * Language to be used during installation, default ENGLISH_US */ + @Parameter String language = LanguageID.ENGLISH_US.name(); /** * Trademarks of author */ + @Parameter String trademarks; net.sf.launch4j.config.VersionInfo toL4j() { diff --git a/src/test/java/com/akathist/maven/plugins/launch4j/Launch4jMojoTest.java b/src/test/java/com/akathist/maven/plugins/launch4j/Launch4jMojoTest.java new file mode 100644 index 0000000..0e9bee2 --- /dev/null +++ b/src/test/java/com/akathist/maven/plugins/launch4j/Launch4jMojoTest.java @@ -0,0 +1,84 @@ +package com.akathist.maven.plugins.launch4j; + +import org.apache.maven.plugin.testing.AbstractMojoTestCase; + +import java.io.File; + +public class Launch4jMojoTest extends AbstractMojoTestCase { + + public void testMojoGoal() throws Exception { + File testPom = new File(getBasedir(), "src/test/resources/unit/launch4j-default/launch4j-default-plugin-config.xml"); + + Launch4jMojo mojo = (Launch4jMojo) lookupMojo("launch4j", testPom); + + assertNotNull(mojo); + + assertEquals("Launch4jMojo{" + + "headerType='gui', " + + "infile=null, " + + "outfile=${project.build.directory}/app.exe, " + + "jar='${project.build.directory}/${project.artifactId}-${project.version}.jar', " + + "dontWrapJar=false, " + + "errTitle='null', " + + "downloadUrl='https://java.com/download', " + + "supportUrl='null', " + + "cmdLine='null', " + + "chdir='null', " + + "priority='null', " + + "stayAlive=false, " + + "restartOnCrash=false, " + + "icon=null, " + + "objs=null, " + + "libs=null, " + + "vars=null, " + + "jre=Jre{" + + "path='%JAVA_HOME%;%PATH%', " + + "requires64Bit=false, " + + "minVersion='1.8', " + + "maxVersion='null', " + + "requiresJdk=true," + + " initialHeapSize=0, " + + "initialHeapPercent=0, " + + "maxHeapSize=0, " + + "maxHeapPercent=0, " + + "opts=[-Dname=Lukasz]" + + "}, " + + "classPath=ClassPath{" + + "mainClass='pl.org.lenart.launch4j.App', " + + "addDependencies=true, " + + "jarLocation='null', " + + "preCp='anything', " + + "postCp='null'" + + "}, " + + "singleInstance=null, " + + "splash=null, " + + "versionInfo=VersionInfo{" + + "fileVersion='1.0.0.0', " + + "txtFileVersion='${project.version}', " + + "fileDescription='Launch4j Demo App', " + + "copyright='Lukasz Lenart', " + + "productVersion='1.0.0.0', " + + "txtProductVersion='1.0.0.0', " + + "productName='App', " + + "companyName='Lukasz Lenart', " + + "internalName='app', " + + "originalFilename='app.exe', " + + "language='ENGLISH_US', " + + "trademarks='Luk ™'" + + "}, " + + "messages=Messages{" + + "startupErr='null', " + + "jreVersionErr='null', " + + "launcherErr='null', " + + "instanceAlreadyExistsMsg='null', " + + "jreNotFoundErr='null'" + + "}, " + + "manifest=null, " + + "saveConfig=false, " + + "configOutfile=null, " + + "parallelExecution=false, " + + "skip=false" + + "}", mojo.toString()); + } + +} diff --git a/src/test/resources/unit/launch4j-default/launch4j-default-plugin-config.xml b/src/test/resources/unit/launch4j-default/launch4j-default-plugin-config.xml new file mode 100644 index 0000000..7f38dba --- /dev/null +++ b/src/test/resources/unit/launch4j-default/launch4j-default-plugin-config.xml @@ -0,0 +1,60 @@ + + 4.0.0 + + com.akathist.maven.plugins.launch4j.unit + launch4j-default + 1.0-SNAPSHOT + jar + + launch4j-default + + + + + com.akathist.maven.plugins.launch4j + launch4j-maven-plugin + + gui + ${project.build.directory}/${project.artifactId}-${project.version}.jar + ${project.build.directory}/app.exe + https://java.com/download + + pl.org.lenart.launch4j.App + anything + + + %JAVA_HOME%;%PATH% + 1.8 + true + preferJre + true + true + 32 + + -Dname=Lukasz + + + + Test bundledJreErr + + + 1.0.0.0 + ${project.version} + Launch4j Demo App + Lukasz Lenart + 1.0.0.0 + 1.0.0.0 + App + Lukasz Lenart + app + app.exe + Luk ™ + + + + + + + + From b6cb33d6bce37f513bf0eac6b92946f5dfe75757 Mon Sep 17 00:00:00 2001 From: Lukasz Lenart Date: Sat, 19 Nov 2022 18:42:31 +0100 Subject: [PATCH 3/4] Fixes typo --- src/main/java/com/akathist/maven/plugins/launch4j/Jre.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/akathist/maven/plugins/launch4j/Jre.java b/src/main/java/com/akathist/maven/plugins/launch4j/Jre.java index 07d927e..2e9d0ea 100644 --- a/src/main/java/com/akathist/maven/plugins/launch4j/Jre.java +++ b/src/main/java/com/akathist/maven/plugins/launch4j/Jre.java @@ -204,7 +204,7 @@ public String toString() { public void deprecationWarning(Log log) { if (this.bundledJreAsFallback != null) { - log.warn(" has been removed! It has not effect!"); + log.warn(" has been removed! It has no effect!"); } if (this.bundledJre64Bit != null) { log.warn(" is deprecated, use instead!"); From 775b73ae639eb872e93113e7b0be2d5917bb60da Mon Sep 17 00:00:00 2001 From: Lukasz Lenart Date: Mon, 21 Nov 2022 08:59:32 +0100 Subject: [PATCH 4/4] Fixes URLs and licence --- pom.xml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index ffe7283..b005e76 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ Maven Launch4j Plugin This plugin creates Windows executables from Java jar files using the Launch4j utility. - http://9stmaryrd.com/tools/launch4j-maven-plugin/ + https://orphan.software/ 3.50 @@ -36,14 +36,16 @@ - GNU General Public License - http://www.gnu.org/licenses/gpl.txt + Apache 2.0 License + https://www.apache.org/licenses/LICENSE-2.0 repo - scm:git:git@github.com:lukaszlenart/launch4j-maven-plugin.git + scm:git:git@github.com:orphan-oss/launch4j-maven-plugin.git + git@github.com:orphan-oss/launch4j-maven-plugin.git + scm:git:git@github.com:orphan-oss/launch4j-maven-plugin.git HEAD