3

I'm currently attempting to get PlexusContainer to give me an initialized Maven-instance outside of a maven or eclipse execution context.

For that purpose I have following code (simplified):

PlexusContainer container = null;
try {
    container = new DefaultPlexusContainer();
    container.lookup(MavenResolutionTask.class).run();
    container.dispose();
} catch (Exception e) {
    e.printStackTrace();
}

// --- MavenResolutionTask.java:

@Component(role = MavenResolutionTask.class)
// ResolutionTask is an abstract class 
// implementing Runnable and extending CompletableFuture
public class MavenResolutionTask extends ResolutionTask {

    @Requirement
    private Maven maven;
}

Given that I had the standard plexus-component-metadata:process-classes plugin execution in my pom.xml I would've liked if this had worked like this.

Unfortunately running this code results in a LookupException with the following reason (stacktrace omitted for brevity):

WARN Sisu - Error injecting: org.apache.maven.project.DefaultProjectBuildingHelper
com.google.inject.ProvisionException: Guice provision errors:

1) No implementation for org.apache.maven.repository.RepositorySystem was bound.
  while locating org.apache.maven.project.DefaultProjectBuildingHelper

WARN Sisu - Error injecting: org.apache.maven.project.DefaultProjectBuilder
com.google.inject.ProvisionException: Guice provision errors:

1) No implementation for org.apache.maven.repository.RepositorySystem was bound.
  while locating org.apache.maven.project.DefaultProjectBuildingHelper
  at ClassRealm[plexus.core, parent: null]
  at ClassRealm[plexus.core, parent: null]
  while locating org.apache.maven.project.ProjectBuildingHelper
  while locating org.apache.maven.project.DefaultProjectBuilder

...

To remediate the missing bindings and prevent myself from having to go through the trouble of manually registering the complete dependency-graph of maven I attempted to merge the component descriptors included in my dependencies with the one generated for my application.

For that purpose I copied all dependencies into target/dependency and ran some shell-scripts to get a list of all dependencies that include a components.xml.
I pass these dependencies to an execution of dependency:unpack before then passing the extracted locations to the metadata-merger like so:

<plugin>
    <groupId>org.codehaus.plexus</groupId>
    <artifactId>plexus-component-metadata</artifactId>
    <version>1.7.1</version>
    <executions>
        <execution>
            <id>process-classes</id>
            <goals>
                <goal>generate-metadata</goal>
            </goals>
        </execution>
        <execution>
            <id>process-test-classes</id>
            <goals>
                <goal>generate-test-metadata</goal>
            </goals>
        </execution>
        <execution>
            <id>merge-descriptors</id>
            <phase>process-classes</phase>
            <goals>
                <goal>merge-metadata</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <output>${plexus.outputFile}</output>
        <descriptors>
            <descriptor>${plexus.outputFile}</descriptor>
            <!--./aether-transport-wagon-1.1.0.jar.d/META-INF/plexus/components.xml-->
            <descriptor>${project.build.directory}/extracted-sources/aether-transport-wagon/META-INF/plexus/components.xml</descriptor>
            <!--./maven-aether-provider-3.1.0.jar.d/META-INF/plexus/components.xml-->
            <descriptor>${project.build.directory}/extracted-sources/maven-aether-provider/META-INF/plexus/components.xml</descriptor>
            <!--./maven-artifact-manager-2.2.1.jar.d/META-INF/plexus/components.xml-->
            <descriptor>${project.build.directory}/extracted-sources/maven-artifact-manager/META-INF/plexus/components.xml</descriptor>
            <!--./maven-core-3.1.1.jar.d/META-INF/plexus/components.xml-->
            <descriptor>${project.build.directory}/extracted-sources/maven-core/META-INF/plexus/components.xml</descriptor>
            <!--./maven-model-builder-3.1.0.jar.d/META-INF/plexus/components.xml-->
            <descriptor>${project.build.directory}/extracted-sources/maven-model-builder/META-INF/plexus/components.xml</descriptor>
            <!--./maven-plugin-registry-2.2.1.jar.d/META-INF/plexus/components.xml-->
            <descriptor>${project.build.directory}/extracted-sources/maven-plugin-registry/META-INF/plexus/components.xml</descriptor>
            <!--./maven-profile-2.2.1.jar.d/META-INF/plexus/components.xml-->
            <descriptor>${project.build.directory}/extracted-sources/maven-profile/META-INF/plexus/components.xml</descriptor>
            <!--./maven-project-2.2.1.jar.d/META-INF/plexus/components.xml-->
            <descriptor>${project.build.directory}/extracted-sources/maven-project/META-INF/plexus/components.xml</descriptor>
            <!--./maven-settings-builder-3.1.1.jar.d/META-INF/plexus/components.xml-->
            <descriptor>${project.build.directory}/extracted-sources/maven-settings-builder/META-INF/plexus/components.xml</descriptor>
            <!--./org.eclipse.sisu.plexus-0.0.0.M2a.jar.d/META-INF/plexus/components.xml-->
            <descriptor>${project.build.directory}/extracted-sources/sisu-plexus/META-INF/plexus/components.xml</descriptor>
            <!--./plexus-cipher-1.4.jar.d/META-INF/plexus/components.xml-->
            <descriptor>${project.build.directory}/extracted-sources/plexus-cipher/META-INF/plexus/components.xml</descriptor>
            <!--./plexus-interactivity-api-1.0-alpha-6.jar.d/META-INF/plexus/components.xml-->
            <descriptor>${project.build.directory}/extracted-sources/plexus-interactivity-api/META-INF/plexus/components.xml</descriptor>
            <!--./plexus-sec-dispatcher-1.3.jar.d/META-INF/plexus/components.xml-->
            <descriptor>${project.build.directory}/extracted-sources/plexus-sec-dispatcher/META-INF/plexus/components.xml</descriptor>
            <!--./wagon-ssh-1.0.jar.d/META-INF/plexus/components.xml-->
            <descriptor>${project.build.directory}/extracted-sources/wagon-ssh/META-INF/plexus/components.xml</descriptor>
            <!--./wagon-ssh-common-1.0.jar.d/META-INF/plexus/components.xml-->
            <descriptor>${project.build.directory}/extracted-sources/wagon-ssh-common/META-INF/plexus/components.xml</descriptor>
        </descriptors>
    </configuration>
