You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by db...@apache.org on 2005/11/10 07:21:14 UTC

svn commit: r332233 - in /geronimo/gbuild/trunk: ./ src/main/java/org/apache/geronimo/gbuild/ src/main/java/org/apache/geronimo/gbuild/agent/ src/main/resources/META-INF/ src/main/resources/META-INF/plexus/

Author: dblevins
Date: Wed Nov  9 22:21:11 2005
New Revision: 332233

URL: http://svn.apache.org/viewcvs?rev=332233&view=rev
Log:
Beginning of a distributed, jms-based, continuum build executor.  much code liberaly taken from continuum.  won't build unless you manually put all the continuum and plexus jars into your maven 1 repo.

Added:
    geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/
    geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/AbstractDistributedContinuumAction.java
    geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/BuildAgent.java
    geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/ContinuumBuildAgent.java
    geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/DistrubutedBuildController.java
    geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/ExecuteDistributedBuilderContinuumAction.java
    geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/Main.java
    geronimo/gbuild/trunk/src/main/resources/META-INF/
    geronimo/gbuild/trunk/src/main/resources/META-INF/plexus/
    geronimo/gbuild/trunk/src/main/resources/META-INF/plexus/components.xml
Modified:
    geronimo/gbuild/trunk/project.properties
    geronimo/gbuild/trunk/project.xml
    geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/App.java

Modified: geronimo/gbuild/trunk/project.properties
URL: http://svn.apache.org/viewcvs/geronimo/gbuild/trunk/project.properties?rev=332233&r1=332232&r2=332233&view=diff
==============================================================================
--- geronimo/gbuild/trunk/project.properties (original)
+++ geronimo/gbuild/trunk/project.properties Wed Nov  9 22:21:11 2005
@@ -8,3 +8,9 @@
 maven.repo.apache.directory=/www/cvs.apache.org/repository
 maven.repo.apache.username=${user.name}
 
+
+maven.compile.source=1.4
+maven.compile.target=1.4
+#maven.compile.deprecation=true
+maven.compile.debug=true
+maven.compile.optimize=true

Modified: geronimo/gbuild/trunk/project.xml
URL: http://svn.apache.org/viewcvs/geronimo/gbuild/trunk/project.xml?rev=332233&r1=332232&r2=332233&view=diff
==============================================================================
--- geronimo/gbuild/trunk/project.xml (original)
+++ geronimo/gbuild/trunk/project.xml Wed Nov  9 22:21:11 2005
@@ -9,11 +9,42 @@
   <shortDescription>gbuild</shortDescription>
   <description>gbuild</description>
   <url></url>
-  <repository>
-    <connection>scm:cvs:ext:${maven.username}@wibdio.net:/cvs/wibdio/pente:pente</connection>
-    <developerConnection>scm:cvs:ext:${maven.username}@wibdio.net:/cvs/wibdio/pente:pente</developerConnection>
-  </repository>
   <dependencies>
+    <dependency>
+      <groupId>org.apache.maven.continuum</groupId>
+      <artifactId>continuum-api</artifactId>
+      <version>1.1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.continuum</groupId>
+      <artifactId>continuum-core</artifactId>
+      <version>1.1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.continuum</groupId>
+      <artifactId>continuum-model</artifactId>
+      <version>1.1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-command-line</artifactId>
+      <version>1.0-alpha-2</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-container-default</artifactId>
+      <version>1.0-alpha-8</version>
+    </dependency>
+      <dependency>
+        <groupId>org.codehaus.plexus</groupId>
+        <artifactId>plexus-utils</artifactId>
+        <version>1.0.4</version>
+	</dependency>
+      <dependency>
+        <groupId>org.codehaus.plexus</groupId>
+        <artifactId>plexus-action</artifactId>
+        <version>1.0-alpha-6</version>
+      </dependency>
       <dependency>
          <groupId>geronimo-spec</groupId>
          <artifactId>geronimo-spec-j2ee</artifactId>

Modified: geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/App.java
URL: http://svn.apache.org/viewcvs/geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/App.java?rev=332233&r1=332232&r2=332233&view=diff
==============================================================================
--- geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/App.java (original)
+++ geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/App.java Wed Nov  9 22:21:11 2005
@@ -17,39 +17,17 @@
  * Hello world!
  */
 public class App {
+    public static final String SUBJECT = "GBUILD.CTEST.OUT";
 
     public static void main(String[] args) throws Exception {
         thread(new HelloWorldBroker(args), true);
 
-        Thread.sleep(1000);
+        Thread.sleep(2000);
 
         thread(new HelloWorldProducer(), false);
-        thread(new HelloWorldProducer(), false);
-        thread(new HelloWorldConsumer(), false);
-        Thread.sleep(1000);
-        thread(new HelloWorldConsumer(), false);
-        thread(new HelloWorldProducer(), false);
-        thread(new HelloWorldConsumer(), false);
-        thread(new HelloWorldProducer(), false);
-        Thread.sleep(1000);
-        thread(new HelloWorldConsumer(), false);
-        thread(new HelloWorldProducer(), false);
-        thread(new HelloWorldConsumer(), false);
-        thread(new HelloWorldConsumer(), false);
-        thread(new HelloWorldProducer(), false);
-        thread(new HelloWorldProducer(), false);
-        Thread.sleep(1000);
-        thread(new HelloWorldProducer(), false);
-        thread(new HelloWorldConsumer(), false);
         thread(new HelloWorldConsumer(), false);
         thread(new HelloWorldProducer(), false);
         thread(new HelloWorldConsumer(), false);
-        thread(new HelloWorldProducer(), false);
-        thread(new HelloWorldConsumer(), false);
-        thread(new HelloWorldProducer(), false);
-        thread(new HelloWorldConsumer(), false);
-        thread(new HelloWorldConsumer(), false);
-        thread(new HelloWorldProducer(), false);
     }
 
     public static void thread(Runnable runnable, boolean daemon) {
@@ -71,6 +49,7 @@
     }
 
     public static class HelloWorldProducer implements Runnable {
+
         public void run() {
             try {
                 // Create a ConnectionFactory
@@ -84,7 +63,7 @@
                 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
 
                 // Create the destination (Topic or Queue)
-                Destination destination = session.createQueue("TEST.FOO");
+                Destination destination = session.createQueue(SUBJECT);
 
                 // Create a MessageProducer from the Session to the Topic or Queue
                 MessageProducer producer = session.createProducer(destination);
@@ -125,13 +104,13 @@
                 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
 
                 // Create the destination (Topic or Queue)
-                Destination destination = session.createQueue("TEST.FOO");
+                Destination destination = session.createQueue(SUBJECT);
 
                 // Create a MessageConsumer from the Session to the Topic or Queue
                 MessageConsumer consumer = session.createConsumer(destination);
 
                 // Wait for a message
-                Message message = consumer.receive(1000);
+                Message message = consumer.receive(10000);
 
                 if (message instanceof TextMessage) {
                     TextMessage textMessage = (TextMessage) message;
@@ -154,4 +133,5 @@
             System.out.println("JMS Exception occured.  Shutting down client.");
         }
     }
+
 }

Added: geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/AbstractDistributedContinuumAction.java
URL: http://svn.apache.org/viewcvs/geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/AbstractDistributedContinuumAction.java?rev=332233&view=auto
==============================================================================
--- geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/AbstractDistributedContinuumAction.java (added)
+++ geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/AbstractDistributedContinuumAction.java Wed Nov  9 22:21:11 2005
@@ -0,0 +1,52 @@
+/**
+ *
+ * Copyright 2004 The Apache Software Foundation
+ *
+ *  Licensed 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.
+ */
+package org.apache.geronimo.gbuild.agent;
+
+import org.apache.maven.continuum.core.action.AbstractContinuumAction;
+import org.apache.maven.continuum.model.project.Project;
+import org.apache.maven.continuum.model.project.BuildDefinition;
+
+import java.util.Map;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractDistributedContinuumAction extends AbstractContinuumAction {
+
+    // ----------------------------------------------------------------------
+    // Keys for the values that can be in the context
+    // ----------------------------------------------------------------------
+
+    public static final String KEY_PROJECT = "project";
+
+    public static final String KEY_BUILD_DEFINITION = "build-definition";
+
+    // ----------------------------------------------------------------------
+    //
+    // ----------------------------------------------------------------------
+
+    public static Project getProject( Map context )
+    {
+        return (Project) getObject( context, KEY_PROJECT_ID );
+    }
+
+    public static BuildDefinition getBuildDefinition( Map context )
+    {
+        return (BuildDefinition) getObject( context, KEY_BUILD_DEFINITION_ID );
+    }
+
+}

Added: geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/BuildAgent.java
URL: http://svn.apache.org/viewcvs/geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/BuildAgent.java?rev=332233&view=auto
==============================================================================
--- geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/BuildAgent.java (added)
+++ geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/BuildAgent.java Wed Nov  9 22:21:11 2005
@@ -0,0 +1,24 @@
+/**
+ *
+ * Copyright 2004 The Apache Software Foundation
+ *
+ *  Licensed 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.
+ */
+package org.apache.geronimo.gbuild.agent;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface BuildAgent extends Runnable {
+    String ROLE = BuildAgent.class.getName();
+}

Added: geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/ContinuumBuildAgent.java
URL: http://svn.apache.org/viewcvs/geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/ContinuumBuildAgent.java?rev=332233&view=auto
==============================================================================
--- geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/ContinuumBuildAgent.java (added)
+++ geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/ContinuumBuildAgent.java Wed Nov  9 22:21:11 2005
@@ -0,0 +1,110 @@
+/**
+ *
+ * Copyright 2004 The Apache Software Foundation
+ *
+ *  Licensed 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.
+ */
+package org.apache.geronimo.gbuild.agent;
+
+import org.activemq.ActiveMQConnectionFactory;
+import org.apache.maven.continuum.utils.shell.ShellCommandHelper;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.ExceptionListener;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.ObjectMessage;
+import javax.jms.Session;
+import java.util.HashMap;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ContinuumBuildAgent implements BuildAgent, ExceptionListener {
+
+    /**
+     * @plexus.requirement
+     */
+    private ShellCommandHelper shellCommandHelper;
+
+    /**
+     * @plexus.configuration
+     */
+    private String subject;
+
+    /**
+     * @plexus.configuration
+     */
+    private String url;
+
+    private boolean run;
+
+    public void run() {
+        try {
+            run = true;
+
+            // Create a ConnectionFactory
+            ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
+
+            // Create a Connection
+            Connection connection = connectionFactory.createConnection();
+            connection.start();
+
+            connection.setExceptionListener(this);
+
+            // Create a Session
+            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+            // Create the destination (Topic or Queue)
+            Destination destination = session.createQueue(subject);
+
+            // Create a MessageConsumer from the Session to the Topic or Queue
+            MessageConsumer consumer = session.createConsumer(destination);
+
+            while (run) {
+                // Wait for a message
+                Message message = consumer.receive();
+
+                if (message instanceof ObjectMessage) {
+                    ObjectMessage objectMessage = (ObjectMessage) message;
+                    HashMap map = (HashMap) objectMessage.getObject();
+
+                } else {
+                    System.out.println("Incorect message type: " + message.getClass().getName());
+                }
+            }
+
+            consumer.close();
+            session.close();
+            connection.close();
+        } catch (Exception e) {
+            System.out.println("Caught: " + e);
+            e.printStackTrace();
+        }
+    }
+
+    public synchronized boolean isRunning() {
+        return run;
+    }
+
+    public synchronized void stop() {
+        run = false;
+    }
+    
+    public synchronized void onException(JMSException ex) {
+        System.out.println("JMS Exception occured.  Shutting down client.");
+    }
+
+}

Added: geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/DistrubutedBuildController.java
URL: http://svn.apache.org/viewcvs/geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/DistrubutedBuildController.java?rev=332233&view=auto
==============================================================================
--- geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/DistrubutedBuildController.java (added)
+++ geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/DistrubutedBuildController.java Wed Nov  9 22:21:11 2005
@@ -0,0 +1,322 @@
+/**
+ *
+ * Copyright 2004 The Apache Software Foundation
+ *
+ *  Licensed 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.
+ */
+package org.apache.geronimo.gbuild.agent;
+
+import org.apache.maven.continuum.model.project.Project;
+import org.apache.maven.continuum.model.project.BuildResult;
+import org.apache.maven.continuum.model.scm.ScmResult;
+import org.apache.maven.continuum.store.ContinuumStoreException;
+import org.apache.maven.continuum.core.action.AbstractContinuumAction;
+import org.apache.maven.continuum.scm.ContinuumScmException;
+import org.apache.maven.continuum.utils.ContinuumUtils;
+import org.apache.maven.continuum.project.ContinuumProjectState;
+
+import org.apache.maven.continuum.core.action.AbstractContinuumAction;
+import org.apache.maven.continuum.model.project.BuildResult;
+import org.apache.maven.continuum.model.project.Project;
+import org.apache.maven.continuum.model.project.BuildDefinition;
+import org.apache.maven.continuum.model.scm.ScmResult;
+import org.apache.maven.continuum.notification.ContinuumNotificationDispatcher;
+import org.apache.maven.continuum.project.ContinuumProjectState;
+import org.apache.maven.continuum.scm.ContinuumScmException;
+import org.apache.maven.continuum.store.ContinuumStore;
+import org.apache.maven.continuum.store.ContinuumStoreException;
+import org.apache.maven.continuum.utils.ContinuumUtils;
+import org.apache.maven.continuum.utils.WorkingDirectoryService;
+import org.codehaus.plexus.action.ActionManager;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.util.StringUtils;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class DistrubutedBuildController extends AbstractLogEnabled {
+
+    /**
+     * @plexus.requirement
+     */
+    private ContinuumStore store;
+
+    /**
+     * @plexus.requirement
+     */
+    private ContinuumNotificationDispatcher notifierDispatcher;
+
+    /**
+     * @plexus.requirement
+     */
+    private ActionManager actionManager;
+
+    /**
+     * @plexus.requirement
+     */
+    private WorkingDirectoryService workingDirectoryService;
+
+    
+    public void build( Project project, BuildDefinition buildDefinition, int trigger )
+    {
+
+        long startTime = System.currentTimeMillis();
+
+        // ----------------------------------------------------------------------
+        // Initialize the context
+        // ----------------------------------------------------------------------
+
+        // if these calls fail we're screwed anyway
+        // and it will only be logged through the logger.
+
+
+        BuildResult build = null;
+
+        // ----------------------------------------------------------------------
+        // TODO: Centralize the error handling from the SCM related actions.
+        // ContinuumScmResult should return a ContinuumScmResult from all
+        // methods, even in a case of failure.
+        // ----------------------------------------------------------------------
+
+        try
+        {
+            notifierDispatcher.buildStarted( project );
+
+            Map actionContext = new HashMap();
+
+            actionContext.put( AbstractDistributedContinuumAction.KEY_PROJECT, project );
+
+            actionContext.put( AbstractDistributedContinuumAction.KEY_BUILD_DEFINITION, buildDefinition );
+
+            actionContext.put( AbstractContinuumAction.KEY_TRIGGER, new Integer( trigger ) );
+
+            ScmResult scmResult = null;
+
+            try
+            {
+                actionManager.lookup( "check-working-directory" ).execute( actionContext );
+
+                boolean workingDirectoryExists = AbstractContinuumAction.getBoolean( actionContext,
+                                                                                     AbstractContinuumAction.KEY_WORKING_DIRECTORY_EXISTS );
+
+                if ( workingDirectoryExists )
+                {
+                    actionManager.lookup( "update-working-directory-from-scm" ).execute( actionContext );
+
+                    scmResult = AbstractContinuumAction.getUpdateScmResult( actionContext, null );
+                }
+                else
+                {
+                    actionContext.put( AbstractContinuumAction.KEY_WORKING_DIRECTORY,
+                                       workingDirectoryService.getWorkingDirectory( project ).getAbsolutePath() );
+
+                    actionManager.lookup( "checkout-project" ).execute( actionContext );
+
+                    scmResult = AbstractContinuumAction.getCheckoutResult( actionContext, null );
+                }
+
+                // ----------------------------------------------------------------------
+                // Check to see if there was a error while checking out/updating the project
+                // ----------------------------------------------------------------------
+
+                if ( scmResult == null || !scmResult.isSuccess() )
+                {
+                    // scmResult must be converted before sotring it because jpox modify value of all fields to null
+                    String error = convertScmResultToError( scmResult );
+
+                    build = makeAndStoreBuildResult( project, scmResult, startTime, trigger );
+
+                    build.setError( error );
+
+                    store.updateBuildResult( build );
+
+                    build = store.getBuildResult( build.getId() );
+
+                    project.setState( build.getState() );
+
+                    store.updateProject( project );
+
+                    return;
+                }
+
+                actionContext.put( AbstractContinuumAction.KEY_UPDATE_SCM_RESULT, scmResult );
+
+                scmResult = (ScmResult) actionContext.get( AbstractContinuumAction.KEY_UPDATE_SCM_RESULT );
+
+                actionManager.lookup( "update-project-from-working-directory" ).execute( actionContext );
+
+                actionManager.lookup( "execute-builder" ).execute( actionContext );
+
+                String s = (String) actionContext.get( AbstractContinuumAction.KEY_BUILD_ID );
+
+                if ( s != null )
+                {
+                    build = store.getBuildResult( Integer.valueOf( s ).intValue() );
+                }
+            }
+            catch ( Throwable e )
+            {
+                getLogger().error( "Error while building project.", e );
+
+                String s = (String) actionContext.get( AbstractContinuumAction.KEY_BUILD_ID );
+
+                if ( s != null )
+                {
+                    build = store.getBuildResult( Integer.valueOf( s ).intValue() );
+                }
+                else
+                {
+                    build = makeAndStoreBuildResult( project, scmResult, startTime, trigger );
+                }
+
+                // This can happen if the "update project from scm" action fails
+
+                String error = null;
+
+                if ( e instanceof ContinuumScmException )
+                {
+                    ContinuumScmException ex = (ContinuumScmException) e;
+
+                    ScmResult result = ex.getResult();
+
+                    if ( result != null )
+                    {
+                        error = convertScmResultToError( result );
+                    }
+
+                }
+                if ( error == null )
+                {
+                    error = ContinuumUtils.throwableToString( e );
+                }
+
+                build.setError( error );
+
+                store.updateBuildResult( build );
+
+                build = store.getBuildResult( build.getId() );
+
+                project.setState( build.getState() );
+
+                store.updateProject( project );
+            }
+        }
+        catch ( Exception ex )
+        {
+            if ( !Thread.interrupted() )
+            {
+                getLogger().error( "Internal error while building the project.", ex );
+            }
+        }
+        finally
+        {
+            try
+            {
+                project = store.getProject( project.getId() );
+            }
+            catch ( ContinuumStoreException ex )
+            {
+                getLogger().error( "Internal error while building the project.", ex );
+            }
+
+            if ( project.getState() != ContinuumProjectState.NEW &&
+                 project.getState() != ContinuumProjectState.OK &&
+                 project.getState() != ContinuumProjectState.FAILED &&
+                 project.getState() != ContinuumProjectState.ERROR )
+            {
+                try
+                {
+                    project.setState( ContinuumProjectState.ERROR );
+
+                    store.updateProject( project );
+                }
+                catch ( ContinuumStoreException e )
+                {
+                    getLogger().error( "Internal error while storing the project.", e );
+                }
+            }
+
+            notifierDispatcher.buildComplete( project, build );
+        }
+    }
+
+    private String convertScmResultToError( ScmResult result )
+    {
+        String error = "";
+
+        if ( result == null )
+        {
+            error = "Scm result is null.";
+        }
+        else
+        {
+            if ( result.getCommandLine() != null )
+            {
+                error = "Command line: " + StringUtils.clean( result.getCommandLine() ) +
+                    System.getProperty( "line.separator" );
+            }
+
+            if ( result.getProviderMessage() != null )
+            {
+                error = "Provider message: " + StringUtils.clean( result.getProviderMessage() ) +
+                    System.getProperty( "line.separator" );
+            }
+
+            if ( result.getCommandOutput() != null )
+            {
+                error += "Command output: " + System.getProperty( "line.separator" );
+                error += "-------------------------------------------------------------------------------" +
+                    System.getProperty( "line.separator" );
+                error += StringUtils.clean( result.getCommandOutput() ) + System.getProperty( "line.separator" );
+                error += "-------------------------------------------------------------------------------" +
+                    System.getProperty( "line.separator" );
+            }
+
+            if ( result.getException() != null )
+            {
+                error += "Exception:" + System.getProperty( "line.separator" );
+                error += result.getException();
+            }
+        }
+
+        return error;
+    }
+
+    // ----------------------------------------------------------------------
+    //
+    // ----------------------------------------------------------------------
+
+    private BuildResult makeAndStoreBuildResult( Project project, ScmResult scmResult, long startTime, int trigger )
+        throws ContinuumStoreException
+    {
+        BuildResult build = new BuildResult();
+
+        build.setState( ContinuumProjectState.ERROR );
+
+        build.setTrigger( trigger );
+
+        build.setStartTime( startTime );
+
+        build.setEndTime( System.currentTimeMillis() );
+
+        build.setScmResult( scmResult );
+
+        store.addBuildResult( project, build );
+
+        return store.getBuildResult( build.getId() );
+    }
+
+}

Added: geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/ExecuteDistributedBuilderContinuumAction.java
URL: http://svn.apache.org/viewcvs/geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/ExecuteDistributedBuilderContinuumAction.java?rev=332233&view=auto
==============================================================================
--- geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/ExecuteDistributedBuilderContinuumAction.java (added)
+++ geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/ExecuteDistributedBuilderContinuumAction.java Wed Nov  9 22:21:11 2005
@@ -0,0 +1,152 @@
+/**
+ *
+ * Copyright 2004 The Apache Software Foundation
+ *
+ *  Licensed 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.
+ */
+package org.apache.geronimo.gbuild.agent;
+
+import org.apache.maven.continuum.execution.ContinuumBuildExecutionResult;
+import org.apache.maven.continuum.execution.ContinuumBuildExecutor;
+import org.apache.maven.continuum.execution.manager.BuildExecutorManager;
+import org.apache.maven.continuum.model.project.BuildDefinition;
+import org.apache.maven.continuum.model.project.BuildResult;
+import org.apache.maven.continuum.model.project.Project;
+import org.apache.maven.continuum.model.scm.ScmResult;
+import org.apache.maven.continuum.notification.ContinuumNotificationDispatcher;
+import org.apache.maven.continuum.project.ContinuumProjectState;
+import org.apache.maven.continuum.store.ContinuumStore;
+import org.apache.maven.continuum.utils.ContinuumUtils;
+
+import java.io.File;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ExecuteDistributedBuilderContinuumAction extends AbstractDistributedContinuumAction {
+
+    // ----------------------------------------------------------------------
+    // Keys for the values that can be in the context
+    // ----------------------------------------------------------------------
+
+    public static final String KEY_BUILD_OUTPUT_FILE = "build-output-file";
+
+    /**
+     * @plexus.requirement
+     */
+    private BuildExecutorManager buildExecutorManager;
+
+    /**
+     * @plexus.requirement
+     */
+    private ContinuumStore store;
+
+    /**
+     * @plexus.requirement
+     */
+    private ContinuumNotificationDispatcher notifier;
+
+
+    public void execute(Map context)
+            throws Exception {
+        // ----------------------------------------------------------------------
+        // Get parameters from the context
+        // ----------------------------------------------------------------------
+
+        Project project = getProject(context);
+
+        int trigger = getTrigger(context);
+
+        ScmResult scmResult = getUpdateScmResult(context);
+
+        ContinuumBuildExecutor buildExecutor = buildExecutorManager.getBuildExecutor(project.getExecutorId());
+
+        // ----------------------------------------------------------------------
+        // Make the build
+        // ----------------------------------------------------------------------
+
+        BuildResult build = new BuildResult();
+
+        build.setStartTime(new Date().getTime());
+
+        build.setState(ContinuumProjectState.BUILDING);
+
+        build.setTrigger(trigger);
+
+        BuildDefinition buildDefinition = getBuildDefinition(context);
+
+        build.setScmResult(scmResult);
+
+        store.addBuildResult(project, build);
+
+        context.put(KEY_BUILD_ID, Integer.toString(build.getId()));
+
+        build = store.getBuildResult(build.getId());
+
+        try {
+            notifier.runningGoals(project, build);
+
+            File buildOutputFile = getBuildOutputFile( context );
+
+            ContinuumBuildExecutionResult result = buildExecutor.build(project, buildDefinition, buildOutputFile);
+
+            build.setState(result.getExitCode() == 0 ? ContinuumProjectState.OK : ContinuumProjectState.FAILED);
+
+            build.setExitCode(result.getExitCode());
+        }
+        catch (Throwable e) {
+            getLogger().error("Error running build", e);
+
+            build.setState(ContinuumProjectState.ERROR);
+
+            build.setError(ContinuumUtils.throwableToString(e));
+        }
+        finally {
+            build.setEndTime(new Date().getTime());
+
+            if (build.getState() == ContinuumProjectState.OK) {
+                project.setBuildNumber(project.getBuildNumber() + 1);
+            }
+
+            project.setLatestBuildId(build.getId());
+
+            build.setBuildNumber(project.getBuildNumber());
+
+            if (build.getState() != ContinuumProjectState.OK && build.getState() != ContinuumProjectState.FAILED && build.getState() != ContinuumProjectState.ERROR) {
+                build.setState(ContinuumProjectState.ERROR);
+            }
+
+            // ----------------------------------------------------------------------
+            // Copy over the build result
+            // ----------------------------------------------------------------------
+
+            store.updateBuildResult(build);
+
+            build = store.getBuildResult(build.getId());
+
+            store.updateProject(project);
+
+            notifier.goalsCompleted(project, build);
+        }
+    }
+
+    private File getBuildOutputFile(Map context) {
+
+        String fileName = getString( context, KEY_BUILD_OUTPUT_FILE );
+
+        return new File( fileName );
+    }
+
+}

Added: geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/Main.java
URL: http://svn.apache.org/viewcvs/geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/Main.java?rev=332233&view=auto
==============================================================================
--- geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/Main.java (added)
+++ geronimo/gbuild/trunk/src/main/java/org/apache/geronimo/gbuild/agent/Main.java Wed Nov  9 22:21:11 2005
@@ -0,0 +1,35 @@
+/**
+ *
+ * Copyright 2004 The Apache Software Foundation
+ *
+ *  Licensed 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.
+ */
+package org.apache.geronimo.gbuild.agent;
+
+import org.codehaus.plexus.embed.Embedder;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class Main {
+
+    public static void main(String[] args) throws Exception {
+        Embedder embedder = new Embedder();
+        embedder.start();
+        BuildAgent buildAgent = (BuildAgent) embedder.lookup(BuildAgent.ROLE);
+
+        Thread agentThread = new Thread(buildAgent);
+        agentThread.start();
+    }
+
+}

Added: geronimo/gbuild/trunk/src/main/resources/META-INF/plexus/components.xml
URL: http://svn.apache.org/viewcvs/geronimo/gbuild/trunk/src/main/resources/META-INF/plexus/components.xml?rev=332233&view=auto
==============================================================================
--- geronimo/gbuild/trunk/src/main/resources/META-INF/plexus/components.xml (added)
+++ geronimo/gbuild/trunk/src/main/resources/META-INF/plexus/components.xml Wed Nov  9 22:21:11 2005
@@ -0,0 +1,23 @@
+<component-set>
+    <components>
+        <component>
+            <role>org.codehaus.plexus.action.Action</role>
+            <role-hint>execute-builder</role-hint>
+            <implementation>org.apache.maven.continuum.core.action.ExecuteBuilderContinuumAction</implementation>
+            <requirements>
+                <requirement>
+                    <role>org.apache.maven.continuum.configuration.ConfigurationService</role>
+                </requirement>
+                <requirement>
+                    <role>org.apache.maven.continuum.execution.manager.BuildExecutorManager</role>
+                </requirement>
+                <requirement>
+                    <role>org.apache.maven.continuum.notification.ContinuumNotificationDispatcher</role>
+                </requirement>
+                <requirement>
+                    <role>org.apache.maven.continuum.store.ContinuumStore</role>
+                </requirement>
+            </requirements>
+        </component>
+    </components>
+</component-set>