如果有个需要是要通过代码调用 maven 命令,来上传 jar 包或进行其余操作,该如何实现?
调用命令行当然能够,maven 官网也有一个我的项目 Apache Maven Invoker 实现相似需要,但前提是服务运行的机器或者容器中须要有 maven。
大家可能都据说过 Write once, run anywhere. 如果没了 maven 环境就执行不了了,有没有更好的形式呢
Maven Embedder 也是 maven 官网的一个我的项目,如名字一样,是可嵌入的,也就是不须要依赖内部 maven。我的项目是个好我的项目,但问题就是官网提供的文档切实太少了。
以防被喷,这里没有说嵌入肯定是更好的计划,毕竟不可能把我的项目所需的所有依赖都打包到一起,还是要依据理论问题来抉择的。
依赖
依照官网其实只须要 maven-embedder
一个依赖就能够,但理论运行起来,会发现报很多错,这里也不啰嗦,间接放出残缺可用的依赖。
<dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-embedder</artifactId> <version>3.6.3</version></dependency><dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-compat</artifactId> <version>3.6.3</version></dependency><dependency> <groupId>org.apache.maven.resolver</groupId> <artifactId>maven-resolver-connector-basic</artifactId> <version>1.4.1</version></dependency><dependency> <groupId>org.apache.maven.resolver</groupId> <artifactId>maven-resolver-transport-http</artifactId> <version>1.4.1</version></dependency>
maven-compat
是一个用于放弃与 Maven2 兼容性的包。
maven-resolver-connector-basic
和 maven-resolver-transport-http
用于 deploy。如果只运行到 install,不须要 deploy ,这两个依赖能够去掉。网上很多会用 aether 我的项目中的依赖,相似上面这种的
<dependency> <groupId>org.eclipse.aether</groupId> <artifactId>aether-connector-basic</artifactId> <version>1.0.2.v20150114</version></dependency><dependency> <groupId>org.eclipse.aether</groupId> <artifactId>aether-transport-wagon</artifactId> <version>1.0.2.v20150114</version></dependency>
然而实际上 aether 这个我的项目曾经进行了,详见 Aether Termination Review,而 Apache Maven Artifact Resolver 就是替代者。
应用
应用的代码也很简略
public static void deploy(String path){ MavenCli cli = new MavenCli(); String mvnHome = MavenCli.USER_MAVEN_CONFIGURATION_HOME.getAbsolutePath(); System.getProperties().setProperty("maven.multiModuleProjectDirectory", mvnHome); List<String> args = new ArrayList<>(); args.add("clean"); args.add("deploy"); int status = 0; try { status = cli.doMain(args.toArray(new String[]{}), path, System.out, System.out); }catch (Exception e){ logger.error(e.getMessage(),e); throw e; } if (status != 0) { throw new RuntimeException("maven 出错"); }}
maven.multiModuleProjectDirectory
这个零碎变量,如果设置了就无需设置了,但如果没有就须要设置,否则会报错。
另外因为 deploy
时波及服务器的账户和明码,可能须要配置文件,这里有两种解决方案:
- 通过
-s,--settings
来指定配置文件的门路。 - 把配置文件放到 maven home 中。
如果应用了明码加密,还波及 settings-security.xml
文件,这时用第一种就行不太通(次要我没胜利),把这两个文件都放到 maven home 是没啥问题的。默认的 maven home 就是用户目录下的.m2
目录。
常见谬误
-Dmaven.multiModuleProjectDirectory system property is not set.
后面提到了,设置这个零碎变量就能够了,值为 maven home 对应的门路即可。
No implementation for org.apache.maven.repository.RepositorySystem was bound.
增加依赖,尽管这是个maven 2 的兼容包,然而还没找到其余的可替代品。
<dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-compat</artifactId> <version>3.6.3</version></dependency>
No connector factories available、No transporter factories registered
这两个都是部署过程中会报出的谬误,增加如下依赖即可解决
<dependency> <groupId>org.apache.maven.resolver</groupId> <artifactId>maven-resolver-connector-basic</artifactId> <version>1.4.1</version></dependency><dependency> <groupId>org.apache.maven.resolver</groupId> <artifactId>maven-resolver-transport-http</artifactId> <version>1.4.1</version></dependency>