如何使用 Maven Core v4.0.0 设置和执行 MavenExecutionRequest?

问题描述 投票:0回答:0

我想使用 Maven Core(版本 4.0.0-alpha-5)库构建 Maven 项目。我现在想要的只是运行

install
阶段的工作概念验证。但是,我无法创建一个工作示例,也无法在 Internet 上找到单个教程或演示。

我的主要方法很简单,不需要解释:

public static void main(String[] args) throws Exception {
    Injector injector = Guice.createInjector(new CompleteMavenModule());

    Maven maven = injector.getInstance(Maven.class);
    MavenExecutionRequestPopulator populator = injector.getInstance(MavenExecutionRequestPopulator.class);

    DefaultMavenExecutionRequest request = new DefaultMavenExecutionRequest();
    request.setPom(new File("C:\\Users\\lc70844\\eclipse-workspace\\TestProject\\pom.xml"));
    request.setGoals(Arrays.asList("install"));

    populator.populateDefaults(request);

    MavenExecutionResult result = maven.execute(request);
    if (result.hasExceptions())
        result.getExceptions().stream().forEach(Throwable::printStackTrace);
}

当我运行它时,出现以下异常:

org.codehaus.plexus.component.repository.exception.ComponentLookupException: java.util.NoSuchElementException
      role: org.eclipse.aether.repository.WorkspaceReader
  roleHint: reactor
    at org.codehaus.plexus.DefaultPlexusContainer.lookup(DefaultPlexusContainer.java:267)
    at org.codehaus.plexus.DefaultPlexusContainer.lookup(DefaultPlexusContainer.java:255)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:246)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:228)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:153)
    at com.nhbb.test.MavenTest.main(MavenTest.java:43)
Caused by: java.util.NoSuchElementException
    at org.eclipse.sisu.inject.LocatedBeans$Itr.next(LocatedBeans.java:141)
    at org.eclipse.sisu.inject.LocatedBeans$Itr.next(LocatedBeans.java:1)
    at org.eclipse.sisu.plexus.DefaultPlexusBeans$Itr.next(DefaultPlexusBeans.java:76)
    at org.eclipse.sisu.plexus.DefaultPlexusBeans$Itr.next(DefaultPlexusBeans.java:1)
    at org.codehaus.plexus.DefaultPlexusContainer.lookup(DefaultPlexusContainer.java:263)
    ... 5 more

回到我的主要方法,你会注意到

Guice.createInjector(new CompleteMavenModule())
CompleteMavenModule
类是一个 Guice 模块,我设置它为我提供一个
DefaultMaven
实例:

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.inject.Named;
import javax.inject.Singleton;

