Java tutorial
/*-------------------------------------------------------------------------- * Copyright 2008 utgenome.org * * 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. *--------------------------------------------------------------------------*/ //-------------------------------------- // utgb-shell Project // // Maven.java // Since: Jan 11, 2008 // // $URL$ // $Author$ //-------------------------------------- package org.utgenome.shell; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; import java.util.Map.Entry; import java.util.Properties; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.apache.maven.cli.MavenCli; import org.xerial.util.StringUtil; import org.xerial.util.io.StandardErrorStream; import org.xerial.util.io.StandardOutputStream; import org.xerial.util.log.Logger; /** * Maven utility * * @author leo * */ public class Maven extends UTGBShellCommand { private static Logger _logger = Logger.getLogger(Maven.class); public static void runMaven(String arg) throws UTGBShellException { runMaven(tokenizeCommandLineArgument(arg)); } public static void runMaven(String arg, File workingDir) throws UTGBShellException { runMaven(arg, workingDir, null); } public static void runMaven(String arg, File workingDir, Properties sytemProperties) throws UTGBShellException { runMaven(tokenizeCommandLineArgument(arg), workingDir, sytemProperties); } public static void runMaven(String[] args) throws UTGBShellException { runMaven(args, null, null); } private static abstract class ProcessOutputReader implements Runnable { private final BufferedReader reader; public ProcessOutputReader(InputStream in) { reader = new BufferedReader(new InputStreamReader(in)); } public abstract void output(String line); public void run() { try { String line; while ((line = reader.readLine()) != null) { output(line); } } catch (IOException e) { // If the process is already terminated, IOException (bad file descriptor) might be reported. _logger.debug(e); } } } public static class CommandExecutor { final ExecutorService threadManager = Executors.newFixedThreadPool(2); Process proc = null; Future<?> stdoutReader; Future<?> stderrReader; private void dispose() { if (proc != null) { proc.destroy(); proc = null; } threadManager.shutdown(); try { while (!threadManager.awaitTermination(1L, TimeUnit.SECONDS)) { } } catch (InterruptedException e) { _logger.error(e); } } public int execCommand(String commandLine, String[] envp, File workingDir) throws IOException { try { if (_logger.isDebugEnabled()) _logger.debug(commandLine); proc = Runtime.getRuntime().exec(commandLine, envp, workingDir); // pipe the program's stdout and stderr to the logger stdoutReader = threadManager.submit(new ProcessOutputReader(proc.getInputStream()) { @Override public void output(String line) { _logger.info(line); } }); stderrReader = threadManager.submit(new ProcessOutputReader(proc.getErrorStream()) { @Override public void output(String line) { _logger.error(line); } }); int ret = proc.waitFor(); return ret; } catch (InterruptedException e) { _logger.error(e); return 0; } finally { dispose(); } } public static int exec(String commandLine) throws IOException { return exec(commandLine, null, null); } public static int exec(String commandLine, String[] envp, File workingDir) throws IOException { CommandExecutor e = new CommandExecutor(); return e.execCommand(commandLine, envp, workingDir); } } public static String[] prepareEnvironmentVariables(File mavenHome) { Properties env = new Properties(); for (Entry<String, String> eachEnv : System.getenv().entrySet()) { env.setProperty(eachEnv.getKey(), eachEnv.getValue()); } if (!env.contains("JAVA_HOME") || env.getProperty("JAVA_HOME").contains("jre")) { env.setProperty("JAVA_HOME", System.getProperty("java.home")); } if (mavenHome != null && !env.contains("M2_HOME")) { env.setProperty("M2_HOME", mavenHome.getAbsolutePath()); } String[] envp = new String[env.size()]; int index = 0; for (Object each : env.keySet()) { String key = each.toString(); envp[index++] = String.format("%s=%s", key, env.getProperty(key)); } _logger.trace("environment variables: " + env); return envp; } private static boolean addedShutdownHook = false; public static int runMaven(String[] args, File workingDir, Properties systemProperties) throws UTGBShellException { // Preserve the context class loader ClassLoader cl = Thread.currentThread().getContextClassLoader(); // preserve the current system properties Properties prevSystemProperties = (Properties) System.getProperties().clone(); try { // add the hook for killing the Maven process when ctrl+C is pressed if (!addedShutdownHook) { addedShutdownHook = true; Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { _logger.debug("shutdown hook is called"); } }); } MavenCli maven = new MavenCli(); if (workingDir == null) workingDir = new File("."); if (systemProperties != null) { // add the user-specified system properties for (Object key : systemProperties.keySet()) { System.setProperty(key.toString(), systemProperties.get(key).toString()); } } int returnCode = maven.doMain(args, workingDir.getPath(), new PrintStream(new StandardOutputStream()), new PrintStream(new StandardErrorStream())); if (returnCode != 0) throw new UTGBShellException("error: " + returnCode); return returnCode; } catch (Exception e) { throw new UTGBShellException(e); } finally { Thread.currentThread().setContextClassLoader(cl); // reset the system properties if (prevSystemProperties != null) System.setProperties(prevSystemProperties); } } public static String[] tokenizeCommandLineArgument(String arg) { return StringUtil.tokenizeCommandLineArgument(arg); } @Override public void execute(String[] args) throws Exception { runMaven(args); } @Override public String name() { return "maven"; } @Override public String getOneLinerDescription() { return "execute maven tasks"; } }