如何获得完全解析的pom文件模型?

Ton*_*ada 15 java pom.xml maven-3 maven

如何获得完全解析的pom文件模型?

这基本上是我如何编程构建pom文件的有效模型的改述?

我正在构建一个maven插件,它针对一组模块执行一些验证规则.这些模块的pom文件可用,但在执行插件时它们不是reactor的一部分.

我可以使用此方法读取pom文件并获取相应的Model对象(为简单起见,删除了异常处理):

private Model pomToModel(String pathToPom) throws Exception {
    BufferedReader in = new BufferedReader(new FileReader(pathToPom));
    MavenXpp3Reader reader = new MavenXpp3Reader();
    Model model = reader.read(in);
    return model;
}
Run Code Online (Sandbox Code Playgroud)

它可以工作,但Model对象只有pom文件所具有的相同信息.

如何改进该方法以便获得"完全解析"的Model对象?通过完全解决,我的意思是:具有所有传递依赖关系以及来自父poms的所有其他内容.

干杯!

Ton*_*ada 10

我做的 :-)

帮助:有效的pom和依赖:树根本没有帮助.

我不得不看看maven如何构建MavenProject的模型,它被注入mojo中.help:effective-pom已经收到已解析的Model,依赖:tree只构建一个DependencyGraph,但它不会将pom的整个模型加载到内存中.

通过使用下面的代码,我能够获得一个Model对象,其中包含来自父级的所有信息,具有已解析的$ {property}表达式,以及扩展的传递依赖性.

这是如何做:

1)获取ModelResolver

您将需要一个接口org.apache.maven.model.resolution.ModelResolver的实例.不幸的是,maven没有通过依赖注入很容易地提供一个(至少我找不到),所以我们必须构建一个.为了使事情变得更好,该接口的唯一两个实现是包保护的,因此您需要使用一些反射魔法来实例化它.实现它的具体类是DefaultModelResolverProjectModelResolver.我能够像这样构建一个DefaultModelResolver

/**
 * The Maven Project Object
 * 
 * @parameter expression="${project}"
 * @required2.0
 * @readonly
 */
protected MavenProject project;

/**
 * @component
 */
protected ArtifactResolver artifactResolver;

/**
 * @component
 */
protected RemoteRepositoryManager remoteRepositoryManager;

private Object invoke( Object object, String method )
        throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
    return object.getClass().getMethod( method ).invoke( object );
}

private org.apache.maven.model.resolution.ModelResolver makeModelResolver() throws MojoExecutionException {
    try {
        ProjectBuildingRequest projectBuildingRequest =
        (ProjectBuildingRequest) invoke( project, "getProjectBuildingRequest" );

        Class c = Class.forName("org.apache.maven.repository.internal.DefaultModelResolver");
        Constructor ct = c.getConstructor(new Class[]{RepositorySystemSession.class, 
                RequestTrace.class, String.class,
                ArtifactResolver.class, RemoteRepositoryManager.class,
                List.class});
        ct.setAccessible(true);
        return (org.apache.maven.model.resolution.ModelResolver) ct.newInstance(new Object[]{
                projectBuildingRequest.getRepositorySession(), 
                null, null, artifactResolver, remoteRepositoryManager, 
                project.getRemoteProjectRepositories()});
    } catch (Exception e) {
        throw new MojoExecutionException("Error instantiating DefaultModelResolver", e);
    }
}
Run Code Online (Sandbox Code Playgroud)

2)构建模型

如果你有modelResolver,你可以从pom文件构建模型,如下所示:

public Model resolveEffectiveModel(File pomfile) {
    try {
        return modelBuilder.build(makeModelBuildRequest(pomfile)).getEffectiveModel();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }   
}

private ModelBuildingRequest makeModelBuildRequest(File artifactFile) {
    DefaultModelBuildingRequest mbr = new DefaultModelBuildingRequest();
    mbr.setPomFile(artifactFile);
    mbr.setModelResolver(modelResolver); // <-- the hard-to-get modelResolver
    return mbr;
}
Run Code Online (Sandbox Code Playgroud)

看起来不漂亮,但它对我有用..:P


Pet*_*nto 7

Romain提供了上面的好答案,但它使用的是从maven 3.x中删除的已弃用的类.更新后的版本如下:

@Parameter( defaultValue = "${project}", readonly = true )
private MavenProject project;

@Component
private RepositorySystem repositorySystem;

@Component
private ProjectBuilder mavenProjectBuilder;

@Parameter( defaultValue = "${session}", readonly = true )
private MavenSession session;

private MavenProject getMavenProject(String groupId, String artifactId, String version) throws ProjectBuildingException {

    Artifact pomArtifact = repositorySystem.createProjectArtifact(groupId, artifactId, version);
    ProjectBuildingResult build = mavenProjectBuilder.build(pomArtifact, session.getProjectBuildingRequest());

    return build.getProject();

}
Run Code Online (Sandbox Code Playgroud)

一个工作示例位于hierarchy-maven-plugin中