import org.apache.maven.DefaultMaven;
import org.apache.maven.Maven;
import org.apache.maven.WorkspaceReaderModule;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.factory.DefaultArtifactFactory;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
import org.apache.maven.artifact.handler.manager.DefaultArtifactHandlerManager;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
import org.apache.maven.artifact.repository.metadata.io.DefaultMetadataReader;
import org.apache.maven.artifact.repository.metadata.io.MetadataReader;
import org.apache.maven.classrealm.ClassRealmManager;
import org.apache.maven.classrealm.ClassRealmManagerDelegate;
import org.apache.maven.classrealm.DefaultClassRealmManager;
import org.apache.maven.eventspy.EventSpy;
import org.apache.maven.execution.BuildResumptionAnalyzer;
import org.apache.maven.execution.BuildResumptionDataRepository;
import org.apache.maven.execution.DefaultBuildResumptionAnalyzer;
import org.apache.maven.execution.DefaultBuildResumptionDataRepository;
import org.apache.maven.execution.DefaultMavenExecutionRequestPopulator;
import org.apache.maven.execution.MavenExecutionRequestPopulator;
import org.apache.maven.execution.MojoExecutionListener;
import org.apache.maven.execution.ProjectExecutionListener;
import org.apache.maven.execution.scope.internal.MojoExecutionScopeCoreModule;
import org.apache.maven.extension.internal.CoreExports;
import org.apache.maven.graph.DefaultGraphBuilder;
import org.apache.maven.graph.GraphBuilder;
import org.apache.maven.internal.impl.EventSpyImpl;
import org.apache.maven.lifecycle.LifecycleMappingDelegate;
import org.apache.maven.lifecycle.MojoExecutionConfigurator;
import org.apache.maven.lifecycle.internal.DefaultExecutionEventCatapult;
import org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator;
import org.apache.maven.lifecycle.internal.DefaultLifecycleMappingDelegate;
import org.apache.maven.lifecycle.internal.DefaultLifecycleTaskSegmentCalculator;
import org.apache.maven.lifecycle.internal.DefaultMojoExecutionConfigurator;
import org.apache.maven.lifecycle.internal.DefaultProjectArtifactFactory;
import org.apache.maven.lifecycle.internal.ExecutionEventCatapult;
import org.apache.maven.lifecycle.internal.LifecycleExecutionPlanCalculator;
import org.apache.maven.lifecycle.internal.LifecycleTaskSegmentCalculator;
import org.apache.maven.lifecycle.internal.ProjectArtifactFactory;
import org.apache.maven.lifecycle.internal.builder.Builder;
import org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder;
import org.apache.maven.model.building.DefaultModelProcessor;
import org.apache.maven.model.building.DefaultModelSourceTransformer;
import org.apache.maven.model.building.ModelProcessor;
import org.apache.maven.model.building.ModelSourceTransformer;
import org.apache.maven.model.io.DefaultModelReader;
import org.apache.maven.model.io.ModelReader;
import org.apache.maven.model.locator.DefaultModelLocator;
import org.apache.maven.model.locator.ModelLocator;
import org.apache.maven.model.superpom.DefaultSuperPomProvider;
import org.apache.maven.model.superpom.SuperPomProvider;
import org.apache.maven.plugin.BuildPluginManager;
import org.apache.maven.plugin.DefaultBuildPluginManager;
import org.apache.maven.plugin.DefaultExtensionRealmCache;
import org.apache.maven.plugin.DefaultMojosExecutionStrategy;
import org.apache.maven.plugin.DefaultPluginArtifactsCache;
import org.apache.maven.plugin.DefaultPluginDescriptorCache;
import org.apache.maven.plugin.DefaultPluginRealmCache;
import org.apache.maven.plugin.ExtensionRealmCache;
import org.apache.maven.plugin.LegacySupport;
import org.apache.maven.plugin.MavenPluginManager;
import org.apache.maven.plugin.MavenPluginPrerequisitesChecker;
import org.apache.maven.plugin.MojosExecutionStrategy;
import org.apache.maven.plugin.PluginArtifactsCache;
import org.apache.maven.plugin.PluginDescriptorCache;
import org.apache.maven.plugin.PluginRealmCache;
import org.apache.maven.plugin.internal.DefaultLegacySupport;
import org.apache.maven.plugin.internal.DefaultMavenPluginManager;
import org.apache.maven.plugin.internal.DefaultPluginDependenciesResolver;
import org.apache.maven.plugin.internal.MavenPluginInternalModule;
import org.apache.maven.plugin.internal.MavenPluginJavaPrerequisiteChecker;
import org.apache.maven.plugin.internal.MavenPluginMavenPrerequisiteChecker;
import org.apache.maven.plugin.internal.PluginDependenciesResolver;
import org.apache.maven.plugin.prefix.PluginPrefixResolver;
import org.apache.maven.plugin.prefix.internal.DefaultPluginPrefixResolver;
import org.apache.maven.plugin.version.PluginVersionResolver;
import org.apache.maven.plugin.version.internal.DefaultPluginVersionResolver;
import org.apache.maven.project.DefaultProjectBuilder;
import org.apache.maven.project.DefaultProjectBuildingHelper;
import org.apache.maven.project.DefaultProjectDependenciesResolver;
import org.apache.maven.project.DefaultProjectRealmCache;
import org.apache.maven.project.ProjectBuilder;
import org.apache.maven.project.ProjectBuildingHelper;
import org.apache.maven.project.ProjectDependenciesResolver;
import org.apache.maven.project.ProjectRealmCache;
import org.apache.maven.project.RepositorySessionDecorator;
import org.apache.maven.project.artifact.DefaultProjectArtifactsCache;
import org.apache.maven.project.artifact.ProjectArtifactsCache;
import org.apache.maven.project.collector.DefaultProjectsSelector;
import org.apache.maven.project.collector.ProjectsSelector;
import org.apache.maven.repository.RepositorySystem;
import org.apache.maven.repository.internal.MavenResolverModule;
import org.apache.maven.repository.legacy.LegacyRepositorySystem;
import org.apache.maven.rtinfo.RuntimeInformation;
import org.apache.maven.rtinfo.internal.DefaultRuntimeInformation;
import org.apache.maven.session.scope.internal.SessionScopeModule;
import org.apache.maven.settings.crypto.DefaultSettingsDecrypter;
import org.apache.maven.settings.crypto.SettingsDecrypter;
import org.codehaus.plexus.DefaultPlexusContainer;
import org.codehaus.plexus.PlexusContainer;
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
import org.eclipse.aether.repository.WorkspaceReader;
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
import org.eclipse.aether.transport.file.FileTransporterFactory;
import org.eclipse.aether.transport.http.ChecksumExtractor;
import org.eclipse.aether.transport.http.HttpTransporterFactory;
import org.sonatype.plexus.components.cipher.DefaultPlexusCipher;
import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;

