Ton*_*ada 15 java pom.xml maven-3 maven
如何获得完全解析的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没有通过依赖注入很容易地提供一个(至少我找不到),所以我们必须构建一个.为了使事情变得更好,该接口的唯一两个实现是包保护的,因此您需要使用一些反射魔法来实例化它.实现它的具体类是DefaultModelResolver和ProjectModelResolver.我能够像这样构建一个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
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中
归档时间: |
|
查看次数: |
11037 次 |
最近记录: |