You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by jd...@apache.org on 2006/10/13 00:06:12 UTC

svn commit: r463460 - in /geronimo/genesis/trunk/plugins/plugin-support/src/main/java/org/apache/geronimo/genesis/ant: JavaLauncherMojoSupport.java OptionSet.java

Author: jdillon
Date: Thu Oct 12 15:06:11 2006
New Revision: 463460

URL: http://svn.apache.org/viewvc?view=rev&rev=463460
Log:
Moved JavaLauncher* from j2eetck plugin

Added:
    geronimo/genesis/trunk/plugins/plugin-support/src/main/java/org/apache/geronimo/genesis/ant/JavaLauncherMojoSupport.java   (with props)
    geronimo/genesis/trunk/plugins/plugin-support/src/main/java/org/apache/geronimo/genesis/ant/OptionSet.java   (with props)

Added: geronimo/genesis/trunk/plugins/plugin-support/src/main/java/org/apache/geronimo/genesis/ant/JavaLauncherMojoSupport.java
URL: http://svn.apache.org/viewvc/geronimo/genesis/trunk/plugins/plugin-support/src/main/java/org/apache/geronimo/genesis/ant/JavaLauncherMojoSupport.java?view=auto&rev=463460
==============================================================================
--- geronimo/genesis/trunk/plugins/plugin-support/src/main/java/org/apache/geronimo/genesis/ant/JavaLauncherMojoSupport.java (added)
+++ geronimo/genesis/trunk/plugins/plugin-support/src/main/java/org/apache/geronimo/genesis/ant/JavaLauncherMojoSupport.java Thu Oct 12 15:06:11 2006
@@ -0,0 +1,416 @@
+/*
+ * 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.
+ */
+
+package org.apache.geronimo.genesis.ant;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProject;
+import org.apache.tools.ant.taskdefs.Java;
+import org.apache.tools.ant.types.Path;
+import org.codehaus.plexus.util.FileUtils;
+
+import org.apache.geronimo.genesis.util.ObjectHolder;
+
+/**
+ * Support for mojos that launch Java processes.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class JavaLauncherMojoSupport
+    extends AntMojoSupport
+{
+    //
+    // TODO: Use AntHelper component and extend from MojoSupport
+    //
+    
+    private Timer timer = new Timer(true);
+
+    /**
+     * Set the maximum memory for the forked JVM.
+     *
+     * @parameter expression="${maximumMemory}"
+     */
+    private String maximumMemory = null;
+    
+    /**
+     * The base working directory where process will be started from, a sub-directory
+     * the process name will be used for the effective working directory.
+     *
+     * @parameter expression="${project.build.directory}"
+     * @required
+     */
+    protected File baseWorkingDirectory = null;
+
+    /**
+     * Enable logging mode.
+     *
+     * @parameter expression="${logOutput}" default-value="false"
+     */
+    protected boolean logOutput = false;
+
+    /**
+     * Flag to control if we background the process or block Maven execution.
+     *
+     * @parameter default-value="false"
+     * @required
+     */
+    protected boolean background = false;
+
+    /**
+     * Timeout for the process in seconds.
+     *
+     * @parameter expression="${timeout}" default-value="-1"
+     */
+    protected int timeout = -1;
+
+    /**
+     * Time in seconds to wait while verifing that the process has started (if there is custom validation).
+     *
+     * @parameter expression="${verifyTimeout}" default-value="-1"
+     */
+    private int verifyTimeout = -1;
+
+    /**
+     * An array of option sets which can be enabled by setting <tt>options</tt>.
+     *
+     * @parameter
+     */
+    protected OptionSet[] optionSets = null;
+
+    /**
+     * A comma seperated list of <tt>optionSets</tt> to enabled.
+     *
+     * @parameter expression="${options}"
+     */
+    protected String options = null;
+
+    /**
+     * Map of of plugin artifacts.
+     *
+     * @parameter expression="${plugin.artifactMap}"
+     * @required
+     * @readonly
+     */
+    protected Map pluginArtifactMap = null;
+
+    protected void doExecute() throws Exception {
+        log.info("Starting " + getProcessTitle() + "...");
+
+        final Java java = (Java)createTask("java");
+
+        File workingDirectory = getWorkingDirectory();
+        FileUtils.forceMkdir(workingDirectory);
+        java.setDir(workingDirectory);
+
+        java.setFailonerror(true);
+        java.setFork(true);
+
+        if (maximumMemory != null) {
+            java.setMaxmemory(maximumMemory);
+        }
+        
+        if (timeout > 0) {
+            log.info("Timeout after: " + timeout + " seconds");
+
+            java.setTimeout(new Long(timeout * 1000));
+        }
+
+        if (logOutput) {
+            File file = getLogFile();
+            log.info("Redirecting output to: " + file);
+            FileUtils.forceMkdir(file.getParentFile());
+
+            java.setLogError(true);
+            java.setOutput(file);
+        }
+
+        java.setClassname(getClassName());
+        setClassPath(java.createClasspath());
+
+        applyOptionSets(java);
+
+        customizeJava(java);
+
+        // Holds any exception that was thrown during startup
+        final ObjectHolder errorHolder = new ObjectHolder();
+
+        // Start the process in a seperate thread
+        Thread t = new Thread(getProcessTitle() + " Runner") {
+            public void run() {
+                try {
+                    java.execute();
+                }
+                catch (Exception e) {
+                    errorHolder.set(e);
+
+                    //
+                    // NOTE: Don't log here, as when the JVM exists an exception will get thrown by Ant
+                    //       but that should be fine.
+                    //
+                }
+            }
+        };
+        t.start();
+
+        log.debug("Waiting for " + getProcessTitle() + "...");
+
+        // Setup a callback to time out verification
+        final ObjectHolder verifyTimedOut = new ObjectHolder();
+
+        TimerTask timeoutTask = new TimerTask() {
+            public void run() {
+                verifyTimedOut.set(Boolean.TRUE);
+            }
+        };
+
+        if (verifyTimeout > 0) {
+            log.debug("Starting verify timeout task; triggers in: " + verifyTimeout + "s");
+            timer.schedule(timeoutTask, verifyTimeout * 1000);
+        }
+        
+        // Verify the process has started
+        boolean started = false;
+        while (!started) {
+            if (verifyTimedOut.isSet()) {
+                throw new MojoExecutionException("Unable to verify if the " + getProcessTitle() + " process was started in the given time");
+            }
+
+            if (errorHolder.isSet()) {
+                throw new MojoExecutionException("Failed to launch " + getProcessTitle(), (Throwable)errorHolder.get());
+            }
+
+            try {
+                started = verifyProcessStarted();
+            }
+            catch (Exception e) {
+                // ignore
+            }
+
+            Thread.sleep(1000);
+        }
+
+        log.info(getProcessTitle() + " started");
+
+        if (!background) {
+            log.info("Waiting for " + getProcessTitle() + " to shutdown...");
+
+            t.join();
+        }
+    }
+
+    protected Artifact getPluginArtifact(final String name) throws MojoExecutionException {
+        assert name != null;
+
+        Artifact artifact = (Artifact)pluginArtifactMap.get(name);
+        if (artifact == null) {
+            throw new MojoExecutionException("Unable to locate '" + name + "' in the list of plugin artifacts");
+        }
+
+        return artifact;
+    }
+
+    protected void appendArtifactFile(final Path classpath, final String name) throws MojoExecutionException {
+        assert classpath != null;
+        assert name != null;
+
+        appendArtifact(classpath, getPluginArtifact(name));
+    }
+
+    protected void appendArtifact(final Path classpath, final Artifact artifact) throws MojoExecutionException {
+        assert classpath != null;
+        assert artifact != null;
+
+        File file = artifact.getFile();
+        if (file == null) {
+            throw new MojoExecutionException("Artifact does not have an attached file: " + artifact);
+        }
+        
+        classpath.createPathElement().setLocation(file);
+    }
+
+    private void applyOptionSets(final Java java) throws MojoExecutionException {
+        assert java != null;
+
+        //
+        // TODO: Add optionSet activation
+        //
+
+        // Apply option sets
+        if (options != null  && (optionSets == null || optionSets.length == 0)) {
+            throw new MojoExecutionException("At least one optionSet must be defined to select one using options");
+        }
+        else if (options == null) {
+            options = "default";
+        }
+
+        if (optionSets != null && optionSets.length != 0) {
+            OptionSet[] sets = selectOptionSets();
+
+            for (int i=0; i < sets.length; i++) {
+                if (log.isDebugEnabled()) {
+                    log.debug("Selected option set: " + sets[i]);
+                }
+                else {
+                    log.info("Selected option set: " + sets[i].getId());
+                }
+
+                String[] options = sets[i].getOptions();
+                if (options != null) {
+                    for (int j=0; j < options.length; j++) {
+                        java.createJvmarg().setValue(options[j]);
+                    }
+                }
+
+                Properties props = sets[i].getProperties();
+                if (props != null) {
+                    Iterator iter = props.keySet().iterator();
+                    while (iter.hasNext()) {
+                        String name = (String)iter.next();
+                        String value = props.getProperty(name);
+
+                        setSystemProperty(java, name, value);
+                    }
+                }
+            }
+        }
+    }
+
+    private OptionSet[] selectOptionSets() throws MojoExecutionException {
+        // Make a map of the option sets and validate ids
+        Map map = new HashMap();
+        for (int i=0; i<optionSets.length; i++) {
+            if (log.isDebugEnabled()) {
+                log.debug("Checking option set: " + optionSets[i]);
+            }
+
+            String id = optionSets[i].getId();
+
+            if (id == null && optionSets.length > 1) {
+                throw new MojoExecutionException("Must specify id for optionSet when more than one optionSet is configured");
+            }
+            else if (id == null && optionSets.length == 1) {
+                id = "default";
+                optionSets[i].setId(id);
+            }
+
+            assert id != null;
+            id = id.trim();
+
+            if (map.containsKey(id)) {
+                throw new MojoExecutionException("Must specify unique id for optionSet: " + optionSets[i]);
+            }
+            map.put(id, optionSets[i]);
+        }
+
+        StringTokenizer stok = new StringTokenizer(options, ",");
+
+        List selected = new ArrayList();
+        while (stok.hasMoreTokens()) {
+            String id = stok.nextToken();
+            OptionSet set = (OptionSet)map.get(options);
+
+            if (set == null) {
+                if ("default".equals(options)) {
+                    log.debug("Default optionSet selected, but no optionSet defined with that id; ignoring");
+                }
+                else {
+                    throw new MojoExecutionException("Missing optionSet for id: " + id);
+                }
+            }
+            else {
+                selected.add(set);
+            }
+        }
+
+        return (OptionSet[]) selected.toArray(new OptionSet[selected.size()]);
+    }
+
+    //
+    // MojoSupport Hooks
+    //
+
+    /**
+     * The maven project.
+     *
+     * @parameter expression="${project}"
+     * @required
+     * @readonly
+     */
+    protected MavenProject project = null;
+
+    protected MavenProject getProject() {
+        return project;
+    }
+
+    /**
+     * @parameter expression="${localRepository}"
+     * @readonly
+     * @required
+     */
+    protected ArtifactRepository artifactRepository = null;
+
+    protected ArtifactRepository getArtifactRepository() {
+        return artifactRepository;
+    }
+
+    //
+    // Sub-class API
+    //
+
+    protected abstract String getProcessName();
+
+    protected String getProcessTitle() {
+        return getProcessName();
+    }
+
+    protected File getWorkingDirectory() {
+        return new File(baseWorkingDirectory, getProcessName());
+    }
+
+    protected File getLogFile() {
+        return new File(getWorkingDirectory(), getProcessName() + ".log");
+    }
+
+    protected abstract String getClassName();
+
+    protected abstract void setClassPath(Path classpath) throws Exception;
+
+    protected void customizeJava(final Java java) throws MojoExecutionException {
+        assert java != null;
+
+        // nothing by default
+    }
+    
+    protected boolean verifyProcessStarted() throws Exception {
+        return true;
+    }
+}

