Maven:以编程方式获取所有依赖项

Maven:以编程方式获取所有依赖项,第1张

Maven:以编程方式获取所有依赖

在Maven插件之外,对工件进行 *** 作的方法是通过Aether。该团队有一个示例项目,以获取名为的给定工件的传递依赖

ResolveTransitiveDependencies
。设置以太依赖项后(如此处所示),您可以简单地进行以下 *** 作:

public static void main(final String[] args) throws Exception {    DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();    RepositorySystem system = newRepositorySystem(locator);    RepositorySystemSession session = newSession(system);    RemoteRepository central = new RemoteRepository.Builder("central", "default", "http://repo1.maven.org/maven2/").build();    Artifact artifact = new DefaultArtifact("group.id:artifact.id:version");    CollectRequest collectRequest = new CollectRequest(new Dependency(artifact, JavaScopes.COMPILE), Arrays.asList(central));    DependencyFilter filter = DependencyFilterUtils.classpathFilter(JavaScopes.COMPILE);    DependencyRequest request = new DependencyRequest(collectRequest, filter);    DependencyResult result = system.resolveDependencies(session, request);    for (ArtifactResult artifactResult : result.getArtifactResults()) {        System.out.println(artifactResult.getArtifact().getFile());    }}private static RepositorySystem newRepositorySystem(DefaultServiceLocator locator) {    locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);    locator.addService(TransporterFactory.class, FileTransporterFactory.class);    locator.addService(TransporterFactory.class, HttpTransporterFactory.class);    return locator.getService(RepositorySystem.class);}private static RepositorySystemSession newSession(RepositorySystem system) {    DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();    LocalRepository localRepo = new LocalRepository("target/local-repo");    session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));    return session;}

它将下载工件并将其放入

"target/local-repo"

请注意,您可以在系统会话上使用

DefaultProxySelector
和配置代理和镜像
DefaultMirrorSelector
。可以读取Maven设置文件并使用它来填充会话,但是事情变得非常难看而且非常快…


当您想要访问MOM并希望将设置考虑在内而希望与Maven本身紧密结合时,以编程方式直接调用Maven会容易得多。在这种情况下,您会对给定POM文件的每个依赖项(包括传递性依赖项)的路径感兴趣。对于该

dependency:list
目标,以设置在一起
outputAbsoluteArtifactFilename
true
,会给(几乎)正是这样。

要以编程方式调用Maven,可以使用Invoker API。将依赖项添加到您的项目中:

<dependency>  <groupId>org.apache.maven.shared</groupId>  <artifactId>maven-invoker</artifactId>  <version>2.2</version></dependency>

你可以有:

InvocationRequest request = new DefaultInvocationRequest();request.setPomFile(new File(pomPath));request.setGoals(Arrays.asList("dependency:list"));Properties properties = new Properties();properties.setProperty("outputFile", "dependencies.txt"); // redirect output to a fileproperties.setProperty("outputAbsoluteArtifactFilename", "true"); // with pathsproperties.setProperty("includeScope", "runtime"); // only runtime (scope compile + runtime)// if only interested in scope runtime, you may replace with excludeScope = compilerequest.setProperties(properties);Invoker invoker = new DefaultInvoker();// the Maven home can be omitted if the "maven.home" system property is setinvoker.setMavenHome(new File("/path/to/maven/home"));invoker.setOutputHandler(null); // not interested in Maven output itselfInvocationResult result = invoker.execute(request);if (result.getExitCode() != 0) {    throw new IllegalStateException("Build failed.");}Pattern pattern = Pattern.compile("(?:compile|runtime):(.*)");try (BufferedReader reader = Files.newBufferedReader(Paths.get("dependencies.txt"))) {    while (!"The following files have been resolved:".equals(reader.readLine()));    String line;    while ((line = reader.readLine()) != null && !line.isEmpty()) {        Matcher matcher = pattern.matcher(line);        if (matcher.find()) { // group 1 contains the path to the file System.out.println(matcher.group(1));        }    }}

这将创建一个调用请求,该请求包含:调用目标和系统属性,就像

mvn dependency:list-Dprop=value
在命令行上启动一样。使用设置的路径将默认为的标准位置
"${user.home}/settings.xml"
,但也可以使用
request.setUserSettingsFile(...)
和来指定设置的路径
request.setGlobalSettingsFile(...)
。仅在
"maven.home"
未设置系统属性的情况下,才需要将调用者设置为Maven主目录(即安装目录)。

调用的结果

dependency:list
被重定向到文件,该文件随后进行后处理。该目标的输出包括以下格式的依赖项列表(如果没有分类器,则分类器可能不存在):

group.id:artifact.id:type[:classifier]:version:scope:pathname

没有一种方法只能输出已解析工件的文件的路径,并且分类器可能不存在的事实使解析变得有些复杂(

:
由于路径可能包含
:
..
,因此我们无法进行限制分割))。首先,已解析的工件
"The following files have beenresolved:"
在输出文件中的行下方,然后,由于所需作用域仅是
compile
or
runtime
,我们可以使用简单的正则表达式获取工件文件的路径,该正则表达式接受
compile:
或之后的所有内容
runtime:
。该路径然后可以直接用作
newFile


如果后处理过程中的箍圈看起来太脆弱,我想您可以创建自己的插件,该插件仅输出已解析工件的文件名。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5439510.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存