|
17 | 17 | import java.util.Set; |
18 | 18 |
|
19 | 19 | import org.apache.maven.artifact.Artifact; |
20 | | -import org.apache.maven.artifact.factory.ArtifactFactory; |
21 | 20 | import org.apache.maven.plugin.MojoExecutionException; |
22 | 21 | import org.apache.maven.plugin.MojoFailureException; |
23 | 22 | import org.apache.maven.plugins.annotations.Component; |
|
28 | 27 | import org.apache.maven.project.ProjectBuilder; |
29 | 28 | import org.apache.maven.project.ProjectBuildingRequest; |
30 | 29 | import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult; |
31 | | -import org.apache.maven.shared.transfer.dependencies.DefaultDependableCoordinate; |
32 | 30 | import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver; |
33 | 31 |
|
| 32 | +import javax.script.ScriptEngine; |
| 33 | +import javax.script.ScriptEngineManager; |
| 34 | +import javax.script.ScriptException; |
| 35 | + |
34 | 36 | /** |
35 | 37 | * Executes the supplied java class in the current VM with the enclosing project's dependencies as classpath. |
36 | 38 | * |
@@ -173,6 +175,33 @@ public class ExecJavaMojo |
173 | 175 | @Deprecated |
174 | 176 | private long killAfter; |
175 | 177 |
|
| 178 | + /** |
| 179 | + * If set to true the Java class executes asynchronously and build execution continues in parallel. |
| 180 | + */ |
| 181 | + @Parameter( property = "exec.async", defaultValue = "false" ) |
| 182 | + private boolean async; |
| 183 | + |
| 184 | + /** |
| 185 | + * Sets the script code to check if the Java class is successfully started. |
| 186 | + */ |
| 187 | + @Parameter( property = "exec.asyncStartCheck") |
| 188 | + private String asyncStartCheck; |
| 189 | + |
| 190 | + /** |
| 191 | + * Sets the script language to evaluate the {@link #asyncStartCheck}. |
| 192 | + * <p> |
| 193 | + * It is possible to add new plugin dependencies of script libraries supporting JSR-223. |
| 194 | + * </p> |
| 195 | + */ |
| 196 | + @Parameter( property = "exec.asyncStartCheckScriptLanguage", defaultValue = "JavaScript") |
| 197 | + private String asyncStartCheckScriptLanguage; |
| 198 | + |
| 199 | + /** |
| 200 | + * Sets the poll interval in ms to evaluate the {@link #asyncStartCheck}. |
| 201 | + */ |
| 202 | + @Parameter( property = "exec.asyncStartCheckPollInterval", defaultValue = "1000") |
| 203 | + private int asyncStartCheckPollInterval; |
| 204 | + |
176 | 205 | private Properties originalSystemProperties; |
177 | 206 |
|
178 | 207 | /** |
@@ -224,7 +253,7 @@ public void execute() |
224 | 253 | getLog().debug( msg ); |
225 | 254 | } |
226 | 255 |
|
227 | | - IsolatedThreadGroup threadGroup = new IsolatedThreadGroup( mainClass /* name */ ); |
| 256 | + final IsolatedThreadGroup threadGroup = new IsolatedThreadGroup( mainClass /* name */ ); |
228 | 257 | Thread bootstrapThread = new Thread( threadGroup, new Runnable() |
229 | 258 | { |
230 | 259 | public void run() |
@@ -274,45 +303,79 @@ public void run() |
274 | 303 | setSystemProperties(); |
275 | 304 |
|
276 | 305 | bootstrapThread.start(); |
277 | | - joinNonDaemonThreads( threadGroup ); |
278 | | - // It's plausible that spontaneously a non-daemon thread might be created as we try and shut down, |
279 | | - // but it's too late since the termination condition (only daemon threads) has been triggered. |
280 | | - if ( keepAlive ) |
281 | | - { |
282 | | - getLog().warn( "Warning: keepAlive is now deprecated and obsolete. Do you need it? Please comment on MEXEC-6." ); |
283 | | - waitFor( 0 ); |
| 306 | + if (!async) { |
| 307 | + terminate(threadGroup); |
284 | 308 | } |
| 309 | + else { |
| 310 | + if (asyncStartCheck != null) { |
| 311 | + // wait until condition to know that java thread has started |
| 312 | + ScriptEngineManager factory = new ScriptEngineManager(); |
| 313 | + // create a JavaScript engine |
| 314 | + ScriptEngine engine = factory.getEngineByName(asyncStartCheckScriptLanguage); |
| 315 | + if (engine == null) { |
| 316 | + throw new MojoExecutionException("Couldn't find engine for script language "+asyncStartCheckScriptLanguage); |
| 317 | + } |
| 318 | + // evaluate JavaScript code from String |
| 319 | + while (true) { |
| 320 | + try { |
| 321 | + Thread.sleep(asyncStartCheckPollInterval); |
| 322 | + } catch (InterruptedException e) { |
| 323 | + throw new MojoExecutionException("Couldn't not sleep for poll interval.", e); |
| 324 | + } |
| 325 | + try { |
| 326 | + if ((Boolean) engine.eval(asyncStartCheck)) { |
| 327 | + getLog().info("Java class is ready."); |
| 328 | + break; |
| 329 | + } |
| 330 | + else { |
| 331 | + getLog().info("Java class is not yet ready. Waiting ..."); |
| 332 | + } |
| 333 | + } catch (ScriptException e) { |
| 334 | + throw new MojoExecutionException("Couldn't evaluate start check expression.", e); |
| 335 | + } |
| 336 | + } |
| 337 | + Runtime.getRuntime().addShutdownHook(new Thread() |
| 338 | + { |
| 339 | + public void run() |
| 340 | + { |
| 341 | + try { |
| 342 | + terminate(threadGroup); |
| 343 | + } catch (MojoExecutionException e) { |
| 344 | + getLog().error(e); |
| 345 | + } |
| 346 | + } |
| 347 | + }); |
| 348 | + } |
| 349 | + } |
| 350 | + registerSourceRoots(); |
| 351 | + } |
285 | 352 |
|
286 | | - if ( cleanupDaemonThreads ) |
287 | | - { |
| 353 | + private void terminate(IsolatedThreadGroup threadGroup) throws MojoExecutionException { |
| 354 | + joinNonDaemonThreads(threadGroup); |
288 | 355 |
|
289 | | - terminateThreads( threadGroup ); |
| 356 | + if (cleanupDaemonThreads) { |
290 | 357 |
|
291 | | - try |
292 | | - { |
293 | | - threadGroup.destroy(); |
294 | | - } |
295 | | - catch ( IllegalThreadStateException e ) |
296 | | - { |
297 | | - getLog().warn( "Couldn't destroy threadgroup " + threadGroup, e ); |
| 358 | + terminateThreads(threadGroup); |
| 359 | + |
| 360 | + try { |
| 361 | + if (!threadGroup.isDestroyed()) { |
| 362 | + threadGroup.destroy(); |
| 363 | + } |
| 364 | + } catch (IllegalThreadStateException e) { |
| 365 | + getLog().warn("Couldn't destroy threadgroup " + threadGroup, e); |
298 | 366 | } |
299 | 367 | } |
300 | 368 |
|
301 | | - if ( originalSystemProperties != null ) |
302 | | - { |
303 | | - System.setProperties( originalSystemProperties ); |
| 369 | + if (originalSystemProperties != null) { |
| 370 | + System.setProperties(originalSystemProperties); |
304 | 371 | } |
305 | 372 |
|
306 | | - synchronized ( threadGroup ) |
307 | | - { |
308 | | - if ( threadGroup.uncaughtException != null ) |
309 | | - { |
310 | | - throw new MojoExecutionException( "An exception occured while executing the Java class. " |
311 | | - + threadGroup.uncaughtException.getMessage(), threadGroup.uncaughtException ); |
| 373 | + synchronized (threadGroup) { |
| 374 | + if (threadGroup.uncaughtException != null) { |
| 375 | + throw new MojoExecutionException("An exception occurred while executing the Java class. " |
| 376 | + + threadGroup.uncaughtException.getMessage(), threadGroup.uncaughtException); |
312 | 377 | } |
313 | 378 | } |
314 | | - |
315 | | - registerSourceRoots(); |
316 | 379 | } |
317 | 380 |
|
318 | 381 | /** |
|
0 commit comments