对于Maven central(或任何其他给定的Nexus存储库)上的工件,我想列出所有直接依赖项。
首先,我考虑过只读取pom.xml并从依赖项部分收集所有条目。但我注意到这些条目可能没有版本(由依赖关系管理提供),或者条目可能来自父poms。
我的第二个想法是构建某种人工Maven项目并使用mvn dependency:tree
收集依赖项。这可能会变得复杂。
最直接(但也可靠)的方式是什么?
答案 0 :(得分:5)
在Maven插件之外,您可以使用Aether以编程方式执行此操作。有一种方法readArtifactDescriptor
就是这样做的:
获取有关工件的信息,例如其直接依赖关系和潜在的重定位。
首先,将Aether依赖项添加到您的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;
}
这样做是创建一个Aether存储库系统并告诉它读取给定工件的工件描述符。该工件由构造函数new DefaultArtifact("...")
构造,为其提供所需的坐标。
使用此工件和要从中获取它的存储库列表创建请求对象。在上面的示例中,只添加了Maven Central,但您可以使用RemoteRepository
类创建更多RemoteRepository.Builder
。调用readArtifactDescriptor
后,结果包含直接依赖项列表,可以使用getDependencies()
检索。
可以分别在DefaultProxySelector
和DefaultMirrorSelector
的帮助下配置代理和镜像。 DefaultProxySelector.add
使用Proxy
作为参数,可以使用其构造函数创建它的类型(如"http"
),主机,端口和可选的Authentication
(取一个查看AuthenticationBuilder
类以创建身份验证对象)和非代理主机列表。以同样的方式,DefaultMirrorSelector.add
获取其id,URL,类型(Maven为"default"
,但您可以使用P2),无论是存储库管理器,还是实际存储库ID镜像(根据{{3}}),以及未镜像的存储库类型。
答案 1 :(得分:0)
以下工作流程似乎没问题:
从Maven central下载pom,将其放在一个单独的目录中,并将其命名为pom.xml
。
应用mvn dependency:list -DexcludeTransitive
并获取控制台输出。
从控制台输出中过滤依赖项列表。