以编程方式解析插件之外的Maven依赖关系 – 获取RepositorySystemSession和RepositorySystem

也许这将是一个比我原先想象的更大的任务,但无论如何,我正在尝试从文件加载MavenProject然后解决它的依赖关系。 我有两个位的代码,但我缺少一些我需要的对象引用; 特别是我需要获取RepositorySystemSessionRepositorySystem实例。 有小费吗?

注意:我用maven-plugin标记了这个问题,但这不是Maven插件。 我很高兴要求Maven 3(不管怎么说我已经有了……)

这是我到目前为止的代码:

构建MavenProject

 public static MavenProject loadProject(File pomFile) throws Exception { MavenProject ret = null; MavenXpp3Reader mavenReader = new MavenXpp3Reader(); if (pomFile != null && pomFile.exists()) { FileReader reader = null; try { reader = new FileReader(pomFile); Model model = mavenReader.read(reader); model.setPomFile(pomFile); ret = new MavenProject(model); } finally { // Close reader } } return ret; } 

解决依赖关系:

 public static List getArtifactsDependencies(MavenProject project, String dependencyType, String scope) throws Exception { DefaultArtifact pomArtifact = new DefaultArtifact(project.getId()); RepositorySystemSession repoSession = null; // TODO RepositorySystem repoSystem = null; // TODO List remoteRepos = project.getRemoteProjectRepositories(); List ret = new ArrayList(); Dependency dependency = new Dependency(pomArtifact, scope); CollectRequest collectRequest = new CollectRequest(); collectRequest.setRoot(dependency); collectRequest.setRepositories(remoteRepos); DependencyNode node = repoSystem.collectDependencies(repoSession, collectRequest).getRoot(); DependencyRequest projectDependencyRequest = new DependencyRequest(node, null); repoSystem.resolveDependencies(repoSession, projectDependencyRequest); PreorderNodeListGenerator nlg = new PreorderNodeListGenerator(); node.accept(nlg); ret.addAll(nlg.getDependencies(true)); return ret; } 

我意识到这可能是一个不寻常的请求,也许我应该废弃我想要做的事情并将其作为插件包装……但我只是想完成我现在开始的事情! 提前致谢。

试试jcabi-aether ,它是来自Sonatype的Apache Aether的包装:

 final File repo = this.session.getLocalRepository().getBasedir(); final Collection deps = new Aether(this.getProject(), repo).resolve( new DefaultArtifact("junit", "junit-dep", "", "jar", "4.10"), JavaScopes.RUNTIME ); 

如果你不在Maven插件中:

 final File repo = new File(System.getProperty("java.io.tmpdir"), "my-repo"); final MavenProject project = new MavenProject(); project.setRemoteArtifactRepositories( Arrays.asList( new RemoteRepository( "maven-central", "default", "http://repo1.maven.org/maven2/" ) ) ); final Collection deps = new Aether(project, repo).resolve( new DefaultArtifact("junit", "junit-dep", "", "jar", "4.10"), JavaScopes.RUNTIME ); 

我建议阅读有关Aether lib的信息,这正是出于这种目的。

注意:Aether之前是在Sonatype开发的,但后来转移到了Eclipse 。

我刚刚为你和我的问题提出了一个解决方案:

 /******************************************************************************* * Copyright (c) 2013 TerraFrame, Inc. All rights reserved. * * This file is part of Runway SDK(tm). * * Runway SDK(tm) is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * Runway SDK(tm) is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with Runway SDK(tm). If not, see . ******************************************************************************/ package com.test.mavenaether; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; import org.apache.maven.artifact.repository.MavenArtifactRepository; import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout; import org.apache.maven.model.Model; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import org.sonatype.aether.artifact.Artifact; import org.sonatype.aether.resolution.DependencyResolutionException; import org.sonatype.aether.util.artifact.DefaultArtifact; import org.sonatype.aether.util.artifact.JavaScopes; import com.jcabi.aether.Aether; public class MavenAether { public static void main(String[] args) throws Exception { String classpath = getClasspathFromMavenProject(new File("/users/terraframe/documents/workspace/MavenSandbox/pom.xml"), new File("/users/terraframe/.m2/repository")); System.out.println("classpath = " + classpath); } public static String getClasspathFromMavenProject(File projectPom, File localRepoFolder) throws DependencyResolutionException, IOException, XmlPullParserException { MavenProject proj = loadProject(projectPom); proj.setRemoteArtifactRepositories( Arrays.asList( (ArtifactRepository) new MavenArtifactRepository( "maven-central", "http://repo1.maven.org/maven2/", new DefaultRepositoryLayout(), new ArtifactRepositoryPolicy(), new ArtifactRepositoryPolicy() ) ) ); String classpath = ""; Aether aether = new Aether(proj, localRepoFolder); List dependencies = proj.getDependencies(); Iterator it = dependencies.iterator(); while (it.hasNext()) { org.apache.maven.model.Dependency depend = it.next(); final Collection deps = aether.resolve( new DefaultArtifact(depend.getGroupId(), depend.getArtifactId(), depend.getClassifier(), depend.getType(), depend.getVersion()), JavaScopes.RUNTIME ); Iterator artIt = deps.iterator(); while (artIt.hasNext()) { Artifact art = artIt.next(); classpath = classpath + " " + art.getFile().getAbsolutePath(); } } return classpath; } public static MavenProject loadProject(File pomFile) throws IOException, XmlPullParserException { MavenProject ret = null; MavenXpp3Reader mavenReader = new MavenXpp3Reader(); if (pomFile != null && pomFile.exists()) { FileReader reader = null; try { reader = new FileReader(pomFile); Model model = mavenReader.read(reader); model.setPomFile(pomFile); ret = new MavenProject(model); } finally { reader.close(); } } return ret; } } 

pom.xml中:

  4.0.0 com.test MavenSandbox 0.0.1-SNAPSHOT   com.jcabi jcabi-aether 0.7.19   org.apache.maven maven-core 3.0.3    

代码首先加载Maven项目(使用原始问题中提供的函数),然后使用jcabi-aether在本地存储库中查找工件。 您需要更改main函数中的两个参数:项目的pom.xml的位置以及本地存储库的位置。

请享用! 🙂

试试这个(从ather-demo可以看出):

 ... LocalRepository localRepository = new LocalRepository("/path/to/local-repo"); RepositorySystem system = getRepositorySystemInstance(); RepositorySystemSession session = getRepositorySystemSessionInstance(system, localRepository); .... public static RepositorySystem getRepositorySystemInstance() { /** * Aether's components implement org.sonatype.aether.spi.locator.Service to ease manual wiring and using the * prepopulated DefaultServiceLocator, we only need to register the repository connector factories. */ MavenServiceLocator locator = new MavenServiceLocator(); locator.addService(RepositoryConnectorFactory.class, FileRepositoryConnectorFactory.class); locator.addService(RepositoryConnectorFactory.class, WagonRepositoryConnectorFactory.class); locator.setServices(WagonProvider.class, new ManualWagonProvider()); return locator.getService(RepositorySystem.class); } private static RepositorySystemSession getRepositorySystemSessionInstance(RepositorySystem system, LocalRepository localRepo) { MavenRepositorySystemSession session = new MavenRepositorySystemSession(); session.setLocalRepositoryManager(system.newLocalRepositoryManager(localRepo)); session.setTransferListener(new ConsoleTransferListener()); session.setRepositoryListener(new ConsoleRepositoryListener()); // Set this in order to generate dirty trees session.setDependencyGraphTransformer(null); return session; } 

Eclipses Aether API有一套很好的独立示例,它们在最新的Maven(3.1.1)中使用,可以在这里找到。

注意:Maven 3.1.X仍然使用Aether 0.9.0.M2 (我们在示例中使用的最新版本是0.9.0.M3 )。 因此,要在Maven插件中运行这些示例,需要版本M2,并且独立应用程序可以使用最新的M3版本。

这在RepositorySystem的“Aether / Setting Aether Up”和eclipse wiki中的“Aether / Creating a Repository System Session”中有所介绍。

没有大量文档,但您可以按如下方式创建RepositorySystem:

 // verbatim copy from the Setting Aether Up link private static RepositorySystem newRepositorySystem() { DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator(); locator.addService( RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class ); locator.addService( TransporterFactory.class, FileTransporterFactory.class ); locator.addService( TransporterFactory.class, HttpTransporterFactory.class ); return locator.getService( RepositorySystem.class ); } 

请注意,这需要“获取以太”中详述的依赖关系,最明显的是maven-aether-provider

当您拥有存储库系统时,本教程将继续使用以下工厂方法创建RepositorySystemSession:

 // copied verbatim from "Creating a Repository System Session" 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; }