我做到了 :-)
help:effective-pom 和 dependency:tree 真的一点帮助都没有。
我必须看看 maven 如何为注入 mojo 的 MavenProject 构建模型。help:effective-pom 已经接收到解析的模型,而 dependency:tree 只构建了一个 DependencyGraph,但它不会将 pom 的整个模型加载到内存中。
通过使用下面的代码,我能够从父级获取包含所有信息的模型对象,解析 ${property} 表达式,并扩展传递依赖项。
就是这样:
1) 获取模型解析器
您将需要一个接口 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);
}
}
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;
}
看起来不漂亮,但它对我有用..:P