55 * License, v. 2.0. If a copy of the MPL was not distributed with this
66 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
77 */
8+
89package org .seedstack .maven ;
910
1011import edu .umd .cs .findbugs .annotations .SuppressFBWarnings ;
11- import org .apache .maven .artifact .Artifact ;
12- import org .apache .maven .model .Resource ;
13- import org .apache .maven .plugin .AbstractMojo ;
14- import org .apache .maven .plugin .MojoExecutionException ;
15- import org .apache .maven .plugin .MojoFailureException ;
16- import org .apache .maven .plugins .annotations .Parameter ;
17- import org .apache .maven .project .MavenProject ;
18- import org .codehaus .plexus .util .cli .CommandLineUtils ;
19-
2012import java .io .File ;
2113import java .net .MalformedURLException ;
2214import java .net .URL ;
2315import java .net .URLClassLoader ;
16+ import java .security .AccessController ;
17+ import java .security .PrivilegedAction ;
2418import java .util .ArrayList ;
2519import java .util .Collection ;
2620import java .util .List ;
21+ import org .apache .maven .artifact .Artifact ;
22+ import org .apache .maven .execution .MavenSession ;
23+ import org .apache .maven .model .Resource ;
24+ import org .apache .maven .plugin .BuildPluginManager ;
25+ import org .apache .maven .plugin .MojoExecutionException ;
26+ import org .apache .maven .plugin .MojoFailureException ;
27+ import org .apache .maven .plugins .annotations .Component ;
28+ import org .apache .maven .plugins .annotations .Parameter ;
29+ import org .apache .maven .project .MavenProject ;
30+ import org .codehaus .plexus .util .cli .CommandLineUtils ;
2731
2832/**
2933 * Provides a common base for mojos that run SeedStack applications.
3034 */
31- public class AbstractExecutableMojo extends AbstractSeedStackMojo {
32-
35+ public abstract class AbstractExecutableMojo extends AbstractSeedStackMojo {
3336 @ Parameter (defaultValue = "${project}" , required = true , readonly = true )
3437 private MavenProject project ;
35-
38+ @ Parameter (defaultValue = "${session}" , required = true , readonly = true )
39+ private MavenSession mavenSession ;
40+ @ Component
41+ private BuildPluginManager buildPluginManager ;
3642 @ Parameter (defaultValue = "${project.build.outputDirectory}" , required = true )
3743 private File classesDirectory ;
38-
3944 @ Parameter (defaultValue = "${project.build.testOutputDirectory}" , required = true )
4045 private File testClassesDirectory ;
41-
4246 @ Parameter (property = "args" )
4347 private String args ;
44-
4548 private final IsolatedThreadGroup isolatedThreadGroup = new IsolatedThreadGroup ("seed-app" );
46-
4749 private final Object monitor = new Object ();
4850
49- private boolean testMode = false ;
50-
51- protected Runnable runnable ;
52-
53- @ Override
54- @ SuppressFBWarnings (value = {"UW_UNCOND_WAIT" , "WA_NOT_IN_LOOP" }, justification = "Cannot know when the application is started" )
55- public void execute () throws MojoExecutionException , MojoFailureException {
56- // Create an isolated thread
57- Thread bootstrapThread = new Thread (isolatedThreadGroup , runnable , "main" );
58- File [] classPathFiles = getClassPathFiles ();
51+ @ SuppressFBWarnings (value = {"UW_UNCOND_WAIT" , "WA_NOT_IN_LOOP" }, justification = "Cannot know when the "
52+ + "application is started" )
53+ protected void execute (Runnable runnable , boolean testMode ) throws MojoExecutionException , MojoFailureException {
54+ File [] classPathFiles = getClassPathFiles (testMode );
5955
6056 // Set the system property for proper detection of classpath
6157 System .setProperty ("java.class.path" , buildCpProperty (classPathFiles ));
6258
6359 // Start the launcher thread
64- bootstrapThread .setContextClassLoader (buildClassLoader (classPathFiles ));
60+ ClassLoader classLoader = buildClassLoader (classPathFiles );
61+
62+ // Create an isolated thread
63+ Thread bootstrapThread = new Thread (isolatedThreadGroup , runnable , "main" );
64+ bootstrapThread .setContextClassLoader (classLoader );
6565 bootstrapThread .start ();
6666
6767 // Wait for the application to launch
@@ -76,12 +76,50 @@ public void execute() throws MojoExecutionException, MojoFailureException {
7676 // Check for any uncaught exception
7777 synchronized (isolatedThreadGroup ) {
7878 if (isolatedThreadGroup .uncaughtException != null ) {
79- throw new MojoExecutionException ("An exception occurred while executing Seed" , isolatedThreadGroup .uncaughtException );
79+ throw new MojoExecutionException ("An exception occurred while executing Seed" ,
80+ isolatedThreadGroup .uncaughtException );
8081 }
8182 }
83+ }
84+
85+ MavenSession getMavenSession () {
86+ return mavenSession ;
87+ }
8288
83- // Join the application non-daemon threads
84- joinNonDaemonThreads (isolatedThreadGroup );
89+ BuildPluginManager getBuildPluginManager () {
90+ return buildPluginManager ;
91+ }
92+
93+ MavenProject getProject () {
94+ return project ;
95+ }
96+
97+ File getClassesDirectory () {
98+ return classesDirectory ;
99+ }
100+
101+ File getTestClassesDirectory () {
102+ return testClassesDirectory ;
103+ }
104+
105+ Object getMonitor () {
106+ return monitor ;
107+ }
108+
109+ String [] getArgs () throws MojoExecutionException {
110+ try {
111+ return CommandLineUtils .translateCommandline (args );
112+ } catch (Exception e ) {
113+ throw new MojoExecutionException ("Failed to parse arguments" , e );
114+ }
115+ }
116+
117+ URLClassLoader getClassLoader (final URL [] classPathUrls ) {
118+ return AccessController .doPrivileged (new PrivilegedAction <URLClassLoader >() {
119+ public URLClassLoader run () {
120+ return new URLClassLoader (classPathUrls );
121+ }
122+ });
85123 }
86124
87125 private ClassLoader buildClassLoader (File [] classPathFiles ) throws MojoExecutionException {
@@ -93,7 +131,7 @@ private ClassLoader buildClassLoader(File[] classPathFiles) throws MojoExecution
93131 throw new MojoExecutionException ("Unable to create URL from " + classPathFiles [i ]);
94132 }
95133 }
96- return new URLClassLoader (classPathUrls );
134+ return getClassLoader (classPathUrls );
97135 }
98136
99137 private String buildCpProperty (File [] classPathFiles ) {
@@ -108,29 +146,13 @@ private String buildCpProperty(File[] classPathFiles) {
108146 return stringBuilder .toString ();
109147 }
110148
111- protected void enableTestMode () {
112- this .testMode = true ;
113- }
114-
115- protected Object getMonitor () {
116- return monitor ;
117- }
118-
119- public String [] getArgs () throws MojoExecutionException {
120- try {
121- return CommandLineUtils .translateCommandline (args );
122- } catch (Exception e ) {
123- throw new MojoExecutionException ("Failed to parse arguments" , e );
124- }
125- }
126-
127- private void joinNonDaemonThreads (ThreadGroup threadGroup ) {
149+ void waitForShutdown () {
128150 boolean found = true ;
129151
130152 while (found ) {
131153 found = false ;
132154
133- for (Thread groupThread : getGroupThreads (threadGroup )) {
155+ for (Thread groupThread : getGroupThreads (isolatedThreadGroup )) {
134156 if (!groupThread .isDaemon ()) {
135157 found = true ;
136158
@@ -158,7 +180,7 @@ private Thread[] getGroupThreads(final ThreadGroup group) {
158180 return java .util .Arrays .copyOf (threads , n );
159181 }
160182
161- private File [] getClassPathFiles () throws MojoExecutionException {
183+ private File [] getClassPathFiles (boolean testMode ) throws MojoExecutionException {
162184 List <File > files = new ArrayList <>();
163185
164186 try {
@@ -194,7 +216,8 @@ private void addArtifacts(Collection<Artifact> artifacts, List<File> files) thro
194216 }
195217 }
196218
197- private void addResources (File classesDirectory , List <Resource > resources , List <File > files ) throws MalformedURLException {
219+ private void addResources (File classesDirectory , List <Resource > resources ,
220+ List <File > files ) throws MalformedURLException {
198221 for (Resource resource : resources ) {
199222 File directory = new File (resource .getDirectory ());
200223 files .add (directory );
0 commit comments