Hello -
I’m looking to programatically obtain an effective model from a POM file.
Search on the interwebs have taken me to Maven Resolver Provider
<https://maven.apache.org/ref/3.6.0/maven-resolver-provider/>. This appears
to have replaced Eclipse Aether <http://maven.apache.org/aether.html> as a
means of programmatic access to maven model resolution.

I’ve written some code that *works*. However I’ve had to resort to
accessing a package private class (
org.apache.maven.repository.internal.DefaultModelResolver) to make it work.
Here’s the code:

public static void main(String[] args) throws Exception {
        DefaultServiceLocator locator = serviceLocator();
        RepositorySystem system = locator.getService(RepositorySystem.class);
        DefaultRepositorySystemSession session =
MavenRepositorySystemUtils.newSession();
        LocalRepository localRepo = new LocalRepository("target/m2");
        
session.setLocalRepositoryManager(system.newLocalRepositoryManager(session,
localRepo));

        Constructor<ModelResolver> c = modelResolverCtor();
        RequestTrace requestTrace = new RequestTrace(null);
        ArtifactResolver artifactResolver =
locator.getService(ArtifactResolver.class);
        VersionRangeResolver versionRangeResolver =
locator.getService(VersionRangeResolver.class);
        RemoteRepositoryManager remoteRepositoryManager =
locator.getService(RemoteRepositoryManager.class);
        List<RemoteRepository> repos = List.of(new
RemoteRepository.Builder("central", "default",
"https://repo.maven.apache.org/maven2/";).build());
        ModelResolver modelResolver = c.newInstance(session,
requestTrace, "context", artifactResolver, versionRangeResolver,
remoteRepositoryManager, repos);

        DefaultModelBuildingRequest modelBuildingRequest = new
DefaultModelBuildingRequest();
        String springBootPOMPath =

"https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot/2.1.4.RELEASE/spring-boot-2.1.4.RELEASE.pom";;
        File springBootPOM = downloadPOM(springBootPOMPath,
HttpClientBuilder.create().build());
        modelBuildingRequest.setPomFile(springBootPOM);
        modelBuildingRequest.setModelResolver(modelResolver);
        DefaultModelBuilder modelBuilder = new
DefaultModelBuilderFactory().newInstance();
        
System.out.println(modelBuilder.build(modelBuildingRequest).getEffectiveModel().getDependencies());
    }

    private static DefaultServiceLocator serviceLocator() {
        DefaultServiceLocator locator =
MavenRepositorySystemUtils.newServiceLocator();
        locator.addService(RepositoryConnectorFactory.class,
BasicRepositoryConnectorFactory.class);
        locator.addService(TransporterFactory.class,
FileTransporterFactory.class);
        locator.addService(TransporterFactory.class,
HttpTransporterFactory.class);
        locator.addService(TransporterFactory.class,
WagonTransporterFactory.class);
        return locator;
    }

    private static Constructor<ModelResolver> modelResolverCtor()
throws ClassNotFoundException, NoSuchMethodException {
        @SuppressWarnings("unchecked") Class<ModelResolver> modelResolverClass =
                (Class<ModelResolver>)
Class.forName("org.apache.maven.repository.internal.DefaultModelResolver");
        Constructor<ModelResolver> c =
modelResolverClass.getDeclaredConstructor(RepositorySystemSession.class,
RequestTrace.class,
                String.class, ArtifactResolver.class,
VersionRangeResolver.class, RemoteRepositoryManager.class,
List.class);
        c.setAccessible(true);
        return c;
    }

    private static File downloadPOM(String pomURL, HttpClient client)
throws Exception {
        HttpGet request = new HttpGet(pomURL);
        HttpResponse response = client.execute(request);
        File outputFile = new File("target/" + Paths.get(new
URI(pomURL).getPath()).getFileName().toString());
        try (InputStream contentStream = response.getEntity().getContent()) {
            Files.copy(contentStream, outputFile.toPath(),
StandardCopyOption.REPLACE_EXISTING);
        }
        return outputFile;
    }

Here are the dependencies I’m using:

<dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-resolver-provider</artifactId>
    <version>3.6.0</version></dependency><dependency>
    <groupId>org.apache.maven.resolver</groupId>
    <artifactId>maven-resolver-connector-basic</artifactId>
    <version>1.3.3</version></dependency><dependency>
    <groupId>org.apache.maven.resolver</groupId>
    <artifactId>maven-resolver-transport-file</artifactId>
    <version>1.3.3</version></dependency><dependency>
    <groupId>org.apache.maven.resolver</groupId>
    <artifactId>maven-resolver-transport-http</artifactId>
    <version>1.3.3</version></dependency><dependency>
    <groupId>org.apache.maven.resolver</groupId>
    <artifactId>maven-resolver-transport-wagon</artifactId>
    <version>1.3.3</version></dependency>

I’m unable to figure out how to obtain a ModelResolver without resorting to
reflecting on org.apache.maven.repository.internal.DefaultModelResolver.

Reply via email to