8

What do I want to do?

  • Given a POM file on the local filesystem.
  • I want to programmatically obtain the effective POM of that POM file. Specifically I want to do the following:

    • Resolve the POMs dependencies
    • Ensure that all parent POMs are processed
    • Obtain the list of dependencies of the fully resolved POM
    • And so on...
  • I don't need to obtain transitive dependencies.

What works?

I'm using Maven Resolver Provider which sort of works. However I have to use a package private class org.apache.maven.repository.internal.DefaultModelResolver

Here a GitHub link to a sample Maven project that you can run: https://github.com/sahilm/maven-resolver-test

The example program does the following:

  • Downloads the latest spring boot POM from Maven Central.
  • Prints out it's direct dependencies (with parent deps included)

You can run the the program with: mvn exec:java -Dexec.mainClass="com.sahilm.maven_resolver_test.Test"

What I need help with?

  • I need help with understanding why I have to use a package private class to get stuff to work.
  • Is there another way to get the information I need?
Sahil Muthoo
  • 12,033
  • 2
  • 29
  • 38

2 Answers2

4

You can create (in your project) a public class under the package: org.apache.maven.repository.internal that extends the package-accessibility class. Just use a class name that is not possible to be used in the furutre by the vendor.

package org.apache.maven.repository.internal;
public class VisibleDefaultModelResolver extends DefaultModelResolver{

    public VisibleDefaultModelResolver(RepositorySystemSession session, RequestTrace trace, String context, ArtifactResolver resolver, VersionRangeResolver versionRangeResolver, RemoteRepositoryManager remoteRepositoryManager, List<RemoteRepository> repositories) {
        super(session, trace, context, resolver, versionRangeResolver, remoteRepositoryManager, repositories);
    }

}

Then your code becomes:

ModelResolver modelResolver = new VisibleDefaultModelResolver(session, requestTrace, "context", artifactResolver, versionRangeResolver, remoteRepositoryManager, repos);
Marinos An
  • 9,481
  • 6
  • 63
  • 96
  • That's interesting. Never knew you could do that! I still have a nagging feeling that there's a public API that I'm missing and that I have to combine the maven resolver provider with something else. This is helpful though and I'll accept your answer if I'm not able to find a public API. – Sahil Muthoo Apr 10 '19 at 10:40
3

Maybe you can use ProjectModelResolver. Here's a code snippet,

    DefaultRepositorySystem repositorySystem =
            new DefaultRepositorySystem();
    repositorySystem.initService(locator);

    ModelResolver modelResolver =
            new ProjectModelResolver(session, requestTrace,
                    repositorySystem, remoteRepositoryManager, repos,
                    ProjectBuildingRequest.RepositoryMerging.POM_DOMINANT,
                    null);

I've included a working code here.

Indra Basak
  • 7,124
  • 1
  • 26
  • 45
  • 1
    Awesome. This works. I skipped looking at this because I was unsure how to get a `ReactorModelPool`. Turns out I don't need to. Thanks! – Sahil Muthoo Apr 10 '19 at 22:25