import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.name.Names;
import com.google.inject.util.Providers;

@SuppressWarnings("deprecation")
public class CompleteMavenModule extends AbstractModule {

    @Override
    protected void configure() {
        // org.apache.maven.repository.internal.MavenResolverModule does not provide
        // bindings for all the necessary dependencies
        install(new MavenResolverModule());
        install(new SessionScopeModule());
        install(new MojoExecutionScopeCoreModule());
        install(new MavenPluginInternalModule());
        install(new WorkspaceReaderModule());

        // make module "complete" by binding things not bound by MavenResolverModule
        bind(Maven.class).to(DefaultMaven.class).in(Singleton.class);
        bind(EventSpy.class).annotatedWith(Names.named("impl")).to(EventSpyImpl.class);
        bind(Builder.class).annotatedWith(Names.named("multithreaded")).to(MultiThreadedBuilder.class);
        bind(MojosExecutionStrategy.class).to(DefaultMojosExecutionStrategy.class).in(Singleton.class);
        bind(ArtifactRepositoryLayout.class).to(DefaultRepositoryLayout.class).in(Singleton.class);
        bind(ArtifactHandlerManager.class).to(DefaultArtifactHandlerManager.class).in(Singleton.class);
        bind(BuildResumptionAnalyzer.class).to(DefaultBuildResumptionAnalyzer.class).in(Singleton.class);
        bind(BuildResumptionDataRepository.class).to(DefaultBuildResumptionDataRepository.class).in(Singleton.class);
        bind(GraphBuilder.class).annotatedWith(Names.named(GraphBuilder.HINT)).to(DefaultGraphBuilder.class)
                .in(Singleton.class);
        bind(ExecutionEventCatapult.class).to(DefaultExecutionEventCatapult.class).in(Singleton.class);
        bind(LifecycleExecutionPlanCalculator.class).to(DefaultLifecycleExecutionPlanCalculator.class)
                .in(Singleton.class);
        bind(LifecycleMappingDelegate.class).annotatedWith(Names.named("default"))
                .to(DefaultLifecycleMappingDelegate.class).in(Singleton.class);
        bind(MojoExecutionConfigurator.class).annotatedWith(Names.named("default"))
                .to(DefaultMojoExecutionConfigurator.class).in(Singleton.class);
        bind(LifecycleTaskSegmentCalculator.class).to(DefaultLifecycleTaskSegmentCalculator.class).in(Singleton.class);
        bind(ProjectArtifactFactory.class).to(DefaultProjectArtifactFactory.class).in(Singleton.class);
        bind(ArtifactFactory.class).to(DefaultArtifactFactory.class).in(Singleton.class);
        bind(ModelLocator.class).to(DefaultModelLocator.class).in(Singleton.class);
        bind(ModelReader.class).to(DefaultModelReader.class).in(Singleton.class);
        bind(ModelProcessor.class).to(DefaultModelProcessor.class).in(Singleton.class);
        bind(SuperPomProvider.class).to(DefaultSuperPomProvider.class).in(Singleton.class);
        bind(ModelSourceTransformer.class).to(DefaultModelSourceTransformer.class).in(Singleton.class);
        bind(BuildPluginManager.class).to(DefaultBuildPluginManager.class).in(Singleton.class);
        bind(LegacySupport.class).to(DefaultLegacySupport.class).in(Singleton.class);
        bind(MavenPluginManager.class).to(DefaultMavenPluginManager.class).in(Singleton.class);
        bind(MavenPluginPrerequisitesChecker.class).annotatedWith(Names.named("java"))
                .to(MavenPluginJavaPrerequisiteChecker.class);
        bind(MavenPluginPrerequisitesChecker.class).annotatedWith(Names.named("maven"))
                .to(MavenPluginMavenPrerequisiteChecker.class);
        bind(ClassRealmManager.class).to(DefaultClassRealmManager.class).in(Singleton.class);
        bind(ExtensionRealmCache.class).to(DefaultExtensionRealmCache.class).in(Singleton.class);
        bind(PluginArtifactsCache.class).to(DefaultPluginArtifactsCache.class).in(Singleton.class);
        bind(PluginDescriptorCache.class).to(DefaultPluginDescriptorCache.class).in(Singleton.class);
        bind(PluginRealmCache.class).to(DefaultPluginRealmCache.class).in(Singleton.class);
        bind(PluginDependenciesResolver.class).to(DefaultPluginDependenciesResolver.class).in(Singleton.class);
        bind(PluginPrefixResolver.class).to(DefaultPluginPrefixResolver.class).in(Singleton.class);
        bind(MetadataReader.class).to(DefaultMetadataReader.class).in(Singleton.class);
        bind(PluginVersionResolver.class).to(DefaultPluginVersionResolver.class).in(Singleton.class);
        bind(ProjectBuilder.class).to(DefaultProjectBuilder.class);
        bind(ProjectBuildingHelper.class).to(DefaultProjectBuildingHelper.class).in(Singleton.class);
        bind(ProjectDependenciesResolver.class).to(DefaultProjectDependenciesResolver.class);
        bind(ProjectRealmCache.class).to(DefaultProjectRealmCache.class).in(Singleton.class);
        bind(ProjectArtifactsCache.class).to(DefaultProjectArtifactsCache.class).in(Singleton.class);
        bind(ProjectsSelector.class).to(DefaultProjectsSelector.class).in(Singleton.class);
        bind(RepositorySystem.class).to(LegacyRepositorySystem.class).in(Singleton.class);
        bind(RuntimeInformation.class).to(DefaultRuntimeInformation.class).in(Singleton.class);
        bind(SettingsDecrypter.class).to(DefaultSettingsDecrypter.class).in(Singleton.class);
        bind(PlexusContainer.class).to(DefaultPlexusContainer.class).in(Singleton.class);
        bind(WorkspaceReader.class).annotatedWith(Names.named("ide")).toProvider(Providers.of(null))
                .in(Singleton.class);
        bind(SecDispatcher.class).annotatedWith(Names.named("maven"))
                .toInstance(new DefaultSecDispatcher(new DefaultPlexusCipher()));
        bind(MavenExecutionRequestPopulator.class).to(DefaultMavenExecutionRequestPopulator.class).in(Singleton.class);
        bind(CoreExports.class).toInstance(new CoreExports(null, Collections.emptySet(), Collections.emptySet()));

        bind(RepositoryConnectorFactory.class).annotatedWith(Names.named("basic"))
                .to(BasicRepositoryConnectorFactory.class);
        bind(TransporterFactory.class).annotatedWith(Names.named("file")).to(FileTransporterFactory.class);
        bind(TransporterFactory.class).annotatedWith(Names.named("http")).to(HttpTransporterFactory.class);
    }

