我做到了:-)
help:effective-pom and dependency:tree 真的根本无济于事。
我必须看看maven如何为MavenProject构建模型,并将其注入mojo中。help:effective-pom 已经收到了解析的模型,而 dependency:tree 只构建了 DependencyGraph,但它不会将 pom 的整个模型加载到内存中。
通过使用下面的代码,我能够获得一个 Model 对象,其中包含来自父级的所有信息,具有解析的 ${property} 表达式和扩展的传递依赖项。
操作方法如下:
1) 获取模型解析器
您将需要一个 interface org.apache.maven.model.resolution.ModelResolver 的实例。不幸的是,maven不能通过依赖注入轻松提供一个(至少我找不到一个),所以我们必须构建一个。为了使事情变得更好,该接口的仅有两个实现是受包保护的,因此您需要使用一些反射魔术来实例化它。实现它的具体类是DefaultModelResolver和ProjectModelResolver。我能够像这样构建一个默认模型解析器
/**
* 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);
}
}
2) 构建模型
当你有一个模型解析器时,你可以从一个 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;
}
看起来不漂亮,但它对我有用。:P