问题描述
对于Maven中心(或任何其他给定的Nexus存储库)上的工件,我想列出所有直接依赖项的列表.
For an artifact on Maven central (or any other given Nexus repository), I want to make a list of all direct dependencies.
起初,我考虑过只读取pom.xml并从依赖项部分收集所有条目.但是我注意到这些条目可能没有版本(由依赖性管理提供),或者这些条目可能来自父poms.
At first, I thought about just reading the pom.xml and gather all entries from the dependency section. But I noticed that these entries might have no version (supplied by dependency management) or that entries might come from parent poms.
我的第二个想法是构建某种人工Maven项目,并使用mvn dependency:tree
收集依赖项.这可能会变得复杂.
My second idea was to build some kind of artificial Maven project and gather the dependencies with mvn dependency:tree
. This might become complicated.
最直接(也是最可靠)的方法是什么?
What would be the most direct (but also reliable) way?
推荐答案
在Maven插件之外,您可以使用Aether以编程方式进行此操作.有一种方法 readArtifactDescriptor
就是这样:
Outside of a Maven plugin, you can do this programmatically using Aether. There is a method readArtifactDescriptor
that does exactly this:
首先,将以太依赖项添加到您的POM中:
First, add the Aether dependencies to your POM:
<dependencies>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-impl</artifactId>
<version>${aetherVersion}</version>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-connector-basic</artifactId>
<version>${aetherVersion}</version>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-transport-file</artifactId>
<version>${aetherVersion}</version>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-transport-http</artifactId>
<version>${aetherVersion}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-aether-provider</artifactId>
<version>${mavenVersion}</version>
</dependency>
</dependencies>
<properties>
<aetherVersion>1.1.0</aetherVersion>
<mavenVersion>3.3.9</mavenVersion>
</properties>
那么您可以拥有:
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("groupId:artifactId:version");
ArtifactDescriptorRequest request = new ArtifactDescriptorRequest(artifact, Arrays.asList(central), null);
ArtifactDescriptorResult result = system.readArtifactDescriptor(session, request);
for (Dependency dependency : result.getDependencies()) {
System.out.println(dependency);
}
}
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));
// set possible proxies and mirrors
session.setProxySelector(new DefaultProxySelector().add(new Proxy(Proxy.TYPE_HTTP, "host", 3625), Arrays.asList("localhost", "127.0.0.1")));
session.setMirrorSelector(new DefaultMirrorSelector().add("my-mirror", "http://mirror", "default", false, "external:*", null));
return session;
}
这是创建一个以太存储库系统,并告诉它读取给定工件的工件描述符.该构件是使用构造函数new DefaultArtifact("...")
为其提供所需坐标的方式构造的.
What this does is creating a Aether repository system and telling it to read the artifact descriptor of a given artifact. The artifact is constructed with the constructor new DefaultArtifact("...")
giving it the wanted coordinates.
使用此工件和要从中获取请求的存储库列表创建请求对象.在上面的示例中,仅添加了Maven Central,但是您可以通过使用RemoteRepository.Builder
类创建它们来添加更多的RemoteRepository
.调用readArtifactDescriptor
之后,结果包含直接依赖项列表,可以使用 getDependencies()
.
A request object is created with this artifact and the list of repositories to fetch it from. In the above sample, only Maven Central was added, but you could add more RemoteRepository
by creating them with the RemoteRepository.Builder
class. After calling readArtifactDescriptor
, the result contains the list of direct dependencies, that can be retrieved with getDependencies()
.
可以在 DefaultProxySelector
和 DefaultMirrorSelector
. DefaultProxySelector.add
使用 Proxy
作为参数,可以通过为其构造函数传递其类型(例如"http"
)来创建它,主机,端口和可选的 Authentication
(请查看 AuthenticationBuilder
类以创建身份验证对象),以及非代理主机的列表.以相同的方式, DefaultMirrorSelector.add
需要它的ID,URL,类型(对于Maven,它是"default"
,但是您可以使用P2),无论它是存储库管理器,还是镜像了实际的存储库ID(根据镜像规范),并且存储库类型未镜像.
Proxies and mirrors can be configured with the help of the DefaultProxySelector
and DefaultMirrorSelector
respectively. DefaultProxySelector.add
takes a Proxy
as argument, which can be created with its constructor by passing it its type (like "http"
), host, port and optionally an Authentication
(take a look at the AuthenticationBuilder
class to create authentication objects), and a list of non-proxied host. In the same way, DefaultMirrorSelector.add
takes its id, URL, type (which is "default"
for Maven, but you could have P2 for example), whether it is a repository manager, the actual repository ids mirrored (according to the mirror specification), and the repository type not mirrored.
这篇关于在Maven Central上找到工件的所有直接依赖项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!