【Maven】Maven手动发布jar到私服
【Maven】Maven手动发布jar到私服
工作中,常常需要把一些特殊的jar包,如:公司内部的定制的工具包,第三方客户的定制的服务包,还有一些非开源的jar,上传到公司的私服上。以便于管理,同时可以在多个项目组中共用。
手动发布命令
- 必选参数3个:url, file和repositoryId
# url: 仓库地址, file: jar包地址, repositoryId: 仓库名字,与settings.xml中的<server><id>保持一致
mvn deploy:deploy-file -Durl=http://10.0.0.100/repository/maven/tenmao-repo/ -Dfile=E:\data\demo-1.0-SNAPSHOT.jar -DrepositoryId=tenmao-repo
- 其他可选参数
# 常用的有groupId, artifactId, packaging和pomFile
mvn deploy:deploy-file -Durl=http://10.0.0.100/repository/maven/tenmao-repo/ -Dfile=E:\data\demo-1.0-SNAPSHOT.jar -DrepositoryId=tenmao-repo -DgroupId=com.tenmao -DartifactId=demo -Dversion=1.0-SNAPSHOT -Dpackaging=jar -DpomFile=E:\data\pom.xml
-
maven配置文件
settings.xml
<servers> <server> <id>tenmao-repo</id> <username>tenmao</username> <password>6ddf00d4f01611e99b226c92bf3ad140</password> </server> </servers> <profiles> <profile> <id>default</id> <activation> <activeByDefault>true</activeByDefault> </activation> <repositories> <repository> <id>tenmao-repo</id> <url>http://10.0.0.100/repository/maven/tenmao-repo</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> </profile> </profiles>
常见错误:
Return code is: 401, ReasonPhrase: Unauthorized.
常见有两个原因:
- 没有配置server的账号和密码(settings.xml)
- 参数漏掉了-DrepositoryId=maibao-snapshot
Return code is: 405, ReasonPhrase: PUT
错误原因:
- 上传 url 拼写错误
- 发布的私服,类型错误。应该使用hosted类型的nexus仓库
批量发布jar到私服
注意:上传的文件夹不能是 settings.xml
中配置的本地仓库目录
public class Deploy {
public static final String BASE_CMD = "cmd /c mvn "
+ " -s F:\\.m2\\settings.xml"
+ " deploy:deploy-file "
+ " -Durl=http://IP:PORT/nexus/content/repositories/maven-releases/ "
+ " -DrepositoryId=releases "
+ " -DgeneratePom=false";
public static final Pattern DATE_PATTERN = Pattern.compile("-[\\d]{8}\\.[\\d]{6}-");
public static final Runtime CMD = Runtime.getRuntime();
public static final Writer ERROR;
public static final ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(10);
public static final String glob = "glob:**/*.{pom}";
static {
Writer err = null;
try {
err = new OutputStreamWriter(new FileOutputStream("deploy-error.log"), "utf-8");
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
ERROR = err;
}
public static void main(String[] args) {
try {
//注意一定不能是本地仓库目录,将需要的上传的文件拷贝到临时目录
deloy("D:\\temp\\2\\common");
EXECUTOR_SERVICE.shutdown();
ERROR.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void error(String error) {
try {
System.err.println(error);
ERROR.write(error + "\n");
ERROR.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void deloy(String rootPath) throws Exception {
List<Path> match = match(glob, rootPath);
if (match != null && !match.isEmpty()) {
match.forEach(pom -> {
Path parentPath = pom.getParent();
File parentFile = parentPath.toFile();
File[] listFiles = parentFile.listFiles();
deloyFiles(listFiles);
});
}
}
public static void deloyFiles(File[] files) {
UploadFile upload = new UploadFile();
// 忽略日期快照版本,如 xxx-mySql-2.2.6-20170714.095105-1.jar
for (File file : files) {
String name = file.getName();
if (DATE_PATTERN.matcher(name).find()) {
// skip
} else if (name.endsWith(".pom")) {
upload.setPom(file);
} else if (name.endsWith("-javadoc.jar")) {
upload.setJavadoc(file);
} else if (name.endsWith("-sources.jar")) {
upload.setSource(file);
} else if (name.endsWith(".jar")) {
upload.setJar(file);
}
}
if (upload.getPom() != null) {
if (upload.getJar() != null) {
deploy(upload);
} else if (packingIsPom(upload.getPom())) {
deployPom(upload.getPom());
}
}
}
public static boolean packingIsPom(File pom) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(pom)));) {
String line;
while ((line = reader.readLine()) != null) {
if (line.trim().indexOf("<packaging>pom</packaging>") != -1) {
return true;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public static void deployPom(final File pom) {
EXECUTOR_SERVICE.execute(new Runnable() {
@Override
public void run() {
StringBuffer cmd = new StringBuffer(BASE_CMD);
cmd.append(" -DpomFile=").append(pom.getName());
cmd.append(" -Dfile=").append(pom.getName());
exec(cmd.toString());
}
});
}
public static void deploy(UploadFile upload) {
final File pom = upload.getPom();
final File jar = upload.getJar();
final File source = upload.getSource();
final File javadoc = upload.getJavadoc();
EXECUTOR_SERVICE.execute(new Runnable() {
@Override
public void run() {
StringBuffer cmd = new StringBuffer(BASE_CMD);
cmd.append(" -DpomFile=").append(pom.getPath());
if (jar != null) {
// 当有bundle类型时,下面的配置可以保证上传的jar包后缀为.jar
cmd.append(" -Dpackaging=jar -Dfile=").append(jar.getPath());
} else {
cmd.append(" -Dfile=").append(pom.getPath());
}
if (source != null) {
cmd.append(" -Dsources=").append(source.getPath());
}
if (javadoc != null) {
cmd.append(" -Djavadoc=").append(javadoc.getPath());
}
exec(cmd.toString());
}
});
}
private static void exec(String cmd) {
try {
final Process proc = CMD.exec(cmd, null, null);
try (InputStream inputStream = proc.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader reader = new BufferedReader(inputStreamReader);) {
String line;
StringBuffer logBuffer = new StringBuffer();
logBuffer.append("\n\n\n=======================================\n");
while ((line = reader.readLine()) != null) {
if (line.startsWith("[INFO]") || line.startsWith("Upload")) {
logBuffer.append(Thread.currentThread().getName() + " : " + line + "\n");
}
}
System.out.println(logBuffer);
int result = proc.waitFor();
if (result != 0) {
error("上传失败:" + cmd);
}
}
} catch (IOException e) {
error("上传失败:" + cmd);
e.printStackTrace();
} catch (InterruptedException e) {
error("上传失败:" + cmd);
e.printStackTrace();
}
}
private static List<Path> match(String glob, String location) throws IOException {
final PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher(glob);
List<Path> matchFiles = new ArrayList<>();
Files.walkFileTree(Paths.get(location), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
if (pathMatcher.matches(path)) {
matchFiles.add(path);
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
});
return matchFiles;
}
private static class UploadFile {
private File pom = null;
private File jar = null;
private File source = null;
private File javadoc = null;
public File getPom() {
return pom;
}
public void setPom(File pom) {
this.pom = pom;
}
public File getJar() {
return jar;
}
public void setJar(File jar) {
this.jar = jar;
}
public File getSource() {
return source;
}
public void setSource(File source) {
this.source = source;
}
public File getJavadoc() {
return javadoc;
}
public void setJavadoc(File javadoc) {
this.javadoc = javadoc;
}
}
}
好学若饥,谦卑若愚
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律