Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

preload common pool - issue #198 #279

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions pom.xml
Expand Up @@ -262,6 +262,7 @@
</signature>
<ignores>
<ignore>java.lang.invoke.MethodHandle</ignore>
<ignore>java.util.concurrent.ForkJoinPool</ignore>
</ignores>
</configuration>
</plugin>
Expand Down
56 changes: 56 additions & 0 deletions src/main/java/org/codehaus/mojo/exec/ExecJavaMojo.java
Expand Up @@ -16,6 +16,9 @@
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ForkJoinPool;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
Expand Down Expand Up @@ -68,6 +71,18 @@ public class ExecJavaMojo
@Parameter( required = true, property = "exec.mainClass" )
private String mainClass;


/**
* Forces the creation of fork join common pool to avoids the threads to be owned by the isolated thread group
* and prevent a proper shutdown.
* If set to zero the default parallelism is used to precreate all threads,
* if negative it is ignored else the value is the one used to create the fork join threads.
*
* @since 3.0.1
*/
@Parameter( property = "exec.preloadCommonPool", defaultValue = "0" )
private int preloadCommonPool;

/**
* The class arguments.
*
Expand Down Expand Up @@ -234,6 +249,11 @@ public void execute()
getLog().debug( msg );
}

if ( preloadCommonPool >= 0 )
{
preloadCommonPool();
}

IsolatedThreadGroup threadGroup = new IsolatedThreadGroup( mainClass /* name */ );
Thread bootstrapThread = new Thread( threadGroup, new Runnable()
{
Expand Down Expand Up @@ -338,6 +358,42 @@ public void run()
registerSourceRoots();
}

/**
* To avoid the exec:java to consider common pool threads leaked, let's pre-create them.
*/
private void preloadCommonPool()
{
try
{
// ensure common pool exists in the jvm
final ExecutorService es = ForkJoinPool.commonPool();
final int max = preloadCommonPool > 0
? preloadCommonPool :
ForkJoinPool.getCommonPoolParallelism();
final CountDownLatch preLoad = new CountDownLatch( 1 );
for ( int i = 0;
i < max;
i++ )
{
es.submit(() -> {
try
{
preLoad.await();
}
catch ( InterruptedException e )
{
Thread.currentThread().interrupt();
}
});
}
preLoad.countDown();
}
catch (final Exception e)
{
getLog().debug(e.getMessage() + ", skipping commonpool earger init");
}
}

/**
* a ThreadGroup to isolate execution and collect exceptions.
*/
Expand Down