You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by jv...@apache.org on 2014/02/06 22:44:03 UTC
[1/2] git commit: Remove weave mode building from the core
Updated Branches:
refs/heads/master ccc7cb3ab -> 097cc8d25
Remove weave mode building from the core
Project: http://git-wip-us.apache.org/repos/asf/maven/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven/commit/0c5678fa
Tree: http://git-wip-us.apache.org/repos/asf/maven/tree/0c5678fa
Diff: http://git-wip-us.apache.org/repos/asf/maven/diff/0c5678fa
Branch: refs/heads/master
Commit: 0c5678fa89485bbfa64746c5378100cf2bef2113
Parents: ccc7cb3
Author: Jason van Zyl <ja...@tesla.io>
Authored: Thu Feb 6 16:27:15 2014 -0500
Committer: Jason van Zyl <ja...@tesla.io>
Committed: Thu Feb 6 16:27:15 2014 -0500
----------------------------------------------------------------------
.../internal/builder/weave/BuildLogItem.java | 221 --------
.../builder/weave/ConcurrentBuildLogger.java | 124 -----
.../builder/weave/CurrentPhaseForThread.java | 44 --
.../builder/weave/ThreadLockedArtifact.java | 320 ------------
.../internal/builder/weave/WeaveBuilder.java | 521 -------------------
.../internal/ConcurrentBuildLoggerTest.java | 77 ---
.../internal/LifecycleWeaveBuilderTest.java | 142 -----
.../java/org/apache/maven/cli/MavenCli.java | 9 +-
8 files changed, 1 insertion(+), 1457 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/maven/blob/0c5678fa/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/BuildLogItem.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/BuildLogItem.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/BuildLogItem.java
deleted file mode 100644
index 9b5b321..0000000
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/BuildLogItem.java
+++ /dev/null
@@ -1,221 +0,0 @@
-package org.apache.maven.lifecycle.internal.builder.weave;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import org.apache.maven.lifecycle.internal.ExecutionPlanItem;
-import org.apache.maven.project.MavenProject;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * @since 3.0
- * @author Kristian Rosenvold
- * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
- */
-public class BuildLogItem
-{
- private final ExecutionPlanItem executionPlanItem;
-
- private final MavenProject project;
-
- private final long startTime;
-
- private long endTime;
-
- private final List<DependencyLogEntry> dependencies =
- Collections.synchronizedList( new ArrayList<DependencyLogEntry>() );
-
- public BuildLogItem( MavenProject project, ExecutionPlanItem executionPlanItem )
- {
- this.executionPlanItem = executionPlanItem;
- this.project = project;
- startTime = System.currentTimeMillis();
-
- }
-
-
- public MavenProject getProject()
- {
- return project;
- }
-
- public void setComplete()
- {
- endTime = System.currentTimeMillis();
- }
-
- public void addWait( MavenProject upstreamProject, ExecutionPlanItem inSchedule, long startWait )
- {
- long now = System.currentTimeMillis();
- dependencies.add( new DependencyLogEntry( upstreamProject, inSchedule, startWait, now, null ) );
- }
-
- public void addDependency( MavenProject upstreamProject, String message )
- {
- dependencies.add( new DependencyLogEntry( upstreamProject, message ) );
- }
-
- public String toString( long rootStart )
- {
- StringBuilder result = new StringBuilder();
- result.append( String.format( "%1d %2d ", startTime - rootStart, endTime - rootStart ) );
- result.append( project.getName() );
- result.append( " " );
- result.append( getMojoExecutionDescription( executionPlanItem ) );
- if ( dependencies.size() > 0 )
- {
- result.append( "\n" );
- for ( DependencyLogEntry waitLogEntry : dependencies )
- {
- result.append( " " );
- result.append( waitLogEntry.toString() );
- result.append( "\n" );
- }
- }
- return result.toString();
- }
-
-
- public Object toGraph( long rootStart )
- {
- StringBuilder result = new StringBuilder();
- if ( dependencies.size() > 0 )
- {
- for ( DependencyLogEntry waitLogEntry : dependencies )
- {
- result.append( " " );
- result.append( nodeKey( project, executionPlanItem ) );
- result.append( " -> " );
- result.append( waitLogEntry.toNodeKey() );
- result.append( waitLogEntry.toNodeDescription( rootStart ) );
- result.append( "\n" );
- }
- }
- else
- {
- result.append( " " );
- result.append( nodeKey( project, executionPlanItem ) );
- result.append( "\n" );
- }
- return result.toString();
- }
-
- private static String nodeKey( MavenProject mavenProject, ExecutionPlanItem executionPlanItem )
- {
- String key = mavenProject.getArtifactId();
- if ( executionPlanItem != null )
- {
- key += "_" + getMojoExecutionDescription( executionPlanItem );
- }
- return key.replace( ".", "_" ).replace( ":", "_" );
- }
-
- private static String getMojoExecutionDescription( ExecutionPlanItem executionPlanItem )
- {
- if ( executionPlanItem.getMojoExecution() != null )
- {
- return executionPlanItem.getMojoExecution().getArtifactId() + getLifeCyclePhase( executionPlanItem );
- }
- else
- {
- return "";
- }
- }
-
- private static String getLifeCyclePhase( ExecutionPlanItem executionPlanItem )
- {
- return executionPlanItem.getLifecyclePhase() != null ? "[" + executionPlanItem.getLifecyclePhase() + "]" : "";
- }
-
-
- class DependencyLogEntry
- {
- private final ExecutionPlanItem executionPlanItem;
-
- private final MavenProject upstreamProject;
-
- private final Long start;
-
- private final Long stop;
-
- private final String message;
-
- DependencyLogEntry( MavenProject upstreamProject, ExecutionPlanItem executionPlanItem, Long start, Long stop,
- String message )
- {
- this.upstreamProject = upstreamProject;
- this.executionPlanItem = executionPlanItem;
- this.start = start;
- this.stop = stop;
- this.message = message;
- }
-
- DependencyLogEntry( MavenProject upstreamProject, String message )
- {
- this( upstreamProject, null, null, null, message );
- }
-
- public String toString()
- {
- return upstreamProject.getName() + ":" + getExecutionPlanItem() + getElapsed() + getMessage();
- }
-
- public String toNodeKey()
- {
- return nodeKey( upstreamProject, executionPlanItem );
- }
-
- public String toNodeDescription( long rootStart )
- {
- return "";
- }
-
-
- private String getMessage()
- {
- return message != null ? message : "";
- }
-
- private String getExecutionPlanItem()
- {
- if ( executionPlanItem != null )
- {
- return getMojoExecutionDescription( executionPlanItem );
- }
- else
- {
- return "";
- }
- }
-
- private String getElapsed()
- {
- if ( start != null && stop != null )
- {
- long elapsed = stop - start;
- return elapsed > 0 ? ", wait=" + elapsed : "";
- }
- return "";
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/maven/blob/0c5678fa/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/ConcurrentBuildLogger.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/ConcurrentBuildLogger.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/ConcurrentBuildLogger.java
deleted file mode 100644
index 2dcd348..0000000
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/ConcurrentBuildLogger.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package org.apache.maven.lifecycle.internal.builder.weave;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import org.apache.maven.lifecycle.internal.ExecutionPlanItem;
-import org.apache.maven.project.MavenProject;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Handles all concurrency-related logging.
- * <p/>
- * The logging/diagnostic needs of a concurrent build are different from a linear build. This
- * delta required to analyze a concurrent build is located here.
- * <p/>
- * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
- *
- * @since 3.0
- * @author Kristian Rosenvold
- */
-public class ConcurrentBuildLogger
-{
- private final long startTime;
-
- private final Map<MavenProject, Thread> threadMap = new ConcurrentHashMap<MavenProject, Thread>();
-
- public ConcurrentBuildLogger()
- {
- startTime = System.currentTimeMillis();
- }
-
-
- List<BuildLogItem> items = Collections.synchronizedList( new ArrayList<BuildLogItem>() );
-
- public BuildLogItem createBuildLogItem( MavenProject project, ExecutionPlanItem current )
- {
- threadMap.put( project, Thread.currentThread() );
- BuildLogItem result = new BuildLogItem( project, current );
- items.add( result );
- return result;
- }
-
- public String toString()
- {
- StringBuilder result = new StringBuilder();
- for ( Map.Entry<MavenProject, Thread> mavenProjectThreadEntry : threadMap.entrySet() )
- {
- result.append( mavenProjectThreadEntry.getKey().getName() );
- result.append( " ran on " );
- result.append( mavenProjectThreadEntry.getValue().getName() );
- result.append( "\n" );
- }
-
- for ( BuildLogItem builtLogItem : items )
- {
- result.append( builtLogItem.toString( startTime ) );
- result.append( "\n" );
- }
- return result.toString();
- }
-
- public String toGraph()
- {
- StringBuilder result = new StringBuilder();
-
- Map<MavenProject, Collection<BuildLogItem>> multiMap = new HashMap<MavenProject, Collection<BuildLogItem>>();
- for ( BuildLogItem builtLogItem : items )
- {
- MavenProject project = builtLogItem.getProject();
- Collection<BuildLogItem> bag = multiMap.get( project );
- if ( bag == null )
- {
- bag = new ArrayList<BuildLogItem>();
- multiMap.put( project, bag );
- }
- bag.add( builtLogItem );
- }
-
- result.append( "digraph build" );
- result.append( " {\n " );
-
- for ( MavenProject mavenProject : multiMap.keySet() )
- {
- final Collection<BuildLogItem> builtLogItems = multiMap.get( mavenProject );
- result.append( " subgraph " );
- result.append( mavenProject.getArtifactId() );
- result.append( " {\n" );
-
- for ( BuildLogItem builtLogItem : builtLogItems )
- {
- result.append( builtLogItem.toGraph( startTime ) );
- }
-
- result.append( "\n }\n" );
- }
-
- result.append( "\n}\n " );
- return result.toString();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/maven/blob/0c5678fa/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/CurrentPhaseForThread.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/CurrentPhaseForThread.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/CurrentPhaseForThread.java
deleted file mode 100644
index f52f4e0..0000000
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/CurrentPhaseForThread.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.apache.maven.lifecycle.internal.builder.weave;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * Knows the phase the current thread is executing.
- * <p/>
- * This class is used in weave-mode only , there may be better ways of doing this once the dust settles.
- *
- * @since 3.0
- * @author Kristian Rosenvold
- */
-class CurrentPhaseForThread
-{
- private static final InheritableThreadLocal<String> THREAD_PHASE = new InheritableThreadLocal<String>();
-
- public static void setPhase( String phase )
- {
- THREAD_PHASE.set( phase );
- }
-
- public static boolean isPhase( String phase )
- {
- return phase.equals( THREAD_PHASE.get() );
- }
-
-}
http://git-wip-us.apache.org/repos/asf/maven/blob/0c5678fa/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/ThreadLockedArtifact.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/ThreadLockedArtifact.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/ThreadLockedArtifact.java
deleted file mode 100644
index 7a0e117..0000000
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/ThreadLockedArtifact.java
+++ /dev/null
@@ -1,320 +0,0 @@
-package org.apache.maven.lifecycle.internal.builder.weave;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.handler.ArtifactHandler;
-import org.apache.maven.artifact.metadata.ArtifactMetadata;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
-import org.apache.maven.artifact.versioning.ArtifactVersion;
-import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
-import org.apache.maven.artifact.versioning.VersionRange;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-
-/**
- * An artifact that conditionally suspends on getFile for anything but the thread it is locked to.
- *
- * @since 3.0
- */
-class ThreadLockedArtifact
- implements Artifact
-{
- private final Artifact real;
-
- private final CountDownLatch artifactLocked = new CountDownLatch( 1 );
-
- ThreadLockedArtifact( Artifact real )
- {
- this.real = real;
- }
-
- public boolean hasReal()
- {
- return real != null
- && ( !( real instanceof ThreadLockedArtifact ) || ( (ThreadLockedArtifact) real ).hasReal() );
- }
-
- public String getGroupId()
- {
- return real.getGroupId();
- }
-
- public String getArtifactId()
- {
- return real.getArtifactId();
- }
-
- public String getVersion()
- {
- return real.getVersion();
- }
-
- public void setVersion( String version )
- {
- real.setVersion( version );
- }
-
- public String getScope()
- {
- return real.getScope();
- }
-
- public String getType()
- {
- return real.getType();
- }
-
- public String getClassifier()
- {
- return real.getClassifier();
- }
-
- public boolean hasClassifier()
- {
- return real.hasClassifier();
- }
-
- private static final InheritableThreadLocal<ThreadLockedArtifact> THREAD_ARTIFACT =
- new InheritableThreadLocal<ThreadLockedArtifact>();
-
- public void attachToThread()
- {
- THREAD_ARTIFACT.set( this );
- }
-
- public File getFile()
- {
- final ThreadLockedArtifact lockedArtifact = THREAD_ARTIFACT.get();
- if ( lockedArtifact != null && this != lockedArtifact && mustLock() )
- {
- try
- {
- artifactLocked.await();
- }
- catch ( InterruptedException e )
- {
- // Ignore and go on to real.getFile();
- }
- }
- return real.getFile();
- }
-
- private boolean mustLock()
- {
- boolean dontNeedLock = CurrentPhaseForThread.isPhase( "compile" ) || CurrentPhaseForThread.isPhase( "test" );
- return !dontNeedLock;
- }
-
- public void setFile( File destination )
- {
- if ( destination != null && destination.exists() && destination.isFile() )
- {
- artifactLocked.countDown();
- }
- real.setFile( destination );
- }
-
- public String getBaseVersion()
- {
- return real.getBaseVersion();
- }
-
- public void setBaseVersion( String baseVersion )
- {
- real.setBaseVersion( baseVersion );
- }
-
- public String getId()
- {
- return real.getId();
- }
-
- public String getDependencyConflictId()
- {
- return real.getDependencyConflictId();
- }
-
- public void addMetadata( ArtifactMetadata metadata )
- {
- real.addMetadata( metadata );
- }
-
- public Collection<ArtifactMetadata> getMetadataList()
- {
- return real.getMetadataList();
- }
-
- public void setRepository( ArtifactRepository remoteRepository )
- {
- real.setRepository( remoteRepository );
- }
-
- public ArtifactRepository getRepository()
- {
- return real.getRepository();
- }
-
- public void updateVersion( String version, ArtifactRepository localRepository )
- {
- real.updateVersion( version, localRepository );
- }
-
- public String getDownloadUrl()
- {
- return real.getDownloadUrl();
- }
-
- public void setDownloadUrl( String downloadUrl )
- {
- real.setDownloadUrl( downloadUrl );
- }
-
- public ArtifactFilter getDependencyFilter()
- {
- return real.getDependencyFilter();
- }
-
- public void setDependencyFilter( ArtifactFilter artifactFilter )
- {
- real.setDependencyFilter( artifactFilter );
- }
-
- public ArtifactHandler getArtifactHandler()
- {
- return real.getArtifactHandler();
- }
-
- public List<String> getDependencyTrail()
- {
- return real.getDependencyTrail();
- }
-
- public void setDependencyTrail( List<String> dependencyTrail )
- {
- real.setDependencyTrail( dependencyTrail );
- }
-
- public void setScope( String scope )
- {
- real.setScope( scope );
- }
-
- public VersionRange getVersionRange()
- {
- return real.getVersionRange();
- }
-
- public void setVersionRange( VersionRange newRange )
- {
- real.setVersionRange( newRange );
- }
-
- public void selectVersion( String version )
- {
- real.selectVersion( version );
- }
-
- public void setGroupId( String groupId )
- {
- real.setGroupId( groupId );
- }
-
- public void setArtifactId( String artifactId )
- {
- real.setArtifactId( artifactId );
- }
-
- public boolean isSnapshot()
- {
- return real.isSnapshot();
- }
-
- public void setResolved( boolean resolved )
- {
- real.setResolved( resolved );
- }
-
- public boolean isResolved()
- {
- return real.isResolved();
- }
-
- public void setResolvedVersion( String version )
- {
- real.setResolvedVersion( version );
- }
-
- public void setArtifactHandler( ArtifactHandler handler )
- {
- real.setArtifactHandler( handler );
- }
-
- public boolean isRelease()
- {
- return real.isRelease();
- }
-
- public void setRelease( boolean release )
- {
- real.setRelease( release );
- }
-
- public List<ArtifactVersion> getAvailableVersions()
- {
- return real.getAvailableVersions();
- }
-
- public void setAvailableVersions( List<ArtifactVersion> versions )
- {
- real.setAvailableVersions( versions );
- }
-
- public boolean isOptional()
- {
- return real.isOptional();
- }
-
- public void setOptional( boolean optional )
- {
- real.setOptional( optional );
- }
-
- public ArtifactVersion getSelectedVersion()
- throws OverConstrainedVersionException
- {
- return real.getSelectedVersion();
- }
-
- public boolean isSelectedVersionKnown()
- throws OverConstrainedVersionException
- {
- return real.isSelectedVersionKnown();
- }
-
- public int compareTo( Artifact o )
- {
- return real.compareTo( o );
- }
-}
http://git-wip-us.apache.org/repos/asf/maven/blob/0c5678fa/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/WeaveBuilder.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/WeaveBuilder.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/WeaveBuilder.java
deleted file mode 100644
index 193eca6..0000000
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/weave/WeaveBuilder.java
+++ /dev/null
@@ -1,521 +0,0 @@
-package org.apache.maven.lifecycle.internal.builder.weave;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.ArtifactUtils;
-import org.apache.maven.execution.BuildSuccess;
-import org.apache.maven.execution.ExecutionEvent;
-import org.apache.maven.execution.MavenExecutionRequest;
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.lifecycle.LifecycleExecutionException;
-import org.apache.maven.lifecycle.MavenExecutionPlan;
-import org.apache.maven.lifecycle.Schedule;
-import org.apache.maven.lifecycle.internal.BuildThreadFactory;
-import org.apache.maven.lifecycle.internal.DependencyContext;
-import org.apache.maven.lifecycle.internal.ExecutionEventCatapult;
-import org.apache.maven.lifecycle.internal.ExecutionPlanItem;
-import org.apache.maven.lifecycle.internal.LifecycleDebugLogger;
-import org.apache.maven.lifecycle.internal.MojoExecutor;
-import org.apache.maven.lifecycle.internal.PhaseRecorder;
-import org.apache.maven.lifecycle.internal.ProjectBuildList;
-import org.apache.maven.lifecycle.internal.ProjectSegment;
-import org.apache.maven.lifecycle.internal.ReactorBuildStatus;
-import org.apache.maven.lifecycle.internal.ReactorContext;
-import org.apache.maven.lifecycle.internal.TaskSegment;
-import org.apache.maven.lifecycle.internal.builder.Builder;
-import org.apache.maven.lifecycle.internal.builder.BuilderCommon;
-import org.apache.maven.project.MavenProject;
-import org.codehaus.plexus.component.annotations.Component;
-import org.codehaus.plexus.component.annotations.Requirement;
-import org.codehaus.plexus.logging.Logger;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CompletionService;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorCompletionService;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Builds the full lifecycle in weave-mode (phase by phase as opposed to project-by-project)
- * <p/>
- * NOTE: Weave mode is still experimental. It may be either promoted to first class citizen at some later point in time,
- * and it may also be removed entirely. Weave mode has much more aggressive concurrency behaviour than regular threaded
- * mode, and as such is still under test wrt cross platform stability.
- * <p/>
- * To remove weave mode from m3, the following should be removed: ExecutionPlanItem.schedule w/setters and getters
- * DefaultLifeCycles.getScheduling() and all its use ReactorArtifactRepository has a reference to isWeave too. This
- * class and its usage
- *
- * @since 3.0
- * @author Kristian Rosenvold Builds one or more lifecycles for a full module
- * <p/>
- * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
- */
-@Component( role = Builder.class, hint = "weave" )
-public class WeaveBuilder
- implements Builder
-{
-
- @Requirement
- private MojoExecutor mojoExecutor;
-
- @Requirement
- private BuilderCommon builderCommon;
-
- @Requirement
- private Logger logger;
-
- @Requirement
- private ExecutionEventCatapult eventCatapult;
-
- @Requirement
- private LifecycleDebugLogger lifecycleDebugLogger;
-
- private Map<MavenProject, MavenExecutionPlan> executionPlans = new HashMap<MavenProject, MavenExecutionPlan>();
-
- public WeaveBuilder()
- {
- }
-
- public WeaveBuilder( MojoExecutor mojoExecutor, BuilderCommon builderCommon, Logger logger,
- ExecutionEventCatapult eventCatapult, LifecycleDebugLogger lifecycleDebugLogger )
- {
- this.mojoExecutor = mojoExecutor;
- this.builderCommon = builderCommon;
- this.logger = logger;
- this.eventCatapult = eventCatapult;
- this.lifecycleDebugLogger = lifecycleDebugLogger;
- }
-
- public void build( MavenSession session, ReactorContext buildContext, ProjectBuildList projectBuilds,
- List<TaskSegment> taskSegments, ReactorBuildStatus reactorBuildStatus )
- throws ExecutionException, InterruptedException
- {
- lifecycleDebugLogger.logWeavePlan( session );
-
- ExecutorService executor =
- Executors.newFixedThreadPool( Math.min( session.getRequest().getDegreeOfConcurrency(),
- session.getProjects().size() ), new BuildThreadFactory() );
-
- try
- {
-
- ConcurrentBuildLogger concurrentBuildLogger = new ConcurrentBuildLogger();
- CompletionService<ProjectSegment> service = new ExecutorCompletionService<ProjectSegment>( executor );
-
- try
- {
- for ( MavenProject mavenProject : session.getProjects() )
- {
- Artifact mainArtifact = mavenProject.getArtifact();
- if ( mainArtifact != null && !( mainArtifact instanceof ThreadLockedArtifact ) )
- {
- ThreadLockedArtifact threadLockedArtifact = new ThreadLockedArtifact( mainArtifact );
- mavenProject.setArtifact( threadLockedArtifact );
- }
- }
-
- final List<Future<ProjectSegment>> futures = new ArrayList<Future<ProjectSegment>>();
- final Map<ProjectSegment, Future<MavenExecutionPlan>> plans =
- new HashMap<ProjectSegment, Future<MavenExecutionPlan>>();
-
- for ( TaskSegment taskSegment : taskSegments )
- {
- ProjectBuildList segmentChunks = projectBuilds.getByTaskSegment( taskSegment );
- Set<Artifact> projectArtifacts = new HashSet<Artifact>();
- for ( ProjectSegment segmentChunk : segmentChunks )
- {
- Artifact artifact = segmentChunk.getProject().getArtifact();
- if ( artifact != null )
- {
- projectArtifacts.add( artifact );
- }
- }
- for ( ProjectSegment projectBuild : segmentChunks )
- {
- plans.put( projectBuild, executor.submit( createEPFuture( projectBuild, projectArtifacts ) ) );
- }
-
- for ( ProjectSegment projectSegment : plans.keySet() )
- {
- executionPlans.put( projectSegment.getProject(), plans.get( projectSegment ).get() );
-
- }
- for ( ProjectSegment projectBuild : segmentChunks )
- {
- try
- {
- final MavenExecutionPlan executionPlan = plans.get( projectBuild ).get();
-
- DependencyContext dependencyContext =
- mojoExecutor.newDependencyContext( session, executionPlan.getMojoExecutions() );
-
- final Callable<ProjectSegment> projectBuilder =
- createCallableForBuildingOneFullModule( buildContext, session, reactorBuildStatus,
- executionPlan, projectBuild, dependencyContext,
- concurrentBuildLogger );
-
- futures.add( service.submit( projectBuilder ) );
- }
- catch ( Exception e )
- {
- throw new ExecutionException( e );
- }
- }
-
- for ( Future<ProjectSegment> buildFuture : futures )
- {
- buildFuture.get(); // At this point, this build *is* finished.
- // Do not leak threads past here or evil gremlins will get you!
- }
- futures.clear();
- }
- }
- finally
- {
- projectBuilds.closeAll();
- }
- logger.info( concurrentBuildLogger.toString() );
- }
- finally
- {
- executor.shutdown();
- // If the builder has terminated with an exception we want to catch any stray threads before going
- // to System.exit in the mavencli.
- executor.awaitTermination( 5, TimeUnit.SECONDS );
- }
- }
-
- private Callable<MavenExecutionPlan> createEPFuture( final ProjectSegment projectSegment,
- final Set<Artifact> projectArtifacts )
- {
- return new Callable<MavenExecutionPlan>()
- {
- public MavenExecutionPlan call()
- throws Exception
- {
- return builderCommon.resolveBuildPlan( projectSegment.getSession(), projectSegment.getProject(),
- projectSegment.getTaskSegment(), projectArtifacts );
- }
- };
- }
-
- private Callable<ProjectSegment> createCallableForBuildingOneFullModule( final ReactorContext reactorContext,
- final MavenSession rootSession,
- final ReactorBuildStatus reactorBuildStatus,
- final MavenExecutionPlan executionPlan,
- final ProjectSegment projectBuild,
- final DependencyContext dependencyContext,
- final ConcurrentBuildLogger concurrentBuildLogger )
- {
- return new Callable<ProjectSegment>()
- {
- public ProjectSegment call()
- throws Exception
- {
- Iterator<ExecutionPlanItem> planItems = executionPlan.iterator();
- ExecutionPlanItem current = planItems.hasNext() ? planItems.next() : null;
- ThreadLockedArtifact threadLockedArtifact =
- (ThreadLockedArtifact) projectBuild.getProject().getArtifact();
- if ( threadLockedArtifact != null )
- {
- threadLockedArtifact.attachToThread();
- }
- long buildStartTime = System.currentTimeMillis();
-
- // muxer.associateThreadWithProjectSegment( projectBuild );
-
- if ( reactorBuildStatus.isHaltedOrBlacklisted( projectBuild.getProject() ) )
- {
- eventCatapult.fire( ExecutionEvent.Type.ProjectSkipped, projectBuild.getSession(), null );
- return null;
- }
-
- eventCatapult.fire( ExecutionEvent.Type.ProjectStarted, projectBuild.getSession(), null );
-
- Collection<ArtifactLink> dependencyLinks = getUpstreamReactorDependencies( projectBuild );
-
- try
- {
- PhaseRecorder phaseRecorder = new PhaseRecorder( projectBuild.getProject() );
- long totalMojoTime = 0;
- long mojoStart;
- while ( current != null && !reactorBuildStatus.isHaltedOrBlacklisted( projectBuild.getProject() ) )
- {
-
- BuildLogItem builtLogItem =
- concurrentBuildLogger.createBuildLogItem( projectBuild.getProject(), current );
- final Schedule schedule = current.getSchedule();
-
- mojoStart = System.currentTimeMillis();
- buildExecutionPlanItem( current, phaseRecorder, schedule, reactorContext, projectBuild,
- dependencyContext );
- totalMojoTime += ( System.currentTimeMillis() - mojoStart );
-
- current.setComplete();
- builtLogItem.setComplete();
-
- ExecutionPlanItem nextPlanItem = planItems.hasNext() ? planItems.next() : null;
- if ( nextPlanItem != null && phaseRecorder.isDifferentPhase( nextPlanItem.getMojoExecution() ) )
- {
-
- final Schedule scheduleOfNext = nextPlanItem.getSchedule();
- if ( scheduleOfNext == null || !scheduleOfNext.isParallel() )
- {
- waitForAppropriateUpstreamExecutionsToFinish( builtLogItem, nextPlanItem, projectBuild,
- scheduleOfNext );
- }
-
- for ( ArtifactLink dependencyLink : dependencyLinks )
- {
- dependencyLink.resolveFromUpstream();
- }
- }
- current = nextPlanItem;
- }
-
- final BuildSuccess summary = new BuildSuccess( projectBuild.getProject(), totalMojoTime ); // -
- // waitingTime
- reactorContext.getResult().addBuildSummary( summary );
- eventCatapult.fire( ExecutionEvent.Type.ProjectSucceeded, projectBuild.getSession(), null );
- }
- catch ( Exception e )
- {
- builderCommon.handleBuildError( reactorContext, rootSession, projectBuild.getSession(),
- projectBuild.getProject(), e, buildStartTime );
- }
- finally
- {
- if ( current != null )
- {
- executionPlan.forceAllComplete();
- }
- // muxer.setThisModuleComplete( projectBuild );
- }
- return null;
- }
-
- };
- }
-
- private void waitForAppropriateUpstreamExecutionsToFinish( BuildLogItem builtLogItem,
- ExecutionPlanItem nextPlanItem,
- ProjectSegment projectBuild, Schedule scheduleOfNext )
- throws InterruptedException
- {
- for ( MavenProject upstreamProject : projectBuild.getImmediateUpstreamProjects() )
- {
- final MavenExecutionPlan upstreamPlan = executionPlans.get( upstreamProject );
- final String nextPhase =
- scheduleOfNext != null && scheduleOfNext.hasUpstreamPhaseDefined() ? scheduleOfNext.getUpstreamPhase()
- : nextPlanItem.getLifecyclePhase();
- final ExecutionPlanItem upstream = upstreamPlan.findLastInPhase( nextPhase );
-
- if ( upstream != null )
- {
- long startWait = System.currentTimeMillis();
- upstream.waitUntilDone();
- builtLogItem.addWait( upstreamProject, upstream, startWait );
- }
- else if ( !upstreamPlan.containsPhase( nextPhase ) )
- {
- // Still a bit of a kludge; if we cannot connect in a sensible way to
- // the upstream build plan we just revert to waiting for it all to
- // complete. Real problem is per-mojo phase->lifecycle mapping
- builtLogItem.addDependency( upstreamProject, "No phase tracking possible " );
- upstreamPlan.waitUntilAllDone();
- }
- else
- {
- builtLogItem.addDependency( upstreamProject, "No schedule" );
- }
- }
- }
-
- private Collection<ArtifactLink> getUpstreamReactorDependencies( ProjectSegment projectBuild )
- {
- Collection<ArtifactLink> result = new ArrayList<ArtifactLink>();
- for ( MavenProject upstreamProject : projectBuild.getTransitiveUpstreamProjects() )
- {
- Artifact upStreamArtifact = upstreamProject.getArtifact();
- if ( upStreamArtifact != null )
- {
- Artifact dependencyArtifact = findDependency( projectBuild.getProject(), upStreamArtifact );
- if ( dependencyArtifact != null )
- {
- result.add( new ArtifactLink( dependencyArtifact, upStreamArtifact ) );
- }
- }
-
- Artifact upStreamTestScopedArtifact = findTestScopedArtifact( upstreamProject );
- if ( upStreamTestScopedArtifact != null )
- {
- Artifact dependencyArtifact = findDependency( projectBuild.getProject(), upStreamArtifact );
- if ( dependencyArtifact != null )
- {
- result.add( new ArtifactLink( dependencyArtifact, upStreamTestScopedArtifact ) );
- }
- }
- }
- return result;
- }
-
- private Artifact findTestScopedArtifact( MavenProject upstreamProject )
- {
- if ( upstreamProject == null )
- {
- return null;
- }
-
- List<Artifact> artifactList = upstreamProject.getAttachedArtifacts();
- for ( Artifact artifact : artifactList )
- {
- if ( Artifact.SCOPE_TEST.equals( artifact.getScope() ) )
- {
- return artifact;
- }
- }
- return null;
- }
-
- private static boolean isThreadLockedAndEmpty( Artifact artifact )
- {
- return artifact instanceof ThreadLockedArtifact && !( (ThreadLockedArtifact) artifact ).hasReal();
- }
-
- private static Artifact findDependency( MavenProject project, Artifact upStreamArtifact )
- {
- if ( upStreamArtifact == null || isThreadLockedAndEmpty( upStreamArtifact ) )
- {
- return null;
- }
-
- String key =
- ArtifactUtils.key( upStreamArtifact.getGroupId(), upStreamArtifact.getArtifactId(),
- upStreamArtifact.getVersion() );
- final Set<Artifact> deps = project.getDependencyArtifacts();
- for ( Artifact dep : deps )
- {
- String depKey = ArtifactUtils.key( dep.getGroupId(), dep.getArtifactId(), dep.getVersion() );
- if ( key.equals( depKey ) )
- {
- return dep;
- }
- }
- return null;
-
- }
-
- private void buildExecutionPlanItem( ExecutionPlanItem current, PhaseRecorder phaseRecorder, Schedule schedule,
- ReactorContext reactorContext, ProjectSegment projectBuild,
- DependencyContext dependencyContext )
- throws LifecycleExecutionException
- {
- if ( schedule != null && schedule.isMojoSynchronized() )
- {
- synchronized ( current.getPlugin() )
- {
- buildExecutionPlanItem( reactorContext, current, projectBuild, dependencyContext, phaseRecorder );
- }
- }
- else
- {
- buildExecutionPlanItem( reactorContext, current, projectBuild, dependencyContext, phaseRecorder );
- }
- }
-
- private void buildExecutionPlanItem( ReactorContext reactorContext, ExecutionPlanItem node,
- ProjectSegment projectBuild, DependencyContext dependencyContext,
- PhaseRecorder phaseRecorder )
- throws LifecycleExecutionException
- {
-
- MavenProject currentProject = projectBuild.getProject();
-
- long buildStartTime = System.currentTimeMillis();
-
- CurrentPhaseForThread.setPhase( node.getLifecyclePhase() );
-
- MavenSession sessionForThisModule = projectBuild.getSession();
- try
- {
-
- if ( reactorContext.getReactorBuildStatus().isHaltedOrBlacklisted( currentProject ) )
- {
- return;
- }
-
- BuilderCommon.attachToThread( currentProject );
-
- mojoExecutor.execute( sessionForThisModule, node.getMojoExecution(), reactorContext.getProjectIndex(),
- dependencyContext, phaseRecorder );
-
- final BuildSuccess summary = new BuildSuccess( currentProject, System.currentTimeMillis() - buildStartTime );
- reactorContext.getResult().addBuildSummary( summary );
- }
- finally
- {
- Thread.currentThread().setContextClassLoader( reactorContext.getOriginalContextClassLoader() );
- }
- }
-
- public static boolean isWeaveMode( MavenExecutionRequest request )
- {
- return "true".equals( request.getUserProperties().getProperty( "maven3.weaveMode" ) );
- }
-
- public static void setWeaveMode( Properties properties )
- {
- properties.setProperty( "maven3.weaveMode", "true" );
- }
-
- static class ArtifactLink
- {
- private final Artifact artifactInThis;
-
- private final Artifact upstream;
-
- ArtifactLink( Artifact artifactInThis, Artifact upstream )
- {
- this.artifactInThis = artifactInThis;
- this.upstream = upstream;
- }
-
- public void resolveFromUpstream()
- {
- artifactInThis.setFile( upstream.getFile() );
- artifactInThis.setRepository( upstream.getRepository() );
- artifactInThis.setResolved( true ); // Or maybe upstream.isResolved()....
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/maven/blob/0c5678fa/maven-core/src/test/java/org/apache/maven/lifecycle/internal/ConcurrentBuildLoggerTest.java
----------------------------------------------------------------------
diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/ConcurrentBuildLoggerTest.java b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/ConcurrentBuildLoggerTest.java
deleted file mode 100644
index 5a7e105..0000000
--- a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/ConcurrentBuildLoggerTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.apache.maven.lifecycle.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License. You may obtain a
- * copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-import java.util.Iterator;
-
-import junit.framework.TestCase;
-
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.lifecycle.MavenExecutionPlan;
-import org.apache.maven.lifecycle.internal.builder.weave.BuildLogItem;
-import org.apache.maven.lifecycle.internal.builder.weave.ConcurrentBuildLogger;
-import org.apache.maven.lifecycle.internal.stub.ProjectDependencyGraphStub;
-import org.apache.maven.project.MavenProject;
-
-/**
- * @author Kristian Rosenvold
- */
-public class ConcurrentBuildLoggerTest
- extends TestCase
-{
- @SuppressWarnings( "unused" )
- public void testToGraph()
- throws Exception
- {
- ConcurrentBuildLogger concurrentBuildLogger = new ConcurrentBuildLogger();
-
- MojoDescriptorCreator mojoDescriptorCreator =
- LifecycleExecutionPlanCalculatorTest.createMojoDescriptorCreator();
- LifecycleExecutionPlanCalculator lifecycleExecutionPlanCalculator =
- LifecycleExecutionPlanCalculatorTest.createExecutionPlaceCalculator( mojoDescriptorCreator );
-
- MavenProject A = ProjectDependencyGraphStub.B;
- MavenProject B = ProjectDependencyGraphStub.C;
-
- final MavenSession session1 = ProjectDependencyGraphStub.getMavenSession( A );
-
- final GoalTask goalTask1 = new GoalTask( "compiler:compile" );
- final GoalTask goalTask2 = new GoalTask( "surefire:test" );
- final TaskSegment taskSegment1 = new TaskSegment( false, goalTask1, goalTask2 );
-
- MavenExecutionPlan executionPlan =
- lifecycleExecutionPlanCalculator.calculateExecutionPlan( session1, A, taskSegment1.getTasks() );
-
- MavenExecutionPlan executionPlan2 =
- lifecycleExecutionPlanCalculator.calculateExecutionPlan( session1, B, taskSegment1.getTasks() );
-
- final Iterator<ExecutionPlanItem> planItemIterator = executionPlan.iterator();
- final BuildLogItem a1 = concurrentBuildLogger.createBuildLogItem( A, planItemIterator.next() );
-
- final BuildLogItem a2 = concurrentBuildLogger.createBuildLogItem( A, planItemIterator.next() );
-
- final Iterator<ExecutionPlanItem> plan2ItemIterator = executionPlan.iterator();
- final BuildLogItem b1 = concurrentBuildLogger.createBuildLogItem( B, plan2ItemIterator.next() );
- final BuildLogItem b2 = concurrentBuildLogger.createBuildLogItem( B, plan2ItemIterator.next() );
-
- b1.addDependency( A, "Project dependency" );
- final Iterator<ExecutionPlanItem> aPlan = executionPlan.iterator();
- b1.addWait( A, aPlan.next(), System.currentTimeMillis() );
- b2.addWait( A, aPlan.next(), System.currentTimeMillis() );
- final String response = concurrentBuildLogger.toGraph();
- assertTrue( response.contains( "digraph" ) );
- }
-}
http://git-wip-us.apache.org/repos/asf/maven/blob/0c5678fa/maven-core/src/test/java/org/apache/maven/lifecycle/internal/LifecycleWeaveBuilderTest.java
----------------------------------------------------------------------
diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/LifecycleWeaveBuilderTest.java b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/LifecycleWeaveBuilderTest.java
deleted file mode 100644
index 44f2311..0000000
--- a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/LifecycleWeaveBuilderTest.java
+++ /dev/null
@@ -1,142 +0,0 @@
-package org.apache.maven.lifecycle.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License. You may obtain a
- * copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-import junit.framework.TestCase;
-
-import org.apache.maven.execution.DefaultMavenExecutionResult;
-import org.apache.maven.execution.MavenExecutionResult;
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.lifecycle.LifecycleNotFoundException;
-import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
-import org.apache.maven.lifecycle.internal.builder.BuilderCommon;
-import org.apache.maven.lifecycle.internal.builder.weave.WeaveBuilder;
-import org.apache.maven.lifecycle.internal.stub.ExecutionEventCatapultStub;
-import org.apache.maven.lifecycle.internal.stub.LifecycleExecutionPlanCalculatorStub;
-import org.apache.maven.lifecycle.internal.stub.LifecycleTaskSegmentCalculatorStub;
-import org.apache.maven.lifecycle.internal.stub.LoggerStub;
-import org.apache.maven.lifecycle.internal.stub.MojoExecutorStub;
-import org.apache.maven.lifecycle.internal.stub.ProjectDependencyGraphStub;
-import org.apache.maven.plugin.InvalidPluginDescriptorException;
-import org.apache.maven.plugin.MojoNotFoundException;
-import org.apache.maven.plugin.PluginDescriptorParsingException;
-import org.apache.maven.plugin.PluginNotFoundException;
-import org.apache.maven.plugin.PluginResolutionException;
-import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
-import org.apache.maven.plugin.version.PluginVersionResolutionException;
-
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorCompletionService;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-/**
- * @author Kristian Rosenvold
- */
-public class LifecycleWeaveBuilderTest
- extends TestCase
-{
-
-/* public void testBuildProjectSynchronously()
- throws Exception
- {
- final CompletionService<ProjectSegment> service = new CompletionServiceStub( true );
- final ProjectBuildList projectBuildList = runWithCompletionService( service );
- assertEquals( "Expect all tasks to be scheduled", projectBuildList.size(),
- ( (CompletionServiceStub) service ).size() );
- }
- */
-
- @SuppressWarnings( "unused" )
- public void testBuildProjectThreaded()
- throws Exception
- {
- ExecutorService executor = Executors.newFixedThreadPool( 10 );
- ExecutorCompletionService<ProjectSegment> service = new ExecutorCompletionService<ProjectSegment>( executor );
- runWithCompletionService( executor );
- executor.shutdown();
- }
-
- @SuppressWarnings( "unused" )
- public void testBuildProjectThreadedAggressive()
- throws Exception
- {
- ExecutorService executor = Executors.newFixedThreadPool( 10 );
- ExecutorCompletionService<ProjectSegment> service = new ExecutorCompletionService<ProjectSegment>( executor );
- runWithCompletionService( executor );
- executor.shutdown();
- }
-
- private ProjectBuildList runWithCompletionService( ExecutorService service )
- throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
- MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
- PluginVersionResolutionException, LifecyclePhaseNotFoundException, LifecycleNotFoundException,
- ExecutionException, InterruptedException
- {
- final ClassLoader loader = Thread.currentThread().getContextClassLoader();
- try
- {
- BuildListCalculator buildListCalculator = new BuildListCalculator();
- final MavenSession session = ProjectDependencyGraphStub.getMavenSession();
- List<TaskSegment> taskSegments = getTaskSegmentCalculator().calculateTaskSegments( session );
- ProjectBuildList projectBuildList = buildListCalculator.calculateProjectBuilds( session, taskSegments );
-
- final MojoExecutorStub mojoExecutorStub = new MojoExecutorStub();
- final WeaveBuilder builder = getWeaveBuilder( mojoExecutorStub );
- final ReactorContext buildContext = createBuildContext( session );
- ReactorBuildStatus reactorBuildStatus = new ReactorBuildStatus( session.getProjectDependencyGraph() );
- builder.build( session, buildContext, projectBuildList, taskSegments, reactorBuildStatus );
-
- LifecycleExecutionPlanCalculatorStub lifecycleExecutionPlanCalculatorStub =
- new LifecycleExecutionPlanCalculatorStub();
- final int expected = lifecycleExecutionPlanCalculatorStub.getNumberOfExceutions( projectBuildList );
- assertEquals( "All executions should be scheduled", expected, mojoExecutorStub.executions.size() );
- return projectBuildList;
- }
- finally
- {
- Thread.currentThread().setContextClassLoader( loader );
- }
- }
-
-
- private static LifecycleTaskSegmentCalculator getTaskSegmentCalculator()
- {
- return new LifecycleTaskSegmentCalculatorStub();
- }
-
- private ReactorContext createBuildContext( MavenSession session )
- {
- MavenExecutionResult mavenExecutionResult = new DefaultMavenExecutionResult();
- ReactorBuildStatus reactorBuildStatus = new ReactorBuildStatus( session.getProjectDependencyGraph() );
- return new ReactorContext( mavenExecutionResult, null, null, reactorBuildStatus );
- }
-
- private WeaveBuilder getWeaveBuilder( MojoExecutor mojoExecutor )
- {
- final BuilderCommon builderCommon = getBuilderCommon();
- final LoggerStub loggerStub = new LoggerStub();
- return new WeaveBuilder( mojoExecutor, builderCommon, loggerStub, new ExecutionEventCatapultStub(), new LifecycleDebugLogger( loggerStub ) );
- }
-
- private BuilderCommon getBuilderCommon()
- {
- final LifecycleDebugLogger logger = new LifecycleDebugLogger( new LoggerStub() );
- return new BuilderCommon( logger, new LifecycleExecutionPlanCalculatorStub(),
- new LoggerStub() );
- }
-}
http://git-wip-us.apache.org/repos/asf/maven/blob/0c5678fa/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
----------------------------------------------------------------------
diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
index 8ee2830..79871df 100644
--- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
+++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
@@ -1087,14 +1087,7 @@ public class MavenCli
if ( threadConfiguration != null )
{
- if ( threadConfiguration.contains( "W" ) )
- {
- request.setBuilderId( "weave" );
- }
- else
- {
- request.setBuilderId( "multithreaded" );
- }
+ request.setBuilderId( "multithreaded" );
int threads =
threadConfiguration.contains( "C" ) ? Integer.valueOf( threadConfiguration.replace( "C", "" ) )
[2/2] git commit: Move ThreadOutputMuxer to sit along with the
multithreaded Builder implementation
Posted by jv...@apache.org.
Move ThreadOutputMuxer to sit along with the multithreaded Builder implementation
Project: http://git-wip-us.apache.org/repos/asf/maven/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven/commit/097cc8d2
Tree: http://git-wip-us.apache.org/repos/asf/maven/tree/097cc8d2
Diff: http://git-wip-us.apache.org/repos/asf/maven/diff/097cc8d2
Branch: refs/heads/master
Commit: 097cc8d25f9261434c6de5e449ca442e45044d00
Parents: 0c5678f
Author: Jason van Zyl <ja...@tesla.io>
Authored: Thu Feb 6 16:39:15 2014 -0500
Committer: Jason van Zyl <ja...@tesla.io>
Committed: Thu Feb 6 16:39:15 2014 -0500
----------------------------------------------------------------------
.../lifecycle/internal/ProjectBuildList.java | 2 +-
.../lifecycle/internal/ThreadOutputMuxer.java | 474 ------------------
.../multithreaded/MultiThreadedBuilder.java | 1 -
.../multithreaded/ThreadOutputMuxer.java | 477 +++++++++++++++++++
.../internal/ThreadOutputMuxerTest.java | 163 -------
.../multithreaded/ThreadOutputMuxerTest.java | 167 +++++++
6 files changed, 645 insertions(+), 639 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/maven/blob/097cc8d2/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectBuildList.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectBuildList.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectBuildList.java
index acea697..ee596ec 100644
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectBuildList.java
+++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectBuildList.java
@@ -119,7 +119,7 @@ public class ProjectBuildList
return items.size();
}
- ProjectSegment get( int index )
+ public ProjectSegment get( int index )
{
return items.get( index );
}
http://git-wip-us.apache.org/repos/asf/maven/blob/097cc8d2/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ThreadOutputMuxer.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ThreadOutputMuxer.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ThreadOutputMuxer.java
deleted file mode 100644
index 0fde6d8..0000000
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ThreadOutputMuxer.java
+++ /dev/null
@@ -1,474 +0,0 @@
-package org.apache.maven.lifecycle.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * @since 3.0
- * @author Kristian Rosenvold
- * <p/>
- * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
- * This class in particular may spontaneusly self-combust and be replaced by a plexus-compliant thread aware
- * logger implementation at any time.
- */
-@SuppressWarnings( { "SynchronizationOnLocalVariableOrMethodParameter" } )
-public class ThreadOutputMuxer
-{
- private final Iterator<ProjectSegment> projects;
-
- private final ThreadLocal<ProjectSegment> projectBuildThreadLocal = new ThreadLocal<ProjectSegment>();
-
- private final Map<ProjectSegment, ByteArrayOutputStream> streams =
- new HashMap<ProjectSegment, ByteArrayOutputStream>();
-
- private final Map<ProjectSegment, PrintStream> printStreams = new HashMap<ProjectSegment, PrintStream>();
-
- private final ByteArrayOutputStream defaultOutputStreamForUnknownData = new ByteArrayOutputStream();
-
- private final PrintStream defaultPringStream = new PrintStream( defaultOutputStreamForUnknownData );
-
- private final Set<ProjectSegment> completedBuilds = Collections.synchronizedSet( new HashSet<ProjectSegment>() );
-
- private volatile ProjectSegment currentBuild;
-
- private final PrintStream originalSystemOUtStream;
-
- private final ConsolePrinter printer;
-
- /**
- * A simple but safe solution for printing to the console.
- */
-
- class ConsolePrinter
- implements Runnable
- {
- public volatile boolean running;
-
- private final ProjectBuildList projectBuildList;
-
- ConsolePrinter( ProjectBuildList projectBuildList )
- {
- this.projectBuildList = projectBuildList;
- }
-
- public void run()
- {
- running = true;
- for ( ProjectSegment projectBuild : projectBuildList )
- {
- final PrintStream projectStream = printStreams.get( projectBuild );
- ByteArrayOutputStream projectOs = streams.get( projectBuild );
-
- do
- {
- synchronized ( projectStream )
- {
- try
- {
- projectStream.wait( 100 );
- }
- catch ( InterruptedException e )
- {
- throw new RuntimeException( e );
- }
- try
- {
- projectOs.writeTo( originalSystemOUtStream );
- }
- catch ( IOException e )
- {
- throw new RuntimeException( e );
- }
-
- projectOs.reset();
- }
- }
- while ( !completedBuilds.contains( projectBuild ) );
- }
- running = false;
- }
-
- /*
- Wait until we are sure the print-stream thread is running.
- */
-
- public void waitUntilRunning( boolean expect )
- {
- while ( !running == expect )
- {
- try
- {
- Thread.sleep( 10 );
- }
- catch ( InterruptedException e )
- {
- throw new RuntimeException( e );
- }
- }
- }
- }
-
- public ThreadOutputMuxer( ProjectBuildList segmentChunks, PrintStream originalSystemOut )
- {
- projects = segmentChunks.iterator();
- for ( ProjectSegment segmentChunk : segmentChunks )
- {
- final ByteArrayOutputStream value = new ByteArrayOutputStream();
- streams.put( segmentChunk, value );
- printStreams.put( segmentChunk, new PrintStream( value ) );
- }
- setNext();
- this.originalSystemOUtStream = originalSystemOut;
- System.setOut( new ThreadBoundPrintStream( this.originalSystemOUtStream ) );
- printer = new ConsolePrinter( segmentChunks );
- new Thread( printer ).start();
- printer.waitUntilRunning( true );
- }
-
- public void close()
- {
- printer.waitUntilRunning( false );
- System.setOut( this.originalSystemOUtStream );
- }
-
- private void setNext()
- {
- currentBuild = projects.hasNext() ? projects.next() : null;
- }
-
- private boolean ownsRealOutputStream( ProjectSegment projectBuild )
- {
- return projectBuild.equals( currentBuild );
- }
-
- private PrintStream getThreadBoundPrintStream()
- {
- ProjectSegment threadProject = projectBuildThreadLocal.get();
- if ( threadProject == null )
- {
- return defaultPringStream;
- }
- if ( ownsRealOutputStream( threadProject ) )
- {
- return originalSystemOUtStream;
- }
- return printStreams.get( threadProject );
- }
-
- public void associateThreadWithProjectSegment( ProjectSegment projectBuild )
- {
- projectBuildThreadLocal.set( projectBuild );
- }
-
- public void setThisModuleComplete( ProjectSegment projectBuild )
- {
- completedBuilds.add( projectBuild );
- PrintStream stream = printStreams.get( projectBuild );
- synchronized ( stream )
- {
- stream.notifyAll();
- }
- disconnectThreadFromProject();
- }
-
- private void disconnectThreadFromProject()
- {
- projectBuildThreadLocal.remove();
- }
-
- private class ThreadBoundPrintStream
- extends PrintStream
- {
-
- public ThreadBoundPrintStream( PrintStream systemOutStream )
- {
- super( systemOutStream );
- }
-
- private PrintStream getOutputStreamForCurrentThread()
- {
- return getThreadBoundPrintStream();
- }
-
- @Override
- public void println()
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.println();
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void print( char c )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.print( c );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void println( char x )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.println( x );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void print( double d )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.print( d );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void println( double x )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.println( x );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void print( float f )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.print( f );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void println( float x )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.println( x );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void print( int i )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.print( i );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void println( int x )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.println( x );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void print( long l )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.print( l );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void println( long x )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.print( x );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void print( boolean b )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.print( b );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void println( boolean x )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.print( x );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void print( char s[] )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.print( s );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void println( char x[] )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.print( x );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void print( Object obj )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.print( obj );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void println( Object x )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.println( x );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void print( String s )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.print( s );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void println( String x )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.println( x );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void write( byte b[], int off, int len )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.write( b, off, len );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void close()
- {
- getOutputStreamForCurrentThread().close();
- }
-
- @Override
- public void flush()
- {
- getOutputStreamForCurrentThread().flush();
- }
-
- @Override
- public void write( int b )
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.write( b );
- currentStream.notifyAll();
- }
- }
-
- @Override
- public void write( byte b[] )
- throws IOException
- {
- final PrintStream currentStream = getOutputStreamForCurrentThread();
- synchronized ( currentStream )
- {
- currentStream.write( b );
- currentStream.notifyAll();
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/maven/blob/097cc8d2/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/MultiThreadedBuilder.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/MultiThreadedBuilder.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/MultiThreadedBuilder.java
index b89aa0e..c0104ef 100644
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/MultiThreadedBuilder.java
+++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/MultiThreadedBuilder.java
@@ -37,7 +37,6 @@ import org.apache.maven.lifecycle.internal.ProjectSegment;
import org.apache.maven.lifecycle.internal.ReactorBuildStatus;
import org.apache.maven.lifecycle.internal.ReactorContext;
import org.apache.maven.lifecycle.internal.TaskSegment;
-import org.apache.maven.lifecycle.internal.ThreadOutputMuxer;
import org.apache.maven.lifecycle.internal.builder.Builder;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.annotations.Component;
http://git-wip-us.apache.org/repos/asf/maven/blob/097cc8d2/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ThreadOutputMuxer.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ThreadOutputMuxer.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ThreadOutputMuxer.java
new file mode 100644
index 0000000..8f1f493
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ThreadOutputMuxer.java
@@ -0,0 +1,477 @@
+package org.apache.maven.lifecycle.internal.builder.multithreaded;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.lifecycle.internal.ProjectBuildList;
+import org.apache.maven.lifecycle.internal.ProjectSegment;
+
+/**
+ * @since 3.0
+ * @author Kristian Rosenvold
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ * This class in particular may spontaneusly self-combust and be replaced by a plexus-compliant thread aware
+ * logger implementation at any time.
+ */
+@SuppressWarnings( { "SynchronizationOnLocalVariableOrMethodParameter" } )
+public class ThreadOutputMuxer
+{
+ private final Iterator<ProjectSegment> projects;
+
+ private final ThreadLocal<ProjectSegment> projectBuildThreadLocal = new ThreadLocal<ProjectSegment>();
+
+ private final Map<ProjectSegment, ByteArrayOutputStream> streams =
+ new HashMap<ProjectSegment, ByteArrayOutputStream>();
+
+ private final Map<ProjectSegment, PrintStream> printStreams = new HashMap<ProjectSegment, PrintStream>();
+
+ private final ByteArrayOutputStream defaultOutputStreamForUnknownData = new ByteArrayOutputStream();
+
+ private final PrintStream defaultPringStream = new PrintStream( defaultOutputStreamForUnknownData );
+
+ private final Set<ProjectSegment> completedBuilds = Collections.synchronizedSet( new HashSet<ProjectSegment>() );
+
+ private volatile ProjectSegment currentBuild;
+
+ private final PrintStream originalSystemOUtStream;
+
+ private final ConsolePrinter printer;
+
+ /**
+ * A simple but safe solution for printing to the console.
+ */
+
+ class ConsolePrinter
+ implements Runnable
+ {
+ public volatile boolean running;
+
+ private final ProjectBuildList projectBuildList;
+
+ ConsolePrinter( ProjectBuildList projectBuildList )
+ {
+ this.projectBuildList = projectBuildList;
+ }
+
+ public void run()
+ {
+ running = true;
+ for ( ProjectSegment projectBuild : projectBuildList )
+ {
+ final PrintStream projectStream = printStreams.get( projectBuild );
+ ByteArrayOutputStream projectOs = streams.get( projectBuild );
+
+ do
+ {
+ synchronized ( projectStream )
+ {
+ try
+ {
+ projectStream.wait( 100 );
+ }
+ catch ( InterruptedException e )
+ {
+ throw new RuntimeException( e );
+ }
+ try
+ {
+ projectOs.writeTo( originalSystemOUtStream );
+ }
+ catch ( IOException e )
+ {
+ throw new RuntimeException( e );
+ }
+
+ projectOs.reset();
+ }
+ }
+ while ( !completedBuilds.contains( projectBuild ) );
+ }
+ running = false;
+ }
+
+ /*
+ Wait until we are sure the print-stream thread is running.
+ */
+
+ public void waitUntilRunning( boolean expect )
+ {
+ while ( !running == expect )
+ {
+ try
+ {
+ Thread.sleep( 10 );
+ }
+ catch ( InterruptedException e )
+ {
+ throw new RuntimeException( e );
+ }
+ }
+ }
+ }
+
+ public ThreadOutputMuxer( ProjectBuildList segmentChunks, PrintStream originalSystemOut )
+ {
+ projects = segmentChunks.iterator();
+ for ( ProjectSegment segmentChunk : segmentChunks )
+ {
+ final ByteArrayOutputStream value = new ByteArrayOutputStream();
+ streams.put( segmentChunk, value );
+ printStreams.put( segmentChunk, new PrintStream( value ) );
+ }
+ setNext();
+ this.originalSystemOUtStream = originalSystemOut;
+ System.setOut( new ThreadBoundPrintStream( this.originalSystemOUtStream ) );
+ printer = new ConsolePrinter( segmentChunks );
+ new Thread( printer ).start();
+ printer.waitUntilRunning( true );
+ }
+
+ public void close()
+ {
+ printer.waitUntilRunning( false );
+ System.setOut( this.originalSystemOUtStream );
+ }
+
+ private void setNext()
+ {
+ currentBuild = projects.hasNext() ? projects.next() : null;
+ }
+
+ private boolean ownsRealOutputStream( ProjectSegment projectBuild )
+ {
+ return projectBuild.equals( currentBuild );
+ }
+
+ private PrintStream getThreadBoundPrintStream()
+ {
+ ProjectSegment threadProject = projectBuildThreadLocal.get();
+ if ( threadProject == null )
+ {
+ return defaultPringStream;
+ }
+ if ( ownsRealOutputStream( threadProject ) )
+ {
+ return originalSystemOUtStream;
+ }
+ return printStreams.get( threadProject );
+ }
+
+ public void associateThreadWithProjectSegment( ProjectSegment projectBuild )
+ {
+ projectBuildThreadLocal.set( projectBuild );
+ }
+
+ public void setThisModuleComplete( ProjectSegment projectBuild )
+ {
+ completedBuilds.add( projectBuild );
+ PrintStream stream = printStreams.get( projectBuild );
+ synchronized ( stream )
+ {
+ stream.notifyAll();
+ }
+ disconnectThreadFromProject();
+ }
+
+ private void disconnectThreadFromProject()
+ {
+ projectBuildThreadLocal.remove();
+ }
+
+ private class ThreadBoundPrintStream
+ extends PrintStream
+ {
+
+ public ThreadBoundPrintStream( PrintStream systemOutStream )
+ {
+ super( systemOutStream );
+ }
+
+ private PrintStream getOutputStreamForCurrentThread()
+ {
+ return getThreadBoundPrintStream();
+ }
+
+ @Override
+ public void println()
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.println();
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void print( char c )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( c );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void println( char x )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.println( x );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void print( double d )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( d );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void println( double x )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.println( x );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void print( float f )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( f );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void println( float x )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.println( x );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void print( int i )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( i );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void println( int x )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.println( x );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void print( long l )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( l );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void println( long x )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( x );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void print( boolean b )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( b );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void println( boolean x )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( x );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void print( char s[] )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( s );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void println( char x[] )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( x );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void print( Object obj )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( obj );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void println( Object x )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.println( x );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void print( String s )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( s );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void println( String x )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.println( x );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void write( byte b[], int off, int len )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.write( b, off, len );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void close()
+ {
+ getOutputStreamForCurrentThread().close();
+ }
+
+ @Override
+ public void flush()
+ {
+ getOutputStreamForCurrentThread().flush();
+ }
+
+ @Override
+ public void write( int b )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.write( b );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void write( byte b[] )
+ throws IOException
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.write( b );
+ currentStream.notifyAll();
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/maven/blob/097cc8d2/maven-core/src/test/java/org/apache/maven/lifecycle/internal/ThreadOutputMuxerTest.java
----------------------------------------------------------------------
diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/ThreadOutputMuxerTest.java b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/ThreadOutputMuxerTest.java
deleted file mode 100644
index f040566..0000000
--- a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/ThreadOutputMuxerTest.java
+++ /dev/null
@@ -1,163 +0,0 @@
-package org.apache.maven.lifecycle.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License. You may obtain a
- * copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-import junit.framework.TestCase;
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.lifecycle.LifecycleNotFoundException;
-import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
-import org.apache.maven.lifecycle.internal.stub.ProjectDependencyGraphStub;
-import org.apache.maven.plugin.InvalidPluginDescriptorException;
-import org.apache.maven.plugin.MojoNotFoundException;
-import org.apache.maven.plugin.PluginDescriptorParsingException;
-import org.apache.maven.plugin.PluginNotFoundException;
-import org.apache.maven.plugin.PluginResolutionException;
-import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
-import org.apache.maven.plugin.version.PluginVersionResolutionException;
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CompletionService;
-import java.util.concurrent.ExecutorCompletionService;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-
-/**
- * @author Kristian Rosenvold
- */
-public class ThreadOutputMuxerTest
- extends TestCase
-{
-
- final String paid = "Paid";
-
- final String in = "In";
-
- final String full = "Full";
-
- public void testSingleThreaded()
- throws Exception
- {
- ProjectBuildList src = getProjectBuildList();
- ProjectBuildList projectBuildList =
- new ProjectBuildList( Arrays.asList( src.get( 0 ), src.get( 1 ), src.get( 2 ) ) );
-
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- PrintStream systemOut = new PrintStream( byteArrayOutputStream );
- ThreadOutputMuxer threadOutputMuxer = new ThreadOutputMuxer( projectBuildList, systemOut );
-
- threadOutputMuxer.associateThreadWithProjectSegment( projectBuildList.get( 0 ) );
- System.out.print( paid ); // No, this does not print to system.out. It's part of the test
- assertEquals( paid.length(), byteArrayOutputStream.size() );
- threadOutputMuxer.associateThreadWithProjectSegment( projectBuildList.get( 1 ) );
- System.out.print( in ); // No, this does not print to system.out. It's part of the test
- assertEquals( paid.length(), byteArrayOutputStream.size() );
- threadOutputMuxer.associateThreadWithProjectSegment( projectBuildList.get( 2 ) );
- System.out.print( full ); // No, this does not print to system.out. It's part of the test
- assertEquals( paid.length(), byteArrayOutputStream.size() );
-
- threadOutputMuxer.setThisModuleComplete( projectBuildList.get( 0 ) );
- threadOutputMuxer.setThisModuleComplete( projectBuildList.get( 1 ) );
- threadOutputMuxer.setThisModuleComplete( projectBuildList.get( 2 ) );
- threadOutputMuxer.close();
- assertEquals( ( paid + in + full ).length(), byteArrayOutputStream.size() );
- }
-
- public void testMultiThreaded()
- throws Exception
- {
- ProjectBuildList projectBuildList = getProjectBuildList();
-
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- PrintStream systemOut = new PrintStream( byteArrayOutputStream );
- final ThreadOutputMuxer threadOutputMuxer = new ThreadOutputMuxer( projectBuildList, systemOut );
-
- final List<String> stringList =
- Arrays.asList( "Thinkin", "of", "a", "master", "plan", "Cuz", "ain’t", "nuthin", "but", "sweat", "inside",
- "my", "hand" );
- Iterator<String> lyrics = stringList.iterator();
-
- ExecutorService executor = Executors.newFixedThreadPool( 10 );
- CompletionService<ProjectSegment> service = new ExecutorCompletionService<ProjectSegment>( executor );
-
- List<Future<ProjectSegment>> futures = new ArrayList<Future<ProjectSegment>>();
- for ( ProjectSegment projectBuild : projectBuildList )
- {
- final Future<ProjectSegment> buildFuture =
- service.submit( new Outputter( threadOutputMuxer, projectBuild, lyrics.next() ) );
- futures.add( buildFuture );
- }
-
- for ( Future<ProjectSegment> future : futures )
- {
- future.get();
- }
- int expectedLength = 0;
- for ( int i = 0; i < projectBuildList.size(); i++ )
- {
- expectedLength += stringList.get( i ).length();
- }
-
- threadOutputMuxer.close();
- final byte[] bytes = byteArrayOutputStream.toByteArray();
- String result = new String( bytes );
- assertEquals( result, expectedLength, bytes.length );
-
-
- }
-
- class Outputter
- implements Callable<ProjectSegment>
- {
- private final ThreadOutputMuxer threadOutputMuxer;
-
- private final ProjectSegment item;
-
- private final String response;
-
- Outputter( ThreadOutputMuxer threadOutputMuxer, ProjectSegment item, String response )
- {
- this.threadOutputMuxer = threadOutputMuxer;
- this.item = item;
- this.response = response;
- }
-
- public ProjectSegment call()
- throws Exception
- {
- threadOutputMuxer.associateThreadWithProjectSegment( item );
- System.out.print( response );
- threadOutputMuxer.setThisModuleComplete( item );
- return item;
- }
- }
-
-
- private ProjectBuildList getProjectBuildList()
- throws InvalidPluginDescriptorException, PluginVersionResolutionException, PluginDescriptorParsingException,
- NoPluginFoundForPrefixException, MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
- LifecyclePhaseNotFoundException, LifecycleNotFoundException
- {
- final MavenSession session = ProjectDependencyGraphStub.getMavenSession();
- return ProjectDependencyGraphStub.getProjectBuildList( session );
- }
-}
http://git-wip-us.apache.org/repos/asf/maven/blob/097cc8d2/maven-core/src/test/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ThreadOutputMuxerTest.java
----------------------------------------------------------------------
diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ThreadOutputMuxerTest.java b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ThreadOutputMuxerTest.java
new file mode 100644
index 0000000..dc75a94
--- /dev/null
+++ b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ThreadOutputMuxerTest.java
@@ -0,0 +1,167 @@
+package org.apache.maven.lifecycle.internal.builder.multithreaded;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import junit.framework.TestCase;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.LifecycleNotFoundException;
+import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
+import org.apache.maven.lifecycle.internal.ProjectBuildList;
+import org.apache.maven.lifecycle.internal.ProjectSegment;
+import org.apache.maven.lifecycle.internal.builder.multithreaded.ThreadOutputMuxer;
+import org.apache.maven.lifecycle.internal.stub.ProjectDependencyGraphStub;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletionService;
+import java.util.concurrent.ExecutorCompletionService;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+/**
+ * @author Kristian Rosenvold
+ */
+public class ThreadOutputMuxerTest
+ extends TestCase
+{
+
+ final String paid = "Paid";
+
+ final String in = "In";
+
+ final String full = "Full";
+
+ public void testSingleThreaded()
+ throws Exception
+ {
+ ProjectBuildList src = getProjectBuildList();
+ ProjectBuildList projectBuildList =
+ new ProjectBuildList( Arrays.asList( src.get( 0 ), src.get( 1 ), src.get( 2 ) ) );
+
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ PrintStream systemOut = new PrintStream( byteArrayOutputStream );
+ ThreadOutputMuxer threadOutputMuxer = new ThreadOutputMuxer( projectBuildList, systemOut );
+
+ threadOutputMuxer.associateThreadWithProjectSegment( projectBuildList.get( 0 ) );
+ System.out.print( paid ); // No, this does not print to system.out. It's part of the test
+ assertEquals( paid.length(), byteArrayOutputStream.size() );
+ threadOutputMuxer.associateThreadWithProjectSegment( projectBuildList.get( 1 ) );
+ System.out.print( in ); // No, this does not print to system.out. It's part of the test
+ assertEquals( paid.length(), byteArrayOutputStream.size() );
+ threadOutputMuxer.associateThreadWithProjectSegment( projectBuildList.get( 2 ) );
+ System.out.print( full ); // No, this does not print to system.out. It's part of the test
+ assertEquals( paid.length(), byteArrayOutputStream.size() );
+
+ threadOutputMuxer.setThisModuleComplete( projectBuildList.get( 0 ) );
+ threadOutputMuxer.setThisModuleComplete( projectBuildList.get( 1 ) );
+ threadOutputMuxer.setThisModuleComplete( projectBuildList.get( 2 ) );
+ threadOutputMuxer.close();
+ assertEquals( ( paid + in + full ).length(), byteArrayOutputStream.size() );
+ }
+
+ public void testMultiThreaded()
+ throws Exception
+ {
+ ProjectBuildList projectBuildList = getProjectBuildList();
+
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ PrintStream systemOut = new PrintStream( byteArrayOutputStream );
+ final ThreadOutputMuxer threadOutputMuxer = new ThreadOutputMuxer( projectBuildList, systemOut );
+
+ final List<String> stringList =
+ Arrays.asList( "Thinkin", "of", "a", "master", "plan", "Cuz", "ain’t", "nuthin", "but", "sweat", "inside",
+ "my", "hand" );
+ Iterator<String> lyrics = stringList.iterator();
+
+ ExecutorService executor = Executors.newFixedThreadPool( 10 );
+ CompletionService<ProjectSegment> service = new ExecutorCompletionService<ProjectSegment>( executor );
+
+ List<Future<ProjectSegment>> futures = new ArrayList<Future<ProjectSegment>>();
+ for ( ProjectSegment projectBuild : projectBuildList )
+ {
+ final Future<ProjectSegment> buildFuture =
+ service.submit( new Outputter( threadOutputMuxer, projectBuild, lyrics.next() ) );
+ futures.add( buildFuture );
+ }
+
+ for ( Future<ProjectSegment> future : futures )
+ {
+ future.get();
+ }
+ int expectedLength = 0;
+ for ( int i = 0; i < projectBuildList.size(); i++ )
+ {
+ expectedLength += stringList.get( i ).length();
+ }
+
+ threadOutputMuxer.close();
+ final byte[] bytes = byteArrayOutputStream.toByteArray();
+ String result = new String( bytes );
+ assertEquals( result, expectedLength, bytes.length );
+
+
+ }
+
+ class Outputter
+ implements Callable<ProjectSegment>
+ {
+ private final ThreadOutputMuxer threadOutputMuxer;
+
+ private final ProjectSegment item;
+
+ private final String response;
+
+ Outputter( ThreadOutputMuxer threadOutputMuxer, ProjectSegment item, String response )
+ {
+ this.threadOutputMuxer = threadOutputMuxer;
+ this.item = item;
+ this.response = response;
+ }
+
+ public ProjectSegment call()
+ throws Exception
+ {
+ threadOutputMuxer.associateThreadWithProjectSegment( item );
+ System.out.print( response );
+ threadOutputMuxer.setThisModuleComplete( item );
+ return item;
+ }
+ }
+
+
+ private ProjectBuildList getProjectBuildList()
+ throws InvalidPluginDescriptorException, PluginVersionResolutionException, PluginDescriptorParsingException,
+ NoPluginFoundForPrefixException, MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException
+ {
+ final MavenSession session = ProjectDependencyGraphStub.getMavenSession();
+ return ProjectDependencyGraphStub.getProjectBuildList( session );
+ }
+}