1111import static org .twdata .maven .mojoexecutor .MojoExecutor .version ;
1212
1313import java .io .File ;
14+ import java .util .ArrayList ;
1415import java .util .Arrays ;
1516import java .util .HashMap ;
17+ import java .util .List ;
1618import java .util .Map ;
1719
1820import org .apache .commons .lang .SystemUtils ;
2729import org .apache .maven .plugins .annotations .ResolutionScope ;
2830import org .apache .maven .project .MavenProject ;
2931import org .apache .maven .project .MavenProjectHelper ;
32+ import org .twdata .maven .mojoexecutor .MojoExecutor .Element ;
3033import org .twdata .maven .mojoexecutor .MojoExecutor .ExecutionEnvironment ;
3134
3235import fvarrui .maven .plugin .javapackager .utils .FileUtils ;
@@ -109,6 +112,12 @@ public class PackageMojo extends AbstractMojo {
109112
110113 @ Parameter (defaultValue = "false" , property = "bundleJre" , required = true )
111114 private Boolean bundleJre ;
115+
116+ @ Parameter (defaultValue = "false" , property = "forceJreOptimization" , required = true )
117+ private Boolean forceJreOptimization ;
118+
119+ @ Parameter (property = "additionalResources" , required = false )
120+ private List <File > additionalResources ;
112121
113122 public PackageMojo () {
114123 super ();
@@ -118,12 +127,11 @@ public PackageMojo() {
118127 public void execute () throws MojoExecutionException {
119128
120129 appFolder = new File (outputDirectory , "app" );
121- assetsFolder = new File (outputDirectory , "assets" );
122-
123130 if (!appFolder .exists ()) {
124131 appFolder .mkdirs ();
125132 }
126133
134+ assetsFolder = new File (outputDirectory , "assets" );
127135 if (!assetsFolder .exists ()) {
128136 assetsFolder .mkdirs ();
129137 }
@@ -134,6 +142,7 @@ public void execute() throws MojoExecutionException {
134142 getLog ().warn ("Specified license file doesn't exist: " + licenseFile .getAbsolutePath ());
135143 licenseFile = null ;
136144 }
145+ // if license not specified, get from pom
137146 if (licenseFile == null && !mavenProject .getLicenses ().isEmpty ()) {
138147 licenseFile = new File (mavenProject .getLicenses ().get (0 ).getUrl ());
139148 }
@@ -330,11 +339,9 @@ private void createMacAppBundle() throws MojoExecutionException {
330339 File infoPlistFile = new File (contentsFolder , "Info.plist" );
331340 VelocityUtils .render ("mac/Info.plist.vtl" , infoPlistFile , info );
332341
333- // copy specified additional resources into the top level directory
334- getLog ().info ("Copying additional resources" );
335- if (licenseFile != null ) {
336- FileUtils .copyFileToFolder (licenseFile , resourcesFolder );
337- }
342+ // copy specified additional resources into the top level directory (include license file)
343+ if (licenseFile != null ) additionalResources .add (licenseFile );
344+ copyAdditionalResources (additionalResources , resourcesFolder );
338345
339346 // codesign app folder
340347 ProcessUtils .execute ("codesign" , "--force" , "--deep" , "--sign" , "-" , appFile );
@@ -369,7 +376,11 @@ private void createLinuxExecutable() throws MojoExecutionException {
369376 // copy all dependencies
370377 File libsFolder = new File (appFolder , "libs" );
371378 copyAllDependencies (libsFolder );
372-
379+
380+ // copy additional resources
381+ if (licenseFile != null ) additionalResources .add (licenseFile );
382+ copyAdditionalResources (additionalResources , appFolder );
383+
373384 // check if JRE should be embedded
374385 if (bundleJre ) {
375386 getLog ().info ("Bundling JRE" );
@@ -390,12 +401,49 @@ private void createWindowsExecutable() throws MojoExecutionException {
390401 File libsFolder = new File (appFolder , "libs" );
391402 copyAllDependencies (libsFolder );
392403
404+ // copy additional resources
405+ if (licenseFile != null ) additionalResources .add (licenseFile );
406+ copyAdditionalResources (additionalResources , appFolder );
407+
393408 // check if JRE should be embedded
394409 if (bundleJre ) {
395410 getLog ().info ("Bundling JRE" );
396411 File jreFolder = new File (appFolder , "jre" );
397412 createCustomizedJre (jreFolder , libsFolder );
398413 }
414+
415+ // prepare launch4j plugin configuration
416+
417+ List <Element > config = new ArrayList <>();
418+
419+ config .add (element ("headerType" , "gui" ));
420+ config .add (element ("jar" , jarFile .getAbsolutePath ()));
421+ config .add (element ("outfile" , executable .getAbsolutePath () + ".exe" ));
422+ config .add (element ("icon" , iconFile .getAbsolutePath ()));
423+ config .add (element ("manifest" , manifestFile .getAbsolutePath ()));
424+ config .add (element ("classPath" , element ("mainClass" , mainClass )));
425+
426+ if (bundleJre ) {
427+ config .add (element ("jre" ,
428+ element ("path" , "jre" )
429+ ));
430+ } else {
431+ config .add (element ("jre" ,
432+ element ("path" , "%JAVA_HOME%" )
433+ ));
434+ }
435+
436+ config .add (element ("versionInfo" ,
437+ element ("fileVersion" , "1.0.0.0" ),
438+ element ("txtFileVersion" , "1.0.0.0" ),
439+ element ("copyright" , "${project.organization.name}" ),
440+ element ("fileDescription" , "${project.description}" ),
441+ element ("productVersion" , "${project.version}.0" ),
442+ element ("txtProductVersion" , "${project.version}.0" ),
443+ element ("productName" , "${project.name}" ),
444+ element ("internalName" , "${project.name}" ),
445+ element ("originalFilename" , "${project.name}.exe" )
446+ ));
399447
400448 // invoke launch4j plugin to generate windows executable
401449 executeMojo (
@@ -405,33 +453,7 @@ private void createWindowsExecutable() throws MojoExecutionException {
405453 version ("1.7.25" )
406454 ),
407455 goal ("launch4j" ),
408- configuration (
409- element ("headerType" , "gui" ),
410- element ("jar" , jarFile .getAbsolutePath ()),
411- element ("outfile" , executable .getAbsolutePath () + ".exe" ),
412- element ("icon" , iconFile .getAbsolutePath ()),
413- element ("manifest" , manifestFile .getAbsolutePath ()),
414- element ("classPath" ,
415- element ("mainClass" , mainClass )
416- ),
417- element ("jre" ,
418- element ("bundledJre64Bit" , bundleJre .toString ()),
419- element ("minVersion" , jreMinVersion ),
420- element ("runtimeBits" , "64" ),
421- element ("path" , "jre" )
422- ),
423- element ("versionInfo" ,
424- element ("fileVersion" , "1.0.0.0" ),
425- element ("txtFileVersion" , "1.0.0.0" ),
426- element ("copyright" , "${project.organization.name}" ),
427- element ("fileDescription" , "${project.description}" ),
428- element ("productVersion" , "${project.version}.0" ),
429- element ("txtProductVersion" , "${project.version}.0" ),
430- element ("productName" , "${project.name}" ),
431- element ("internalName" , "${project.name}" ),
432- element ("originalFilename" , "${project.name}.exe" )
433- )
434- ),
456+ configuration (config .toArray (new Element [config .size ()])),
435457 env );
436458 }
437459
@@ -561,20 +583,30 @@ private void createCustomizedJre(File jreFolder, File libsFolder) throws MojoExe
561583 String modules ;
562584
563585 // warn and generate a non optimized JRE
564- if (JavaUtils .getJavaMajorVersion () <= 12 ) {
586+ if (JavaUtils .getJavaMajorVersion () <= 12 && ! forceJreOptimization ) {
565587
566588 getLog ().warn ("We need JDK 12+ for correctly determining the dependencies. You run " + System .getProperty ("java.home" ));
567589 getLog ().warn ("All modules will be included in the generated JRE." );
568590
569591 modules = "ALL-MODULE-PATH" ;
570592
571593 } else { // generate an optimized JRE, including only required modules
594+
595+ if (forceJreOptimization ) {
596+ getLog ().warn ("JRE optimization has been forced. It can cause issues with some JDKs." );
597+ }
572598
573599 File jdeps = new File (System .getProperty ("java.home" ), "/bin/jdeps" );
574600
575601 // determine required modules for libs and app jar
576602 modules = "java.scripting,jdk.unsupported," ; // add required modules by default
577- modules += ProcessUtils .execute (jdeps .getAbsolutePath (), "-q" , "--ignore-missing-deps" , "--print-module-deps" , "--class-path" , new File (libsFolder , "*" ), jarFile );
603+
604+ Object [] additionalArguments = {};
605+ if (JavaUtils .getJavaMajorVersion () > 12 ) {
606+ additionalArguments = new Object [] { "--ignore-missing-deps" };
607+ }
608+
609+ modules += ProcessUtils .execute (jdeps .getAbsolutePath (), "-q" , additionalArguments , "--print-module-deps" , "--class-path" , new File (libsFolder , "*" ), jarFile );
578610
579611 }
580612
@@ -592,5 +624,24 @@ private void createCustomizedJre(File jreFolder, File libsFolder) throws MojoExe
592624 Arrays .asList (binFolder .listFiles ()).forEach (f -> f .setExecutable (true , false ));
593625
594626 }
627+
628+ private void copyAdditionalResources (List <File > resources , File destination ) {
629+ getLog ().info ("Copying additional resources" );
630+ resources .stream ().forEach (r -> {
631+ if (!r .exists ()) {
632+ getLog ().warn ("Additional resource " + r + " doesn't exist" );
633+ return ;
634+ }
635+ try {
636+ if (r .isDirectory ()) {
637+ FileUtils .copyFolderToFolder (r , destination );
638+ } else if (r .isFile ()) {
639+ FileUtils .copyFileToFolder (r , destination );
640+ }
641+ } catch (MojoExecutionException e ) {
642+ e .printStackTrace ();
643+ }
644+ });
645+ }
595646
596647}
0 commit comments