    @Provides
    @Singleton
    List<RepositorySessionDecorator> getRepositorySessionDecorators() {
        // No implementations exist for
        // org.apache.maven.project.RepositorySessionDecorator
        return Collections.emptyList();
    }

    @Provides
    @Singleton
    List<ClassRealmManagerDelegate> getClassRealmManagerDelegates() {
        // No implementations exist for
        // org.apache.maven.classrealm.ClassRealmManagerDelegate
        return Collections.emptyList();
    }

    @Provides
    @Singleton
    List<MavenPluginPrerequisitesChecker> getMavenPluginPrerequisitesCheckers(
            @Named("java") MavenPluginPrerequisitesChecker java,
            @Named("maven") MavenPluginPrerequisitesChecker maven) {
        return Arrays.asList(java, maven);
    }

    @Provides
    @Singleton
    List<MojoExecutionListener> getMojoExecutionListeners(MojoExecutionListener listener) {
        return Arrays.asList(listener);
    }

    @Provides
    @Singleton
    Map<String, MojoExecutionConfigurator> provideMojoExecutionConfigurators(
            @Named("default") MojoExecutionConfigurator defaultConfigurator) {
        return Stream.of(defaultConfigurator).collect(Collectors.toMap(k -> "default", v -> v));
    }

    @Provides
    @Singleton
    Map<String, LifecycleMappingDelegate> provideLifecycleMappingDelegates(
            @Named("default") LifecycleMappingDelegate defaultDelegate) {
        return Stream.of(defaultDelegate).collect(Collectors.toMap(k -> "default", v -> v));
    }

