For an artifact on Maven central (or any other given Nexus repository), I want to make a list of all direct dependencies.
At first, I thought about just reading the
The following workflow seems to be ok:
Download the pom from Maven central, put it a separate directory and name it pom.xml
.
Apply mvn dependency:list -DexcludeTransitive
and grab the console output.
Filter the list of dependencies from the console output.
Outside of a Maven plugin, you can do this programmatically using Aether. There is a method readArtifactDescriptor that does exactly this:
Gets information about an artifact like its direct dependencies and potential relocations.
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>
Then you can have:
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;
}
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.
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().
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.