目录
背景
一般在使用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