    @Provides
    @Singleton
    Map<String, ArtifactHandler> provideArtifactHandlers() {
        // No implementations exist for CompleteResolverModule.provideArtifactHandlers()
        return Collections.emptyMap();
    }

    @Provides
    @Singleton
    Map<String, ArtifactRepositoryLayout> provideRepositoryLayouts(ArtifactRepositoryLayout defaultLayout) {
        return Stream.of(defaultLayout).collect(Collectors.toMap(k -> "default", v -> v));
    }

    @Provides
    @Singleton
    List<ProjectExecutionListener> provideProjectExecutionListeners() {
        // No listeners
        return Collections.emptyList();
    }

    @Provides
    @Singleton
    Map<String, Builder> provideLifecycleBuilders(@Named("multithreaded") Builder multi) {
        return Stream.of(multi).collect(Collectors.toMap(k -> "multithreaded", v -> v));
    }

    @Provides
    @Singleton
    List<EventSpy> provideEventSpies(@Named("impl") EventSpy impl) {
        return Arrays.asList(impl);
    }

    @Provides
    @Singleton
    Map<String, ChecksumExtractor> provideChecksumExtractors() {
        return Collections.emptyMap();
    }

    @Provides
    @Singleton
    Set<RepositoryConnectorFactory> provideRepositoryConnectorFactories(
            @Named("basic") RepositoryConnectorFactory basic) {
        Set<RepositoryConnectorFactory> factories = new HashSet<>();
        factories.add(basic);
        return Collections.unmodifiableSet(factories);
    }

    @Provides
    @Singleton
    Set<TransporterFactory> provideTransporterFactories(@Named("file") TransporterFactory file,
            @Named("http") TransporterFactory http) {
        Set<TransporterFactory> factories = new HashSet<>();
        factories.add(file);
        factories.add(http);
        return Collections.unmodifiableSet(factories);
    }

}

马上,我知道我没有正确地做这件事。你会注意到这两行:

install(new MavenPluginInternalModule());
install(new WorkspaceReaderModule());

我必须创建这些模块来为

ReadOnlyPluginParametersValidator
DefaultMavenPluginValidator
ReactorReader
设置绑定,它们都是包私有类(ReactorReader 的绑定是我尝试解决上述错误).如果这些类是私有的,它会让我相信某些 Maven 类应该为我设置这些绑定。从我必须自己创建绑定这一事实来看,我怀疑我对依赖注入采取了不正确的方法。

我注意到 Maven 不直接使用 Guice,而是使用

PlexusContainer
接口结合 Plexus ClassworldsGuice 进行依赖注入。我对这些“Plexus”库是什么或如何工作没有深入的了解,我相信这是我问题的根源。同样,我找不到关于如何将这些库与 Maven 一起使用的文档、示例或演示。

我上面粘贴的异常源于DefaultMaven类中的这一行

try {
    WorkspaceReader reactorReader = container.lookup(WorkspaceReader.class, ReactorReader.HINT);
    repoSession.setWorkspaceReader(reactorReader);
} catch (ComponentLookupException e) {
    return addExceptionToResult(result, e);
}

在此代码段中,

container
是 PlexusContainer 实例,而不是 Guice 注入器。在这一点上,我非常确信我需要使用这个“Plexus”库而不是 Guice 来设置我的依赖注入,但是如何呢?我找不到任何解释如何做到这一点的东西。


编辑:这是我的 pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example.test</groupId>
    <artifactId>maven-core-test</artifactId>
    <version>0.0.1</version>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.google.inject</groupId>
            <artifactId>guice</artifactId>
            <version>5.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-core</artifactId>
            <version>4.0.0-alpha-5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-compat</artifactId>
            <version>4.0.0-alpha-5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-resolver-provider</artifactId>
            <version>4.0.0-alpha-5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.resolver</groupId>
            <artifactId>maven-resolver-connector-basic</artifactId>
            <version>1.9.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.resolver</groupId>
            <artifactId>maven-resolver-transport-file</artifactId>
            <version>1.9.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.resolver</groupId>
            <artifactId>maven-resolver-transport-http</artifactId>
            <version>1.9.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.resolver</groupId>
            <artifactId>maven-resolver-spi</artifactId>
            <version>1.9.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.resolver</groupId>
            <artifactId>maven-resolver-util</artifactId>
            <version>1.9.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.resolver</groupId>
            <artifactId>maven-resolver-impl</artifactId>
            <version>1.9.7</version>
        </dependency>
    </dependencies>
</project>
java maven dependencies guice plexus
© www.soinside.com 2019 - 2024. All rights reserved.