</plugin>

Unfortunately the error message persists So I guess my question is: How do I easily get a Maven instance from Plexus?


P.S. for completeness sake, I'm currently using the following dependencies:

[INFO] com.github.vogel612:dependency-analyzer:jar:0.0.1
[INFO] +- org.projectlombok:lombok:jar:1.16.16:compile
[INFO] +- commons-cli:commons-cli:jar:1.4:compile
[INFO] +- org.slf4j:slf4j-simple:jar:1.7.16:compile
[INFO] |  \- org.slf4j:slf4j-api:jar:1.7.16:compile
[INFO] +- org.codehaus.plexus:plexus-utils:jar:3.0.24:compile
[INFO] +- org.eclipse.aether:aether-api:jar:1.1.0:compile
[INFO] +- org.eclipse.aether:aether-util:jar:1.1.0:compile
[INFO] +- org.eclipse.aether:aether-impl:jar:1.1.0:compile
[INFO] |  \- org.eclipse.aether:aether-spi:jar:1.1.0:compile
[INFO] +- org.eclipse.aether:aether-connector-basic:jar:1.1.0:compile
[INFO] +- org.eclipse.aether:aether-transport-file:jar:1.1.0:compile
[INFO] +- org.eclipse.aether:aether-transport-http:jar:1.1.0:compile
[INFO] |  +- org.apache.httpcomponents:httpclient:jar:4.3.5:compile
[INFO] |  |  +- org.apache.httpcomponents:httpcore:jar:4.3.2:compile
[INFO] |  |  \- commons-codec:commons-codec:jar:1.6:compile
[INFO] |  \- org.slf4j:jcl-over-slf4j:jar:1.6.2:compile
[INFO] +- org.eclipse.aether:aether-transport-wagon:jar:1.1.0:compile
[INFO] |  \- org.apache.maven.wagon:wagon-provider-api:jar:1.0:compile
[INFO] +- org.apache.maven:maven-aether-provider:jar:3.1.0:compile
[INFO] |  +- org.apache.maven:maven-model:jar:3.1.0:compile
[INFO] |  +- org.apache.maven:maven-model-builder:jar:3.1.0:compile
[INFO] |  +- org.apache.maven:maven-repository-metadata:jar:3.1.0:compile
[INFO] |  +- org.eclipse.sisu:org.eclipse.sisu.plexus:jar:0.0.0.M2a:compile
[INFO] |  |  +- javax.enterprise:cdi-api:jar:1.0:compile
[INFO] |  |  |  +- javax.annotation:jsr250-api:jar:1.0:compile
[INFO] |  |  |  \- javax.inject:javax.inject:jar:1:compile
[INFO] |  |  +- com.google.guava:guava:jar:10.0.1:compile
[INFO] |  |  |  \- com.google.code.findbugs:jsr305:jar:1.3.9:compile
[INFO] |  |  +- org.sonatype.sisu:sisu-guice:jar:no_aop:3.1.0:compile
[INFO] |  |  |  \- aopalliance:aopalliance:jar:1.0:compile
[INFO] |  |  \- org.eclipse.sisu:org.eclipse.sisu.inject:jar:0.0.0.M2a:compile
[INFO] |  |     \- asm:asm:jar:3.3.1:compile
[INFO] |  \- org.codehaus.plexus:plexus-component-annotations:jar:1.5.5:compile
[INFO] +- org.apache.maven.wagon:wagon-ssh:jar:1.0:compile
[INFO] |  +- com.jcraft:jsch:jar:0.1.44-1:compile
[INFO] |  \- org.apache.maven.wagon:wagon-ssh-common:jar:1.0:compile
[INFO] |     \- org.codehaus.plexus:plexus-interactivity-api:jar:1.0-alpha-6:compile
[INFO] +- org.apache.maven:maven-core:jar:3.1.1:compile
[INFO] |  +- org.apache.maven:maven-settings:jar:3.1.1:compile
[INFO] |  +- org.apache.maven:maven-settings-builder:jar:3.1.1:compile
[INFO] |  +- org.apache.maven:maven-artifact:jar:3.1.1:compile
[INFO] |  +- org.apache.maven:maven-plugin-api:jar:3.1.1:compile
[INFO] |  +- org.codehaus.plexus:plexus-interpolation:jar:1.19:compile
[INFO] |  +- org.codehaus.plexus:plexus-classworlds:jar:2.5.1:compile
[INFO] |  \- org.sonatype.plexus:plexus-sec-dispatcher:jar:1.3:compile
[INFO] |     \- org.sonatype.plexus:plexus-cipher:jar:1.4:compile
[INFO] \- org.apache.maven:maven-project:jar:2.2.1:compile
[INFO]    +- org.apache.maven:maven-profile:jar:2.2.1:compile
[INFO]    +- org.apache.maven:maven-artifact-manager:jar:2.2.1:compile
[INFO]    |  \- backport-util-concurrent:backport-util-concurrent:jar:3.1:compile
[INFO]    +- org.apache.maven:maven-plugin-registry:jar:2.2.1:compile
[INFO]    \- org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile
[INFO]       +- junit:junit:jar:3.8.1:compile
[INFO]       \- classworlds:classworlds:jar:1.1-alpha-2:compile
Vogel612
  • 5,620
  • 5
  • 48
  • 73
  • What are you trying to achieve or what problem are you trying to solve? Can you elaborate more in detail what exactly your problem is? – khmarbaise Aug 26 '17 at 14:56
  • I want to resolve all dependencies of a project. In addition to resolving their names I need their remote URLs. Since I need to do this for more than just maven, invoking `mvn` isn't the best option and so I want to delegate this to `maven-core` – Vogel612 Aug 26 '17 at 15:18
  • I have already understood that you are trying to resolve dependencies of a project but for what purpose? Why do you need the names? And what do you mean by names? The artifactId ? And what kind of remote URL's ? Please explain more details about what problem you have? – khmarbaise Aug 26 '17 at 15:20
  • by remote URL I mean the actual remote repository location that `dependency:get` will fetch the dep from. Name was intended as shorthand for the coordinates... The purpose is to obtain a list of dependencies with additional information (including license information) that can be merged into an EXCEL-List kept for legal reasons with the end goal of automating as much of the legalese work as possible. – Vogel612 Aug 26 '17 at 15:23
  • Take a look at: http://www.mojohaus.org/license-maven-plugin/ – khmarbaise Aug 26 '17 at 20:57

