Find all direct dependencies of an artifact on Maven Central

前端 未结 2 1584
粉色の甜心
粉色の甜心 2021-01-03 06:27

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

相关标签:
2条回答
  • 2021-01-03 06:51

    The following workflow seems to be ok:

    1. Download the pom from Maven central, put it a separate directory and name it pom.xml.

    2. Apply mvn dependency:list -DexcludeTransitive and grab the console output.

    3. Filter the list of dependencies from the console output.

    0 讨论(0)
  • 2021-01-03 06:59

    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.

    0 讨论(0)
提交回复
热议问题