Author: bentmann Date: Sun Jul 25 12:05:32 2010 New Revision: 979028 URL: http://svn.apache.org/viewvc?rev=979028&view=rev Log: [MNG-4738] DefaultArtifactResolver forks non-daemon threads Submitted by: Benjamin Hanzelmann
Modified: maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java maven/maven-3/trunk/maven-compat/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactResolverTest.java Modified: maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java?rev=979028&r1=979027&r2=979028&view=diff ============================================================================== --- maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java (original) +++ maven/maven-3/trunk/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java Sun Jul 25 12:05:32 2010 @@ -32,8 +32,10 @@ import java.util.concurrent.CountDownLat import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.factory.ArtifactFactory; @@ -125,7 +127,7 @@ public class DefaultArtifactResolver else { executor = - new ThreadPoolExecutor( threads, threads, 3, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>() ); + new ThreadPoolExecutor( threads, threads, 3, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new DaemonThreadCreator()); } } @@ -687,6 +689,26 @@ public class DefaultArtifactResolver resolve( artifact, remoteRepositories, localRepository, null ); } + /** + * ThreadCreator for creating daemon threads with fixed ThreadGroup-name. + */ + final static class DaemonThreadCreator + implements ThreadFactory + { + static final String THREADGROUP_NAME = "org.apache.maven.artifact.resolver.DefaultArtifactResolver"; + + final static ThreadGroup group = new ThreadGroup( THREADGROUP_NAME ); + + final static AtomicInteger threadNumber = new AtomicInteger( 1 ); + + public Thread newThread( Runnable r ) + { + Thread newThread = new Thread( group, r, "resolver-" + threadNumber.getAndIncrement() ); + newThread.setDaemon( true ); + return newThread; + } + } + private class ResolveTask implements Runnable { Modified: maven/maven-3/trunk/maven-compat/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactResolverTest.java URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-compat/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactResolverTest.java?rev=979028&r1=979027&r2=979028&view=diff ============================================================================== --- maven/maven-3/trunk/maven-compat/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactResolverTest.java (original) +++ maven/maven-3/trunk/maven-compat/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactResolverTest.java Sun Jul 25 12:05:32 2010 @@ -1,10 +1,88 @@ package org.apache.maven.artifact.resolver; -import org.codehaus.plexus.PlexusTestCase; +import java.util.Collections; + +import org.apache.maven.artifact.AbstractArtifactComponentTestCase; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.resolver.DefaultArtifactResolver.DaemonThreadCreator; public class DefaultArtifactResolverTest - extends PlexusTestCase + extends AbstractArtifactComponentTestCase { + private DefaultArtifactResolver artifactResolver; + + private Artifact projectArtifact; + + @Override + protected void setUp() + throws Exception + { + super.setUp(); + + artifactResolver = (DefaultArtifactResolver) lookup( ArtifactResolver.class ); + + projectArtifact = createLocalArtifact( "project", "3.0" ); + } + + @Override + protected void tearDown() + throws Exception + { + artifactFactory = null; + projectArtifact = null; + super.tearDown(); + } + + @Override + protected String component() + { + return "resolver"; + } + + public void testMNG4738() + throws Exception + { + Artifact g = createLocalArtifact( "g", "1.0" ); + createLocalArtifact( "h", "1.0" ); + artifactResolver.resolveTransitively( Collections.singleton( g ), projectArtifact, remoteRepositories(), + localRepository(), null ); + + // we want to see all top-level thread groups + ThreadGroup tg = Thread.currentThread().getThreadGroup(); + while ( !( tg.getParent() != null ) ) + { + tg = tg.getParent(); + } + + ThreadGroup[] tgList = new ThreadGroup[tg.activeGroupCount()]; + tg.enumerate( tgList ); + + boolean seen = false; + + for ( int i = 0; i < tgList.length; i++ ) + { + if ( !tgList[i].getName().equals( DaemonThreadCreator.THREADGROUP_NAME ) ) + { + continue; + } + + seen = true; + + tg = tgList[i]; + Thread[] ts = new Thread[tg.activeCount()]; + tg.enumerate( ts ); + + for ( Thread active : ts ) + { + String name = active.getName(); + boolean daemon = active.isDaemon(); + assertTrue( name + " is no daemon Thread.", daemon ); + } + + } + + assertTrue( "Could not find ThreadGroup: " + DaemonThreadCreator.THREADGROUP_NAME, seen ); + } public void testLookup() throws Exception