Propchange: geronimo/genesis/trunk/plugins/plugin-support/src/main/java/org/apache/geronimo/genesis/ant/JavaLauncherMojoSupport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/genesis/trunk/plugins/plugin-support/src/main/java/org/apache/geronimo/genesis/ant/JavaLauncherMojoSupport.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/genesis/trunk/plugins/plugin-support/src/main/java/org/apache/geronimo/genesis/ant/JavaLauncherMojoSupport.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/genesis/trunk/plugins/plugin-support/src/main/java/org/apache/geronimo/genesis/ant/OptionSet.java
URL: http://svn.apache.org/viewvc/geronimo/genesis/trunk/plugins/plugin-support/src/main/java/org/apache/geronimo/genesis/ant/OptionSet.java?view=auto&rev=463460
==============================================================================
--- geronimo/genesis/trunk/plugins/plugin-support/src/main/java/org/apache/geronimo/genesis/ant/OptionSet.java (added)
+++ geronimo/genesis/trunk/plugins/plugin-support/src/main/java/org/apache/geronimo/genesis/ant/OptionSet.java Thu Oct 12 15:06:11 2006
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+package org.apache.geronimo.genesis.ant;
+
+import java.util.Properties;
+import java.util.Arrays;
+
+/**
+ * Container for a set of options to be passed to a JVM.
+ *
+ * @version $Rev$ $Date$
+ */
+public class OptionSet
+{
+    /**
+     * @parameter
+     */
+    private String id = null;
+
+    /**
+     * @parameter
+     */
+    private String[] options = null;
+
+    /**
+     * @parameter
+     */
+    private Properties properties = null;
+
+    public String toString() {
+        return "{ id=" + id +
+               ", options=" + (options != null ? Arrays.asList(options) : null) +
+               ", properties=" + properties +
+               " }";
+    }
+
+    public void setId(final String id) {
+        this.id = id;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setOptions(final String[] options) {
+        this.options = options;
+    }
+
+    public String[] getOptions() {
+        return options;
+    }
+
+    public Properties getProperties() {
+        return properties;
+    }
+
+    public void setProperties(final Properties properties) {
+        this.properties = properties;
+    }
+}
\ No newline at end of file

Propchange: geronimo/genesis/trunk/plugins/plugin-support/src/main/java/org/apache/geronimo/genesis/ant/OptionSet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/genesis/trunk/plugins/plugin-support/src/main/java/org/apache/geronimo/genesis/ant/OptionSet.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/genesis/trunk/plugins/plugin-support/src/main/java/org/apache/geronimo/genesis/ant/OptionSet.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain