目录
背景
一般在使用maven进行程序打包过程中最常用方法是使用maven-assembly-plugin或者maven-shade-plugin插件。最近在做项目的时候需要对用户所指定git仓库中代码进行编译打包,由于无法获取Jenkins较高授权,因此只能将用户代码从git仓库中拉取到本地进行打包,这种情况下就需要将编译打包过程集成到java代码中,因此调研了几种集成形式,以下提供测试代码。
Maven集成
package com.w3sun.it.maven; import com.google.common.base.Charsets; import com.google.common.base.Strings; import com.google.common.io.Files; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; import java.nio.file.Paths; /** * @author neters */ public class ProcessMavenBuilder { private static final Logger logger = LoggerFactory.getLogger(ProcessMavenBuilder.class); private static final String CMD = "mvn"; private static final String DEFAULT_MAVEN_HOME_ENV = "M2_HOME"; private static final String DEFAULT_MAVEN_HOME_PROPERTY = "maven.home"; private File logFile = Paths.get("/var/log/mvnit.log").toFile(); public ProcessMavenBuilder() throws IOException { //empty the constructor } public ProcessMavenBuilder(File logFile) throws IOException { this.logFile = logFile; } public File getLogFile() { return logFile; } /** * Generate the default maven install directory path for detecting the mvn command. * * @return mvn command path in String by default */ public String getMavenCommand() { return getMavenCommand(null, null); } /** * Method overload for detecting maven install directory and the mvn command. * * @param mavenHomeEnv M2_HOME * @return mvn command path in String */ public String getMavenCommand(String mavenHomeEnv) { return getMavenCommand(null, mavenHomeEnv); } /** * Generate the complete path for `mvn` command. * * @param mavenHomeInProperty {maven.home} by default * @param mavenHomeInEnvironment {M2_HOME} by default * @return */ public String getMavenCommand(String mavenHomeInProperty, String mavenHomeInEnvironment) { String mavenHomeProp = Strings.isNullOrEmpty(mavenHomeInProperty) ? DEFAULT_MAVEN_HOME_PROPERTY : mavenHomeInProperty; String mavenHomeEnv = Strings.isNullOrEmpty(mavenHomeInEnvironment) ? DEFAULT_MAVEN_HOME_ENV : mavenHomeInEnvironment; String mavenHome = System.getProperty(mavenHomeProp); if (Strings.isNullOrEmpty(mavenHome)) { mavenHome = System.getenv(mavenHomeEnv); if (Strings.isNullOrEmpty(mavenHome)) { return StringUtils.EMPTY; } } StringBuilder sb = new StringBuilder(mavenHome); return sb.append(File.separator) .append("bin") .append(File.separator) .append(CMD) .toString(); } /** * Run the build process in the `workingDirectory` according to specified goals. * * @param goals plugin goals * @param workingDirectory current project or sub-project work directory */ public void build(String goals, String workingDirectory) { build(null, goals, workingDirectory); } /** * Run the build process in the `workingDirectory` according to specified goals. * * @param mavenCommand complete path of {mvn} command * @param goals plugin goals * @param workingDirectory current project or sub-project work directory */ public void build(String mavenCommand, String goals, String workingDirectory) { String mvn = Strings.isNullOrEmpty(mavenCommand) ? getMavenCommand() : mavenCommand; ProcessBuilder processBuilder = new ProcessBuilder(mvn, goals); processBuilder.directory(Paths.get(workingDirectory).toFile()); try { redirectLogToFile(processBuilder); Process process = processBuilder.start(); int exitCode = process.waitFor(); System.out.println(Files.toString(this.logFile, Charsets.UTF_8)); if (0 != exitCode) { //compile failed } else { //compile successed } } catch (Exception e) { String error = String.format("build error!", e.getMessage()); logger.error(error); } } /** * Redirect log generated by maven package process, either error or sucess message. * * @param processBuilder ProcessBuilder * @throws IOException IOException */ private void redirectLogToFile(ProcessBuilder processBuilder) throws IOException { processBuilder.redirectErrorStream(true); if (!logFile.exists()) { boolean newFile = logFile.createNewFile(); if (newFile) { String info = String.format("new log file was generated!", "redirect log to file!"); logger.info(info); } } processBuilder.redirectOutput(logFile); } }
上述代码效果和执行脚本代码类似,使用了maven-assembly-plugin进行打包:
/** * @author neters */ public class MavenBuild { public static void main(String[] args) { try { ProcessMavenBuilder builder = new ProcessMavenBuilder(new File("/Users/neters/demos/it/log.dat")); builder.build("assembly:assembly", "/Users/neters/demos/it"); } catch (IOException e) { e.printStackTrace(); } } }
效果
虽然可以进行打包,但是这种方式使用过程中存在一些不可控的因素,比如还需要用户指定打包插件类别,插件会对系统环境造成污染等。如果在要求不太高的环境或者场景中可以考虑上述方式,如果对系统环境或者打包过程中有洁癖要求不建议此种方式。
转载请注明:雪后西塘 » Maven集成 – ProcessBuilder