1 Answers1

5

It might have been helpful as a start to read the error message closely:

The missing Component is org.apache.maven.repository.RepositorySystem and not org.eclipse.aether.RepositorySystem. While the former was already included, the latter is only present in org.apache.maven:maven-compat.

Adding that to the dependencies (and including it's component definitions) fixes the immediate issue here. The intermediate result is currently a NoClassDefFoundError for Lorg/apache/maven/artifact/transform/ArtifactTransformationManager, which can be resolved by actually using the correct version of the dependency.

As the final step now an instance of org.eclipse.aether.RepositorySystem and one instance of org.eclipse.aether.impl.RemoteRepositoryManager needs to be registered, which can be accomplished using code along the following lines:

final ServiceLocator serviceLocator = MavenRepositorySystemUtils.newServiceLocator()
        .addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class)
        .addService(TransporterFactory.class, FileTransporterFactory.class)
        .addService(TransporterFactory.class, HttpTransporterFactory.class);

 // ...
container.addComponent(serviceLocator.lookup(RepositorySystem.class)
    , RepositorySystem.class
    , "default");
container.addComponent(serviceLocator.lookup(RemoteRepositoryManager.class)
    , RemoteRepositoryManager.class
    , "default");

And now we can finally have a maven-instance.

Vogel612
  • 5,620
  • 5
  • 48
  • 73