diff --git a/src/main/java/com/akathist/maven/plugins/launch4j/ClassPath.java b/src/main/java/com/akathist/maven/plugins/launch4j/ClassPath.java index 0ec2e34..bf5a6f4 100644 --- a/src/main/java/com/akathist/maven/plugins/launch4j/ClassPath.java +++ b/src/main/java/com/akathist/maven/plugins/launch4j/ClassPath.java @@ -28,62 +28,62 @@ public class ClassPath { - /** - * The main class to run. This is not required if you are wrapping an executable jar. - */ - @Parameter - String mainClass; - - /** - * The launch4j executable sets up a classpath before running your jar, but it must know what the - * classpath should be. If you set this property to true, the plugin will indicate a classpath - * based on all the dependencies your program will need at runtime. You can augment this classpath - * using the preCp and postCp properties. - */ - @Parameter(defaultValue="true") - boolean addDependencies = true; - - /** - * If you want maven to build the classpath from dependencies, you can optionally set the jarLocation, - * which is the location of the jars in your distro relative to the executable. So if your distro - * has the exe at the top level and all the jars in a lib directory, you could set this to "lib." - * This property does not affect preCp and postCp. - */ - @Parameter - String jarLocation; - - /** - * Part of the classpath that the executable should give to your application. - * Paths are relative to the executable and should be in Windows format (separated by a semicolon). - * You don't have to list all your dependencies here; the plugin will include them by default - * after this list. - */ - @Parameter - String preCp; - - /** - * Part of the classpath that the executable should give to your application. - * Paths are relative to the executable and should be in Windows format (separated by a semicolon). - * You don't have to list all your dependencies here; the plugin will include them by default - * before this list. - */ - @Parameter - String postCp; - - private void addToCp(List cp, String cpStr) { - cp.addAll(Arrays.asList(cpStr.split("\\s*;\\s*"))); - } - - net.sf.launch4j.config.ClassPath toL4j(Set dependencies, List runtimeDependencies) { - net.sf.launch4j.config.ClassPath ret = new net.sf.launch4j.config.ClassPath(); - ret.setMainClass(mainClass); - - List cp = new ArrayList(); - if (preCp != null) addToCp(cp, preCp); - - if (addDependencies) { - if (jarLocation == null) jarLocation = ""; - else if ( ! jarLocation.endsWith("/")) jarLocation += "/"; + /** + * The main class to run. This is not required if you are wrapping an executable jar. + */ + @Parameter + String mainClass; + + /** + * The launch4j executable sets up a classpath before running your jar, but it must know what the + * classpath should be. If you set this property to true, the plugin will indicate a classpath + * based on all the dependencies your program will need at runtime. You can augment this classpath + * using the preCp and postCp properties. + */ + @Parameter(defaultValue = "true") + boolean addDependencies = true; + + /** + * If you want maven to build the classpath from dependencies, you can optionally set the jarLocation, + * which is the location of the jars in your distro relative to the executable. So if your distro + * has the exe at the top level and all the jars in a lib directory, you could set this to "lib." + * This property does not affect preCp and postCp. + */ + @Parameter + String jarLocation; + + /** + * Part of the classpath that the executable should give to your application. + * Paths are relative to the executable and should be in Windows format (separated by a semicolon). + * You don't have to list all your dependencies here; the plugin will include them by default + * after this list. + */ + @Parameter + String preCp; + + /** + * Part of the classpath that the executable should give to your application. + * Paths are relative to the executable and should be in Windows format (separated by a semicolon). + * You don't have to list all your dependencies here; the plugin will include them by default + * before this list. + */ + @Parameter + String postCp; + + private void addToCp(List cp, String cpStr) { + cp.addAll(Arrays.asList(cpStr.split("\\s*;\\s*"))); + } + + net.sf.launch4j.config.ClassPath toL4j(Set dependencies, List runtimeDependencies) { + net.sf.launch4j.config.ClassPath ret = new net.sf.launch4j.config.ClassPath(); + ret.setMainClass(mainClass); + + List cp = new ArrayList(); + if (preCp != null) addToCp(cp, preCp); + + if (addDependencies) { + if (jarLocation == null) jarLocation = ""; + else if (!jarLocation.endsWith("/")) jarLocation += "/"; // Add all runtime dependencies as we need them to run the wrapped jar dependencies.addAll(runtimeDependencies); @@ -98,13 +98,13 @@ net.sf.launch4j.config.ClassPath toL4j(Set dependencies, List - * 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. - */ - String path; - - /** - * Use this property if you want the executable to search the system for a jre. - * It names the minimum version acceptable, in x.x.x[_xx] format. - *

- * If you specify this property without giving a path, then the executable will search for a jre - * and, none is found, display the java download page. - *

- * If you include a path also, the executable will try that path before searching for jre matching minVersion. - *

- * In either case, you can also specify a maxVersion. - */ - String minVersion; - - /** - * If you specify minVersion, you can also use maxVersion to further constrain the search for a jre. - * This property should be in the format x.x.x[_xx]. - */ - String maxVersion; - - /** - * Allows you to specify a preference for a public JRE or a private JDK runtime. - *

- * Valid values are: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
jreOnlyAlways use a public JRE
preferJrePrefer a public JRE, but use a JDK private runtime if it is newer than the public JRE
preferJdkPrefer a JDK private runtime, but use a public JRE if it is newer than the JDK
jdkOnlyAlways use a private JDK runtime (fails if there is no JDK installed)
- */ - @Parameter(defaultValue="preferJre") - String jdkPreference; - - /** - * Sets java's initial heap size in MB, like the -Xms flag. - */ - int initialHeapSize; - - /** - * Sets java's initial heap size in percent of free memory. - */ - int initialHeapPercent; - - /** - * Sets java's maximum heap size in MB, like the -Xmx flag. - */ - int maxHeapSize; - - /** - * Sets java's maximum heap size in percent of free memory. - */ - int maxHeapPercent; - - /** - * Use this to pass arbitrary options to the java/javaw program. - * For instance, you can say: - *

-	 * <opt>-Dlaunch4j.exedir="%EXEDIR%"</opt>
-	 * <opt>-Dlaunch4j.exefile="%EXEFILE%"</opt>
-	 * <opt>-Denv.path="%Path%"</opt>
-	 * <opt>-Dsettings="%HomeDrive%%HomePath%\\settings.ini"</opt>
-	 * 
- */ - List opts; + /** + * 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. + */ + String path; + + /** + * Use this property if you want the executable to search the system for a jre. + * It names the minimum version acceptable, in x.x.x[_xx] format. + *

+ * If you specify this property without giving a path, then the executable will search for a jre + * and, none is found, display the java download page. + *

+ * If you include a path also, the executable will try that path before searching for jre matching minVersion. + *

+ * In either case, you can also specify a maxVersion. + */ + String minVersion; + + /** + * If you specify minVersion, you can also use maxVersion to further constrain the search for a jre. + * This property should be in the format x.x.x[_xx]. + */ + String maxVersion; + + /** + * Allows you to specify a preference for a public JRE or a private JDK runtime. + *

+ * Valid values are: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
jreOnlyAlways use a public JRE
preferJrePrefer a public JRE, but use a JDK private runtime if it is newer than the public JRE
preferJdkPrefer a JDK private runtime, but use a public JRE if it is newer than the JDK
jdkOnlyAlways use a private JDK runtime (fails if there is no JDK installed)
+ */ + @Parameter(defaultValue = "preferJre") + String jdkPreference; + + /** + * Sets java's initial heap size in MB, like the -Xms flag. + */ + int initialHeapSize; + + /** + * Sets java's initial heap size in percent of free memory. + */ + int initialHeapPercent; + + /** + * Sets java's maximum heap size in MB, like the -Xmx flag. + */ + int maxHeapSize; + + /** + * Sets java's maximum heap size in percent of free memory. + */ + int maxHeapPercent; + + /** + * Use this to pass arbitrary options to the java/javaw program. + * For instance, you can say: + *

+     * <opt>-Dlaunch4j.exedir="%EXEDIR%"</opt>
+     * <opt>-Dlaunch4j.exefile="%EXEFILE%"</opt>
+     * <opt>-Denv.path="%Path%"</opt>
+     * <opt>-Dsettings="%HomeDrive%%HomePath%\\settings.ini"</opt>
+     * 
+ */ + List opts; /** * 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 */ - @Parameter(defaultValue="64/32") + @Parameter(defaultValue = "64/32") String runtimeBits; - net.sf.launch4j.config.Jre toL4j() { - net.sf.launch4j.config.Jre ret = new net.sf.launch4j.config.Jre(); - - ret.setPath(path); - ret.setMinVersion(minVersion); - ret.setMaxVersion(maxVersion); - ret.setJdkPreference(jdkPreference); - ret.setInitialHeapSize(initialHeapSize); - ret.setInitialHeapPercent(initialHeapPercent); - ret.setMaxHeapSize(maxHeapSize); - ret.setMaxHeapPercent(maxHeapPercent); - ret.setOptions(opts); + net.sf.launch4j.config.Jre toL4j() { + net.sf.launch4j.config.Jre ret = new net.sf.launch4j.config.Jre(); + + ret.setPath(path); + ret.setMinVersion(minVersion); + ret.setMaxVersion(maxVersion); + ret.setJdkPreference(jdkPreference); + ret.setInitialHeapSize(initialHeapSize); + ret.setInitialHeapPercent(initialHeapPercent); + ret.setMaxHeapSize(maxHeapSize); + ret.setMaxHeapPercent(maxHeapPercent); + ret.setOptions(opts); ret.setRuntimeBits(runtimeBits); - return ret; - } + return ret; + } @Override public String toString() { 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 4651804..944a218 100644 --- a/src/main/java/com/akathist/maven/plugins/launch4j/Launch4jMojo.java +++ b/src/main/java/com/akathist/maven/plugins/launch4j/Launch4jMojo.java @@ -52,554 +52,557 @@ /** * Wraps a jar in a Windows executable. */ -@Mojo(name="launch4j",defaultPhase=LifecyclePhase.PACKAGE,requiresDependencyResolution=ResolutionScope.COMPILE) +@Mojo(name = "launch4j", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.COMPILE) public class Launch4jMojo extends AbstractMojo { - private static final String LAUNCH4J_ARTIFACT_ID = "launch4j"; - - private static final String LAUNCH4J_GROUP_ID = "net.sf.launch4j"; - - /** - * The dependencies required by the project. - */ - @Parameter(defaultValue="${project.artifacts}",required=true,readonly=true) - private Set dependencies; - - /** - * The user's current project. - */ - @Parameter(defaultValue="${project}",required=true,readonly=true) - private MavenProject project; - - /** - * The user's plugins (including, I hope, this one). - */ - @Parameter(defaultValue="${project.build.plugins}",required=true,readonly=true) - private List plugins; - - /** - * Used to look up Artifacts in the remote repository. - */ - @Component(role=ArtifactFactory.class) - private ArtifactFactory factory; - - /** - * The user's local repository. - */ - @Parameter(defaultValue="${localRepository}",required=true,readonly=true) - private ArtifactRepository localRepository; - - /** - * The artifact resolver used to grab the binary bits that launch4j needs. - */ - @Component(role=ArtifactResolver.class) - private ArtifactResolver resolver; - - /** - * The dependencies of this plugin. - * Used to get the Launch4j artifact version. - */ - @Parameter(defaultValue="${plugin.artifacts}") - private java.util.List pluginArtifacts; - - /** - * The base of the current project. - */ - @Parameter(defaultValue="${project.basedir}",required=true,readonly=true) - private File basedir; - - /** - * Whether you want a gui or console app. - * Valid values are "gui" and "console." - * If you say gui, then launch4j will run your app from javaw instead of java - * in order to avoid opening a DOS window. - * Choosing gui also enables other options like taskbar icon and a splash screen. - */ - @Parameter(required=true) - private String headerType; - - /** - * The name of the executable you want launch4j to produce. - * The path, if relative, is relative to the pom.xml. - */ - @Parameter(defaultValue="${project.bluid.directory}/${project.artifactId}.exe") - private File outfile; - - /** - * The jar to bundle inside the executable. - * The path, if relative, is relative to the pom.xml. - *

- * If you don't want to wrap the jar, then this value should be the runtime path - * to the jar relative to the executable. You should also set dontWrapJar to true. - *

- * You can only bundle a single jar. Therefore, you should either create a jar that contains - * your own code plus all your dependencies, or you should distribute your dependencies alongside - * the executable. - */ - @Parameter(defaultValue="${project.build.directory}/${project.build.finalName}.jar") - private String jar; - - /** - * Whether the executable should wrap the jar or not. - */ - @Parameter(defaultValue="false") - private boolean dontWrapJar; - - /** - * The title of the error popup if something goes wrong trying to run your program, - * like if java can't be found. If this is a console app and not a gui, then this value - * is used to prefix any error messages, as in ${errTitle}: ${errorMessage}. - */ - @Parameter - private String errTitle; - - /** - * downloadUrl (?). - */ - @Parameter - private String downloadUrl; - - /** - * supportUrl (?). - */ - @Parameter - private String supportUrl; - - /** - * Constant command line arguments to pass to your program's main method. - * Actual command line arguments entered by the user will appear after these. - */ - @Parameter - private String cmdLine; - - /** - * Changes to the given directory, relative to the executable, before running your jar. - * If set to . the current directory will be where the executable is. - * If omitted, the directory will not be changed. - */ - @Parameter - private String chdir; - - /** - * Priority class of windows process. - * Valid values are "normal" (default), "idle" and "high". - * @see MSDN: Scheduling Priorities - */ - @Parameter(defaultValue="normal") - private String priority; - - - /** - * If true, the executable waits for the java application to finish before returning its exit code. - * Defaults to false for gui applications. Has no effect for console applications, which always wait. - */ - @Parameter(defaultValue="false") - private boolean stayAlive; - - /** - * If true, when the application exits, any exit code other than 0 is considered a crash and - * the application will be started again. - */ - @Parameter(defaultValue="false") - private boolean restartOnCrash; - - /** - * The icon to use in the taskbar. Must be in ico format. - */ - @Parameter - private File icon; - - /** - * Object files to include. Used for custom headers only. - */ - @Parameter - private List objs; - - /** - * Win32 libraries to include. Used for custom headers only. - */ - @Parameter - private List libs; - - /** - * Variables to set. - */ - @Parameter - private List vars; - - /** - * Details about the supported jres. - */ - @Parameter(required=true) - private Jre jre; - - /** - * Details about the classpath your application should have. - * This is required if you are not wrapping a jar. - */ - @Parameter - private ClassPath classPath; - - /** - * Details about whether to run as a single instance. - */ - @Parameter - private SingleInstance singleInstance; - - /** - * Details about the splash screen. - */ - @Parameter - private Splash splash; - - /** - * Lots of information you can attach to the windows process. - */ - @Parameter - private VersionInfo versionInfo; - - /** - * Various messages you can display. - */ - @Parameter - private Messages messages; - - /** - * Windows manifest file (a XML file) with the same name as .exe file (myapp.exe.manifest) - */ - @Parameter - private File manifest; - - private File getJar() { - return new File(jar); - } - - public void execute() throws MojoExecutionException { - if (getLog().isDebugEnabled()) printState(); - - Config c = new Config(); - - c.setHeaderType(headerType); - c.setOutfile(outfile); - c.setJar(getJar()); - c.setDontWrapJar(dontWrapJar); - c.setErrTitle(errTitle); - c.setDownloadUrl(downloadUrl); - c.setSupportUrl(supportUrl); - c.setCmdLine(cmdLine); - c.setChdir(chdir); - c.setPriority(priority); - c.setStayAlive(stayAlive); - c.setRestartOnCrash(restartOnCrash); - c.setManifest(manifest); - c.setIcon(icon); - c.setHeaderObjects(objs); - c.setLibs(libs); - c.setVariables(vars); - - if (classPath != null) { - c.setClassPath(classPath.toL4j(dependencies, project.getRuntimeArtifacts())); - } - if (jre != null) { - c.setJre(jre.toL4j()); - } - if (singleInstance != null) { - c.setSingleInstance(singleInstance.toL4j()); - } - if (splash != null) { - c.setSplash(splash.toL4j()); - } - if (versionInfo != null) { - c.setVersionInfo(versionInfo.toL4j()); - } - if (messages != null) { - c.setMessages(messages.toL4j()); - } - - ConfigPersister.getInstance().setAntConfig(c, getBaseDir()); - File workdir = setupBuildEnvironment(); - Builder b = new Builder(new MavenLog(getLog()), workdir); - - try { - b.build(); - } catch (BuilderException e) { - getLog().error(e); - throw new MojoExecutionException("Failed to build the executable; please verify your configuration.", e); - } - } - - /** - * Prepares a little directory for launch4j to do its thing. Launch4j needs a bunch of object files - * (in the w32api and head directories) and the ld and windres binaries (in the bin directory). - * The tricky part is that launch4j picks this directory based on where its own jar is sitting. - * In our case, the jar is going to be sitting in the user's ~/.m2 repository. That's okay: we know - * maven is allowed to write there. So we'll just add our things to that directory. - *

- * This approach is not without flaws. - * It risks two processes writing to the directory at the same time. - * But fortunately, once the binary bits are in place, we don't do any more writing there, - * and launch4j doesn't write there either. - * Usually ~/.m2 will only be one system or another. - * But if it's an NFS mount shared by several system types, this approach will break. - *

- * Okay, so here is a better proposal: package the plugin without these varying binary files, - * and put each set of binaries in its own tarball. Download the tarball you need to ~/.m2 and - * unpack it. Then different systems won't contend for the same space. But then I'll need to hack - * the l4j code so it permits passing in a work directory and doesn't always base it on - * the location of its own jarfile. - * - * @return the work directory. - */ - private File setupBuildEnvironment() throws MojoExecutionException { - Artifact binaryBits = chooseBinaryBits(); - retrieveBinaryBits(binaryBits); - return unpackWorkDir(binaryBits); - } - - /** - * Unzips the given artifact in-place and returns the newly-unzipped top-level directory. - * Writes a marker file to prevent unzipping more than once. - */ - private File unpackWorkDir(Artifact a) throws MojoExecutionException { - File platJar = a.getFile(); - File dest = platJar.getParentFile(); - File marker = new File(dest, platJar.getName() + ".unpacked"); - - // If the artifact is a SNAPSHOT, then a.getVersion() will report the long timestamp, - // but getFile() will be 1.1-SNAPSHOT. - // Since getFile() doesn't use the timestamp, all timestamps wind up in the same place. - // Therefore we need to expand the jar every time, if the marker file is stale. - if (marker.exists() && marker.lastModified() > platJar.lastModified()) { - // if (marker.exists() && marker.platJar.getName().indexOf("SNAPSHOT") == -1) { - getLog().info("Platform-specific work directory already exists: " + dest.getAbsolutePath()); - } else { - JarFile jf = null; - try { - // trying to use plexus-archiver here is a miserable waste of time: - jf = new JarFile(platJar); - Enumeration en = jf.entries(); - while (en.hasMoreElements()) { - JarEntry je = en.nextElement(); - File outFile = new File(dest, je.getName()); - File parent = outFile.getParentFile(); - if (parent != null) parent.mkdirs(); - if (je.isDirectory()) { - outFile.mkdirs(); - } else { - InputStream in = jf.getInputStream(je); - byte[] buf = new byte[1024]; - int len; - FileOutputStream fout = null; - try { - fout = new FileOutputStream(outFile); - while ((len = in.read(buf)) >= 0) { - fout.write(buf, 0, len); - } - fout.close(); - fout = null; - } finally { - if (fout != null) { - try { - fout.close(); - } catch (IOException e2) {} // ignore - } - } - outFile.setLastModified(je.getTime()); - } - } - } catch (IOException e) { - throw new MojoExecutionException("Error unarchiving " + platJar, e); - } finally { - try { - if (jf != null) jf.close(); - } catch (IOException e) {} // ignore - } - - try { - marker.createNewFile(); - marker.setLastModified(new Date().getTime()); - } catch (IOException e) { - getLog().warn("Trouble creating marker file " + marker, e); - } - } - - String n = platJar.getName(); - File workdir = new File(dest, n.substring(0, n.length() - 4)); - setPermissions(workdir); - return workdir; - } - - /** - * Chmods the helper executables ld and windres on systems where that is necessary. - */ - private void setPermissions(File workdir) throws MojoExecutionException { - if ( ! System.getProperty("os.name").startsWith("Windows")) { - Runtime r = Runtime.getRuntime(); - try { - r.exec("chmod 755 " + workdir + "/bin/ld").waitFor(); - r.exec("chmod 755 " + workdir + "/bin/windres").waitFor(); - } catch (InterruptedException e) { - getLog().warn("Interrupted while chmodding platform-specific binaries", e); - } catch (IOException e) { - getLog().warn("Unable to set platform-specific binaries to 755", e); - } - } - } - - /** - * Downloads the platform-specific parts, if necessary. - */ - private void retrieveBinaryBits(Artifact a) throws MojoExecutionException { - try { - resolver.resolve(a, project.getRemoteArtifactRepositories(), localRepository); - - } catch (ArtifactNotFoundException e) { - throw new MojoExecutionException("Can't find platform-specific components", e); - } catch (ArtifactResolutionException e) { - throw new MojoExecutionException("Can't retrieve platform-specific components", e); - } - } - - /** - * Decides which platform-specific bundle we need, based on the current operating system. - */ - private Artifact chooseBinaryBits() throws MojoExecutionException { - String plat; - String os = System.getProperty("os.name"); - getLog().debug("OS = " + os); - - // See here for possible values of os.name: - // http://lopica.sourceforge.net/os.html - if (os.startsWith("Windows")) { - plat = "win32"; - } else if ("Linux".equals(os)) { - plat = "linux"; - } else if ("Solaris".equals(os) || "SunOS".equals(os)) { - plat = "solaris"; - } else if ("Mac OS X".equals(os) || "Darwin".equals(os)) { - plat = "mac"; - } else { - throw new MojoExecutionException("Sorry, Launch4j doesn't support the '" + os + "' OS."); - } - - return factory.createArtifactWithClassifier(LAUNCH4J_GROUP_ID, LAUNCH4J_ARTIFACT_ID, - getLaunch4jVersion(), "jar", "workdir-" + plat); - } - - - private File getBaseDir() { - return basedir; - } - - /** - * Just prints out how we were configured. - */ - private void printState() { - Log log = getLog(); - - log.debug("headerType = " + headerType); - log.debug("outfile = " + outfile); - log.debug("jar = " + jar); - log.debug("dontWrapJar = " + dontWrapJar); - log.debug("errTitle = " + errTitle); - log.debug("downloadUrl = " + downloadUrl); - log.debug("supportUrl = " + supportUrl); - log.debug("cmdLine = " + cmdLine); - log.debug("chdir = " + chdir); - log.debug("priority = " + priority); - log.debug("stayAlive = " + stayAlive); - log.debug("restartOnCrash = " + restartOnCrash); - log.debug("icon = " + icon); - log.debug("objs = " + objs); - log.debug("libs = " + libs); - log.debug("vars = " + vars); - if (singleInstance != null) { - log.debug("singleInstance.mutexName = " + singleInstance.mutexName); - log.debug("singleInstance.windowTitle = " + singleInstance.windowTitle); - } else { - log.debug("singleInstance = null"); - } - if (jre != null) { - log.debug("jre.path = " + jre.path); - log.debug("jre.minVersion = " + jre.minVersion); - log.debug("jre.maxVersion = " + jre.maxVersion); - log.debug("jre.jdkPreference = " + jre.jdkPreference); - log.debug("jre.initialHeapSize = " + jre.initialHeapSize); - log.debug("jre.initialHeapPercent = " + jre.initialHeapPercent); - log.debug("jre.maxHeapSize = " + jre.maxHeapSize); - log.debug("jre.maxHeapPercent = " + jre.maxHeapPercent); - log.debug("jre.opts = "+ jre.opts); - } else { - log.debug("jre = null"); - } - if (classPath != null) { - log.debug("classPath.mainClass = " + classPath.mainClass); - log.debug("classPath.addDependencies = " + classPath.addDependencies); - log.debug("classPath.jarLocation = " + classPath.jarLocation); - log.debug("classPath.preCp = " + classPath.preCp); - log.debug("classPath.postCp = " + classPath.postCp); - } else { - log.info("classpath = null"); - } - if (splash != null) { - log.debug("splash.file = " + splash.file); - log.debug("splash.waitForWindow = " + splash.waitForWindow); - log.debug("splash.timeout = " + splash.timeout); - log.debug("splash.timoutErr = " + splash.timeoutErr); - } else { - log.debug("splash = null"); - } - if (versionInfo != null) { - log.debug("versionInfo.fileVersion = " + versionInfo.fileVersion); - log.debug("versionInfo.txtFileVersion = " + versionInfo.txtFileVersion); - log.debug("versionInfo.fileDescription = " + versionInfo.fileDescription); - log.debug("versionInfo.copyright = " + versionInfo.copyright); - log.debug("versionInfo.productVersion = " + versionInfo.productVersion); - log.debug("versionInfo.txtProductVersion = " + versionInfo.txtProductVersion); - log.debug("versionInfo.productName = " + versionInfo.productName); - log.debug("versionInfo.companyName = " + versionInfo.companyName); - log.debug("versionInfo.internalName = " + versionInfo.internalName); - log.debug("versionInfo.originalFilename = " + versionInfo.originalFilename); - } else { - log.debug("versionInfo = null"); - } - if (messages != null) { - log.debug("messages.startupErr = " + messages.startupErr); - log.debug("messages.bundledJreErr = " + messages.bundledJreErr); - log.debug("messages.jreVersionErr = " + messages.jreVersionErr); - log.debug("messages.launcherErr = " + messages.launcherErr); - log.debug("messages.instanceAlreadyExistsMsg = " + messages.instanceAlreadyExistsMsg); - } else { - log.debug("messages = null"); - } - } - - /** - * The Launch4j version used by the plugin. - * We want to download the platform-specific bundle whose version matches the Launch4j version, - * so we have to figure out what version the plugin is using. - * - * @return - * @throws MojoExecutionException - */ - private String getLaunch4jVersion() throws MojoExecutionException{ - String version = null; - - for(Artifact artifact: pluginArtifacts){ - if(LAUNCH4J_GROUP_ID.equals(artifact.getGroupId()) && - LAUNCH4J_ARTIFACT_ID.equals(artifact.getArtifactId()) - && "core".equals(artifact.getClassifier()) ){ - - version = artifact.getVersion(); - getLog().debug("Found launch4j version " + version); - break; - } - } - - if(version==null){ - throw new MojoExecutionException("Impossible to find which Launch4j version to use"); - } - - return version; - } + private static final String LAUNCH4J_ARTIFACT_ID = "launch4j"; + + private static final String LAUNCH4J_GROUP_ID = "net.sf.launch4j"; + + /** + * The dependencies required by the project. + */ + @Parameter(defaultValue = "${project.artifacts}", required = true, readonly = true) + private Set dependencies; + + /** + * The user's current project. + */ + @Parameter(defaultValue = "${project}", required = true, readonly = true) + private MavenProject project; + + /** + * The user's plugins (including, I hope, this one). + */ + @Parameter(defaultValue = "${project.build.plugins}", required = true, readonly = true) + private List plugins; + + /** + * Used to look up Artifacts in the remote repository. + */ + @Component(role = ArtifactFactory.class) + private ArtifactFactory factory; + + /** + * The user's local repository. + */ + @Parameter(defaultValue = "${localRepository}", required = true, readonly = true) + private ArtifactRepository localRepository; + + /** + * The artifact resolver used to grab the binary bits that launch4j needs. + */ + @Component(role = ArtifactResolver.class) + private ArtifactResolver resolver; + + /** + * The dependencies of this plugin. + * Used to get the Launch4j artifact version. + */ + @Parameter(defaultValue = "${plugin.artifacts}") + private java.util.List pluginArtifacts; + + /** + * The base of the current project. + */ + @Parameter(defaultValue = "${project.basedir}", required = true, readonly = true) + private File basedir; + + /** + * Whether you want a gui or console app. + * Valid values are "gui" and "console." + * If you say gui, then launch4j will run your app from javaw instead of java + * in order to avoid opening a DOS window. + * Choosing gui also enables other options like taskbar icon and a splash screen. + */ + @Parameter(required = true) + private String headerType; + + /** + * The name of the executable you want launch4j to produce. + * The path, if relative, is relative to the pom.xml. + */ + @Parameter(defaultValue = "${project.bluid.directory}/${project.artifactId}.exe") + private File outfile; + + /** + * The jar to bundle inside the executable. + * The path, if relative, is relative to the pom.xml. + *

+ * If you don't want to wrap the jar, then this value should be the runtime path + * to the jar relative to the executable. You should also set dontWrapJar to true. + *

+ * You can only bundle a single jar. Therefore, you should either create a jar that contains + * your own code plus all your dependencies, or you should distribute your dependencies alongside + * the executable. + */ + @Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}.jar") + private String jar; + + /** + * Whether the executable should wrap the jar or not. + */ + @Parameter(defaultValue = "false") + private boolean dontWrapJar; + + /** + * The title of the error popup if something goes wrong trying to run your program, + * like if java can't be found. If this is a console app and not a gui, then this value + * is used to prefix any error messages, as in ${errTitle}: ${errorMessage}. + */ + @Parameter + private String errTitle; + + /** + * downloadUrl (?). + */ + @Parameter + private String downloadUrl; + + /** + * supportUrl (?). + */ + @Parameter + private String supportUrl; + + /** + * Constant command line arguments to pass to your program's main method. + * Actual command line arguments entered by the user will appear after these. + */ + @Parameter + private String cmdLine; + + /** + * Changes to the given directory, relative to the executable, before running your jar. + * If set to . the current directory will be where the executable is. + * If omitted, the directory will not be changed. + */ + @Parameter + private String chdir; + + /** + * Priority class of windows process. + * Valid values are "normal" (default), "idle" and "high". + * + * @see MSDN: Scheduling Priorities + */ + @Parameter(defaultValue = "normal") + private String priority; + + + /** + * If true, the executable waits for the java application to finish before returning its exit code. + * Defaults to false for gui applications. Has no effect for console applications, which always wait. + */ + @Parameter(defaultValue = "false") + private boolean stayAlive; + + /** + * If true, when the application exits, any exit code other than 0 is considered a crash and + * the application will be started again. + */ + @Parameter(defaultValue = "false") + private boolean restartOnCrash; + + /** + * The icon to use in the taskbar. Must be in ico format. + */ + @Parameter + private File icon; + + /** + * Object files to include. Used for custom headers only. + */ + @Parameter + private List objs; + + /** + * Win32 libraries to include. Used for custom headers only. + */ + @Parameter + private List libs; + + /** + * Variables to set. + */ + @Parameter + private List vars; + + /** + * Details about the supported jres. + */ + @Parameter(required = true) + private Jre jre; + + /** + * Details about the classpath your application should have. + * This is required if you are not wrapping a jar. + */ + @Parameter + private ClassPath classPath; + + /** + * Details about whether to run as a single instance. + */ + @Parameter + private SingleInstance singleInstance; + + /** + * Details about the splash screen. + */ + @Parameter + private Splash splash; + + /** + * Lots of information you can attach to the windows process. + */ + @Parameter + private VersionInfo versionInfo; + + /** + * Various messages you can display. + */ + @Parameter + private Messages messages; + + /** + * Windows manifest file (a XML file) with the same name as .exe file (myapp.exe.manifest) + */ + @Parameter + private File manifest; + + private File getJar() { + return new File(jar); + } + + public void execute() throws MojoExecutionException { + if (getLog().isDebugEnabled()) printState(); + + Config c = new Config(); + + c.setHeaderType(headerType); + c.setOutfile(outfile); + c.setJar(getJar()); + c.setDontWrapJar(dontWrapJar); + c.setErrTitle(errTitle); + c.setDownloadUrl(downloadUrl); + c.setSupportUrl(supportUrl); + c.setCmdLine(cmdLine); + c.setChdir(chdir); + c.setPriority(priority); + c.setStayAlive(stayAlive); + c.setRestartOnCrash(restartOnCrash); + c.setManifest(manifest); + c.setIcon(icon); + c.setHeaderObjects(objs); + c.setLibs(libs); + c.setVariables(vars); + + if (classPath != null) { + c.setClassPath(classPath.toL4j(dependencies, project.getRuntimeArtifacts())); + } + if (jre != null) { + c.setJre(jre.toL4j()); + } + if (singleInstance != null) { + c.setSingleInstance(singleInstance.toL4j()); + } + if (splash != null) { + c.setSplash(splash.toL4j()); + } + if (versionInfo != null) { + c.setVersionInfo(versionInfo.toL4j()); + } + if (messages != null) { + c.setMessages(messages.toL4j()); + } + + ConfigPersister.getInstance().setAntConfig(c, getBaseDir()); + File workdir = setupBuildEnvironment(); + Builder b = new Builder(new MavenLog(getLog()), workdir); + + try { + b.build(); + } catch (BuilderException e) { + getLog().error(e); + throw new MojoExecutionException("Failed to build the executable; please verify your configuration.", e); + } + } + + /** + * Prepares a little directory for launch4j to do its thing. Launch4j needs a bunch of object files + * (in the w32api and head directories) and the ld and windres binaries (in the bin directory). + * The tricky part is that launch4j picks this directory based on where its own jar is sitting. + * In our case, the jar is going to be sitting in the user's ~/.m2 repository. That's okay: we know + * maven is allowed to write there. So we'll just add our things to that directory. + *

+ * This approach is not without flaws. + * It risks two processes writing to the directory at the same time. + * But fortunately, once the binary bits are in place, we don't do any more writing there, + * and launch4j doesn't write there either. + * Usually ~/.m2 will only be one system or another. + * But if it's an NFS mount shared by several system types, this approach will break. + *

+ * Okay, so here is a better proposal: package the plugin without these varying binary files, + * and put each set of binaries in its own tarball. Download the tarball you need to ~/.m2 and + * unpack it. Then different systems won't contend for the same space. But then I'll need to hack + * the l4j code so it permits passing in a work directory and doesn't always base it on + * the location of its own jarfile. + * + * @return the work directory. + */ + private File setupBuildEnvironment() throws MojoExecutionException { + Artifact binaryBits = chooseBinaryBits(); + retrieveBinaryBits(binaryBits); + return unpackWorkDir(binaryBits); + } + + /** + * Unzips the given artifact in-place and returns the newly-unzipped top-level directory. + * Writes a marker file to prevent unzipping more than once. + */ + private File unpackWorkDir(Artifact a) throws MojoExecutionException { + File platJar = a.getFile(); + File dest = platJar.getParentFile(); + File marker = new File(dest, platJar.getName() + ".unpacked"); + + // If the artifact is a SNAPSHOT, then a.getVersion() will report the long timestamp, + // but getFile() will be 1.1-SNAPSHOT. + // Since getFile() doesn't use the timestamp, all timestamps wind up in the same place. + // Therefore we need to expand the jar every time, if the marker file is stale. + if (marker.exists() && marker.lastModified() > platJar.lastModified()) { + // if (marker.exists() && marker.platJar.getName().indexOf("SNAPSHOT") == -1) { + getLog().info("Platform-specific work directory already exists: " + dest.getAbsolutePath()); + } else { + JarFile jf = null; + try { + // trying to use plexus-archiver here is a miserable waste of time: + jf = new JarFile(platJar); + Enumeration en = jf.entries(); + while (en.hasMoreElements()) { + JarEntry je = en.nextElement(); + File outFile = new File(dest, je.getName()); + File parent = outFile.getParentFile(); + if (parent != null) parent.mkdirs(); + if (je.isDirectory()) { + outFile.mkdirs(); + } else { + InputStream in = jf.getInputStream(je); + byte[] buf = new byte[1024]; + int len; + FileOutputStream fout = null; + try { + fout = new FileOutputStream(outFile); + while ((len = in.read(buf)) >= 0) { + fout.write(buf, 0, len); + } + fout.close(); + fout = null; + } finally { + if (fout != null) { + try { + fout.close(); + } catch (IOException e2) { + } // ignore + } + } + outFile.setLastModified(je.getTime()); + } + } + } catch (IOException e) { + throw new MojoExecutionException("Error unarchiving " + platJar, e); + } finally { + try { + if (jf != null) jf.close(); + } catch (IOException e) { + } // ignore + } + + try { + marker.createNewFile(); + marker.setLastModified(new Date().getTime()); + } catch (IOException e) { + getLog().warn("Trouble creating marker file " + marker, e); + } + } + + String n = platJar.getName(); + File workdir = new File(dest, n.substring(0, n.length() - 4)); + setPermissions(workdir); + return workdir; + } + + /** + * Chmods the helper executables ld and windres on systems where that is necessary. + */ + private void setPermissions(File workdir) throws MojoExecutionException { + if (!System.getProperty("os.name").startsWith("Windows")) { + Runtime r = Runtime.getRuntime(); + try { + r.exec("chmod 755 " + workdir + "/bin/ld").waitFor(); + r.exec("chmod 755 " + workdir + "/bin/windres").waitFor(); + } catch (InterruptedException e) { + getLog().warn("Interrupted while chmodding platform-specific binaries", e); + } catch (IOException e) { + getLog().warn("Unable to set platform-specific binaries to 755", e); + } + } + } + + /** + * Downloads the platform-specific parts, if necessary. + */ + private void retrieveBinaryBits(Artifact a) throws MojoExecutionException { + try { + resolver.resolve(a, project.getRemoteArtifactRepositories(), localRepository); + + } catch (ArtifactNotFoundException e) { + throw new MojoExecutionException("Can't find platform-specific components", e); + } catch (ArtifactResolutionException e) { + throw new MojoExecutionException("Can't retrieve platform-specific components", e); + } + } + + /** + * Decides which platform-specific bundle we need, based on the current operating system. + */ + private Artifact chooseBinaryBits() throws MojoExecutionException { + String plat; + String os = System.getProperty("os.name"); + getLog().debug("OS = " + os); + + // See here for possible values of os.name: + // http://lopica.sourceforge.net/os.html + if (os.startsWith("Windows")) { + plat = "win32"; + } else if ("Linux".equals(os)) { + plat = "linux"; + } else if ("Solaris".equals(os) || "SunOS".equals(os)) { + plat = "solaris"; + } else if ("Mac OS X".equals(os) || "Darwin".equals(os)) { + plat = "mac"; + } else { + throw new MojoExecutionException("Sorry, Launch4j doesn't support the '" + os + "' OS."); + } + + return factory.createArtifactWithClassifier(LAUNCH4J_GROUP_ID, LAUNCH4J_ARTIFACT_ID, + getLaunch4jVersion(), "jar", "workdir-" + plat); + } + + + private File getBaseDir() { + return basedir; + } + + /** + * Just prints out how we were configured. + */ + private void printState() { + Log log = getLog(); + + log.debug("headerType = " + headerType); + log.debug("outfile = " + outfile); + log.debug("jar = " + jar); + log.debug("dontWrapJar = " + dontWrapJar); + log.debug("errTitle = " + errTitle); + log.debug("downloadUrl = " + downloadUrl); + log.debug("supportUrl = " + supportUrl); + log.debug("cmdLine = " + cmdLine); + log.debug("chdir = " + chdir); + log.debug("priority = " + priority); + log.debug("stayAlive = " + stayAlive); + log.debug("restartOnCrash = " + restartOnCrash); + log.debug("icon = " + icon); + log.debug("objs = " + objs); + log.debug("libs = " + libs); + log.debug("vars = " + vars); + if (singleInstance != null) { + log.debug("singleInstance.mutexName = " + singleInstance.mutexName); + log.debug("singleInstance.windowTitle = " + singleInstance.windowTitle); + } else { + log.debug("singleInstance = null"); + } + if (jre != null) { + log.debug("jre.path = " + jre.path); + log.debug("jre.minVersion = " + jre.minVersion); + log.debug("jre.maxVersion = " + jre.maxVersion); + log.debug("jre.jdkPreference = " + jre.jdkPreference); + log.debug("jre.initialHeapSize = " + jre.initialHeapSize); + log.debug("jre.initialHeapPercent = " + jre.initialHeapPercent); + log.debug("jre.maxHeapSize = " + jre.maxHeapSize); + log.debug("jre.maxHeapPercent = " + jre.maxHeapPercent); + log.debug("jre.opts = " + jre.opts); + } else { + log.debug("jre = null"); + } + if (classPath != null) { + log.debug("classPath.mainClass = " + classPath.mainClass); + log.debug("classPath.addDependencies = " + classPath.addDependencies); + log.debug("classPath.jarLocation = " + classPath.jarLocation); + log.debug("classPath.preCp = " + classPath.preCp); + log.debug("classPath.postCp = " + classPath.postCp); + } else { + log.info("classpath = null"); + } + if (splash != null) { + log.debug("splash.file = " + splash.file); + log.debug("splash.waitForWindow = " + splash.waitForWindow); + log.debug("splash.timeout = " + splash.timeout); + log.debug("splash.timoutErr = " + splash.timeoutErr); + } else { + log.debug("splash = null"); + } + if (versionInfo != null) { + log.debug("versionInfo.fileVersion = " + versionInfo.fileVersion); + log.debug("versionInfo.txtFileVersion = " + versionInfo.txtFileVersion); + log.debug("versionInfo.fileDescription = " + versionInfo.fileDescription); + log.debug("versionInfo.copyright = " + versionInfo.copyright); + log.debug("versionInfo.productVersion = " + versionInfo.productVersion); + log.debug("versionInfo.txtProductVersion = " + versionInfo.txtProductVersion); + log.debug("versionInfo.productName = " + versionInfo.productName); + log.debug("versionInfo.companyName = " + versionInfo.companyName); + log.debug("versionInfo.internalName = " + versionInfo.internalName); + log.debug("versionInfo.originalFilename = " + versionInfo.originalFilename); + } else { + log.debug("versionInfo = null"); + } + if (messages != null) { + log.debug("messages.startupErr = " + messages.startupErr); + log.debug("messages.bundledJreErr = " + messages.bundledJreErr); + log.debug("messages.jreVersionErr = " + messages.jreVersionErr); + log.debug("messages.launcherErr = " + messages.launcherErr); + log.debug("messages.instanceAlreadyExistsMsg = " + messages.instanceAlreadyExistsMsg); + } else { + log.debug("messages = null"); + } + } + + /** + * The Launch4j version used by the plugin. + * We want to download the platform-specific bundle whose version matches the Launch4j version, + * so we have to figure out what version the plugin is using. + * + * @return + * @throws MojoExecutionException + */ + private String getLaunch4jVersion() throws MojoExecutionException { + String version = null; + + for (Artifact artifact : pluginArtifacts) { + if (LAUNCH4J_GROUP_ID.equals(artifact.getGroupId()) && + LAUNCH4J_ARTIFACT_ID.equals(artifact.getArtifactId()) + && "core".equals(artifact.getClassifier())) { + + version = artifact.getVersion(); + getLog().debug("Found launch4j version " + version); + break; + } + } + + if (version == null) { + throw new MojoExecutionException("Impossible to find which Launch4j version to use"); + } + + return version; + } } diff --git a/src/main/java/com/akathist/maven/plugins/launch4j/MavenLog.java b/src/main/java/com/akathist/maven/plugins/launch4j/MavenLog.java index a07ec66..5b47e71 100644 --- a/src/main/java/com/akathist/maven/plugins/launch4j/MavenLog.java +++ b/src/main/java/com/akathist/maven/plugins/launch4j/MavenLog.java @@ -20,18 +20,18 @@ public class MavenLog extends net.sf.launch4j.Log { - org.apache.maven.plugin.logging.Log _log; + org.apache.maven.plugin.logging.Log _log; - public MavenLog(org.apache.maven.plugin.logging.Log log) { - _log = log; - } + public MavenLog(org.apache.maven.plugin.logging.Log log) { + _log = log; + } - public void clear() { - _log.info(""); - } + public void clear() { + _log.info(""); + } - public void append(String line) { - _log.info("launch4j: " + line); - } + public void append(String line) { + _log.info("launch4j: " + line); + } } 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 9cb05ca..34cd543 100644 --- a/src/main/java/com/akathist/maven/plugins/launch4j/Messages.java +++ b/src/main/java/com/akathist/maven/plugins/launch4j/Messages.java @@ -24,27 +24,27 @@ */ public class Messages { - String startupErr; + String startupErr; - String bundledJreErr; + String bundledJreErr; - String jreVersionErr; + String jreVersionErr; - String launcherErr; + String launcherErr; - String instanceAlreadyExistsMsg; + String instanceAlreadyExistsMsg; - net.sf.launch4j.config.Msg toL4j() { - net.sf.launch4j.config.Msg ret = new net.sf.launch4j.config.Msg(); + net.sf.launch4j.config.Msg toL4j() { + net.sf.launch4j.config.Msg ret = new net.sf.launch4j.config.Msg(); - ret.setStartupErr(startupErr); - ret.setBundledJreErr(bundledJreErr); - ret.setJreVersionErr(jreVersionErr); - ret.setLauncherErr(launcherErr); - ret.setInstanceAlreadyExistsMsg(instanceAlreadyExistsMsg); + ret.setStartupErr(startupErr); + ret.setBundledJreErr(bundledJreErr); + ret.setJreVersionErr(jreVersionErr); + ret.setLauncherErr(launcherErr); + ret.setInstanceAlreadyExistsMsg(instanceAlreadyExistsMsg); - return ret; - } + return ret; + } } 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 23dcab9..a52cc40 100644 --- a/src/main/java/com/akathist/maven/plugins/launch4j/SingleInstance.java +++ b/src/main/java/com/akathist/maven/plugins/launch4j/SingleInstance.java @@ -24,17 +24,17 @@ */ public class SingleInstance { - String mutexName; + String mutexName; - String windowTitle; + String windowTitle; - net.sf.launch4j.config.SingleInstance toL4j() { - net.sf.launch4j.config.SingleInstance ret = new net.sf.launch4j.config.SingleInstance(); + net.sf.launch4j.config.SingleInstance toL4j() { + net.sf.launch4j.config.SingleInstance ret = new net.sf.launch4j.config.SingleInstance(); - ret.setMutexName(mutexName); - ret.setWindowTitle(windowTitle); + ret.setMutexName(mutexName); + ret.setWindowTitle(windowTitle); - return ret; - } + return ret; + } } 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 5531a27..a25c567 100644 --- a/src/main/java/com/akathist/maven/plugins/launch4j/Splash.java +++ b/src/main/java/com/akathist/maven/plugins/launch4j/Splash.java @@ -24,41 +24,41 @@ public class Splash { - /** - * The path (relative to the executable when distributed) to the splash page image. - */ - File file; + /** + * The path (relative to the executable when distributed) to the splash page image. + */ + File file; - /** - * If true, the splash screen will close automatically as soon as an error window or java window appears. - * If false, the splash screen will not close until {@link #timeout} sections. Defaults to true. - */ - @Parameter(defaultValue="true") - boolean waitForWindow; + /** + * If true, the splash screen will close automatically as soon as an error window or java window appears. + * If false, the splash screen will not close until {@link #timeout} sections. Defaults to true. + */ + @Parameter(defaultValue = "true") + boolean waitForWindow; - /** - * The number of seconds to keep the splash screen open before automatically closing it. - * Defaults to 60. - */ - @Parameter(defaultValue="60") - int timeout; + /** + * The number of seconds to keep the splash screen open before automatically closing it. + * Defaults to 60. + */ + @Parameter(defaultValue = "60") + int timeout; - /** - * If true, an error message will appear if the app hasn't started in {@link #timeout} seconds. - * If false, the splash screen will close quietly. Defaults to true. - */ - @Parameter(defaultValue="true") - boolean timeoutErr; + /** + * If true, an error message will appear if the app hasn't started in {@link #timeout} seconds. + * If false, the splash screen will close quietly. Defaults to true. + */ + @Parameter(defaultValue = "true") + boolean timeoutErr; - net.sf.launch4j.config.Splash toL4j() { - net.sf.launch4j.config.Splash ret = new net.sf.launch4j.config.Splash(); + net.sf.launch4j.config.Splash toL4j() { + net.sf.launch4j.config.Splash ret = new net.sf.launch4j.config.Splash(); - ret.setFile(file); - ret.setWaitForWindow(waitForWindow); - ret.setTimeout(timeout); - ret.setTimeoutErr(timeoutErr); + ret.setFile(file); + ret.setWaitForWindow(waitForWindow); + ret.setTimeout(timeout); + ret.setTimeoutErr(timeoutErr); - return ret; - } + return ret; + } } 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 36ca7b2..dd85342 100644 --- a/src/main/java/com/akathist/maven/plugins/launch4j/VersionInfo.java +++ b/src/main/java/com/akathist/maven/plugins/launch4j/VersionInfo.java @@ -23,72 +23,72 @@ */ public class VersionInfo { - /** - * Version number in x.x.x.x format. - */ - String fileVersion; + /** + * Version number in x.x.x.x format. + */ + String fileVersion; - /** - * Free-form version number, like "1.20.RC1." - */ - String txtFileVersion; + /** + * Free-form version number, like "1.20.RC1." + */ + String txtFileVersion; - /** - * File description shown to the user. - */ - String fileDescription; + /** + * File description shown to the user. + */ + String fileDescription; - /** - * Legal copyright. - */ - String copyright; + /** + * Legal copyright. + */ + String copyright; - /** - * Version number in x.x.x.x format. - */ - String productVersion; + /** + * Version number in x.x.x.x format. + */ + String productVersion; - /** - * Free-form version number, like "1.20.RC1." - */ - String txtProductVersion; + /** + * Free-form version number, like "1.20.RC1." + */ + String txtProductVersion; - /** - * The product name. - */ - String productName; + /** + * The product name. + */ + String productName; - /** - * The company name. - */ - String companyName; + /** + * The company name. + */ + String companyName; - /** - * The internal name. For instance, you could use the filename without extension or the module name. - */ - String internalName; + /** + * The internal name. For instance, you could use the filename without extension or the module name. + */ + String internalName; - /** - * The original filename without path. Setting this lets you determine whether a user has renamed the file. - */ - String originalFilename; + /** + * The original filename without path. Setting this lets you determine whether a user has renamed the file. + */ + String originalFilename; - net.sf.launch4j.config.VersionInfo toL4j() { - net.sf.launch4j.config.VersionInfo ret = new net.sf.launch4j.config.VersionInfo(); + net.sf.launch4j.config.VersionInfo toL4j() { + net.sf.launch4j.config.VersionInfo ret = new net.sf.launch4j.config.VersionInfo(); - ret.setFileVersion(fileVersion); - ret.setTxtFileVersion(txtFileVersion); - ret.setFileDescription(fileDescription); - ret.setCopyright(copyright); - ret.setProductVersion(productVersion); - ret.setTxtProductVersion(txtProductVersion); - ret.setProductName(productName); - ret.setCompanyName(companyName); - ret.setInternalName(internalName); - ret.setOriginalFilename(originalFilename); + ret.setFileVersion(fileVersion); + ret.setTxtFileVersion(txtFileVersion); + ret.setFileDescription(fileDescription); + ret.setCopyright(copyright); + ret.setProductVersion(productVersion); + ret.setTxtProductVersion(txtProductVersion); + ret.setProductName(productName); + ret.setCompanyName(companyName); + ret.setInternalName(internalName); + ret.setOriginalFilename(originalFilename); - return ret; - } + return ret; + } @Override public String toString() {