我找不到任何插件來打印依賴關係管理部分的依賴關係樹。
但是,您可以爲此編寫自己的MOJO。下面的所有代碼都是使用Maven 3.3.9編寫和測試的,通過修改新MOJO的依賴關係,可以很容易地將它適用於當前的Maven版本。
以下是Maven插件的POM:
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sample.plugin</groupId>
<artifactId>test-maven-plugin</artifactId>
<version>1.0.0</version>
<packaging>maven-plugin</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.3.9</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>3.3.9</version>
</dependency>
</dependencies>
</project>
和MOJO本身是:
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.DefaultProjectBuildingRequest;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.ProjectBuildingRequest;
import org.eclipse.aether.transfer.ArtifactNotFoundException;
@Mojo(name = "foo", requiresDependencyResolution = ResolutionScope.TEST)
public class MyMojo extends AbstractMojo {
@Parameter(defaultValue = "${project}", readonly = true, required = true)
private MavenProject project;
@Parameter(defaultValue = "${session}", readonly = true, required = true)
private MavenSession session;
@Component
private ArtifactHandler artifactHandler;
@Component
private ProjectBuilder projectBuilder;
public void execute() throws MojoExecutionException, MojoFailureException {
Set<Artifact> visitedArtifacts = new HashSet<Artifact>();
for (Dependency dependency : project.getDependencyManagement().getDependencies()) {
printDependencyTree(toArtifact(dependency), "", visitedArtifacts);
}
}
private void printDependencyTree(Artifact artifact, String level, Set<Artifact> visitedArtifacts) throws MojoExecutionException {
getLog().info(level + "+ " + artifact);
for (Dependency transitive : getTransitiveDependencies(artifact)) {
Artifact transitiveArtifact = toArtifact(transitive);
if (!visitedArtifacts.contains(transitiveArtifact)) {
visitedArtifacts.add(transitiveArtifact);
printDependencyTree(transitiveArtifact, level + " ", visitedArtifacts);
}
}
}
private List<Dependency> getTransitiveDependencies(Artifact artifact) throws MojoExecutionException {
try {
ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest());
buildingRequest.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL);
buildingRequest.setProject(null);
MavenProject mavenProject = projectBuilder.build(artifact, buildingRequest).getProject();
return mavenProject.getDependencies();
} catch (ProjectBuildingException e) {
if (e.getCause() != null && e.getCause().getCause() instanceof ArtifactNotFoundException) {
//ignore
return new ArrayList<Dependency>();
}
throw new MojoExecutionException("Error while building project", e);
}
}
private Artifact toArtifact(Dependency dependency) {
return new DefaultArtifact(dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion(), dependency.getScope(), dependency.getType(), dependency.getClassifier(), artifactHandler);
}
}
這是一個有點複雜,但其主要成分有:
- 我們注入了當前的Maven項目,爲此我們使用來解決依賴關係管理部分中的依賴關係。
- 對於每個依賴項,我們通過在內存中使用
ProjectBuilder
API構建Maven項目來解決其傳遞依賴性問題。這需要將我們的Dependency
轉換爲Artifact
(這是在toArtifact
的幫助下完成的),構建一個ProjectBuildingRequest
將項目設置爲null
(我注意到我們還需要將驗證級別設置爲最小,以便API不會失敗稍不符合要求的POMs),最後致電projectBuilder.build
建立該項目。有了這個項目,我們可以用mavenProject.getDependencies()
返回它的依賴關係。
- 所有這些都是在遞歸方法內部完成的,它將簡單地打印工件的基本信息。遞歸性級別是通過每次向下一級時預先添加兩個空格來完成的。另外,由於我們可能會重新訪問一個已經受到感染的工件(因此最終會陷入無限循環),所以我保留了一組訪問的工件,並在已經受到鼓勵的工件再次受到鼓勵時結束樹。
ArtifactNotFoundException
例外情況下,如果我們嘗試下載某種找不到的工件,則可能會發生這種情況。
- 第一次啓動時,項目構建器API將從您配置的replactors中下載所有依賴關係,因此會混淆日誌。您將希望第二次啓動它以更好地查看輸出。
爲樣本,我用下面的依賴關係管理部分
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.4.0.GA</version>
</dependency>
</dependencies>
</dependencyManagement>
測試這個,結果是:
+ org.hibernate:hibernate-annotations:jar:3.4.0.GA
+ org.hibernate:ejb3-persistence:jar:1.0.2.GA:compile
+ org.hibernate:hibernate-commons-annotations:jar:3.1.0.GA:compile
+ org.slf4j:slf4j-api:jar:1.4.2:compile
+ junit:junit:jar:3.8.1:test
+ org.hibernate:hibernate-core:jar:3.3.0.SP1:compile
+ antlr:antlr:jar:2.7.6:compile
+ commons-collections:commons-collections:jar:3.1:compile
+ dom4j:dom4j:jar:1.6.1:compile
+ jaxme:jaxme-api:jar:0.3:compile
+ jaxen:jaxen:jar:1.1-beta-6:compile
+ dom4j:dom4j:jar:1.5.2:compile
+ jaxen:jaxen:jar:1.1-beta-4:compile
+ jdom:jdom:jar:b10:compile
+ xerces:xmlParserAPIs:jar:2.6.2:compile
+ xerces:xercesImpl:jar:2.6.2:compile
+ xom:xom:jar:1.0b3:compile
+ xerces:xmlParserAPIs:jar:2.6.1:compile
+ xerces:xercesImpl:jar:2.2.1:compile
+ com.ibm.icu:icu4j:jar:2.6.1:compile
+ xalan:xalan:jar:2.6.0:compile
+ xml-apis:xml-apis:jar:2.0.2:compile
+ xerces:xercesImpl:jar:2.6.0:compile
+ org.ccil.cowan.tagsoup:tagsoup:jar:0.9.7:compile
+ javax.servlet:servlet-api:jar:2.4:provided
+ msv:xsdlib:jar:20030807:compile
+ msv:relaxngDatatype:jar:20030807:compile
+ pull-parser:pull-parser:jar:2:compile
+ xpp3:xpp3:jar:1.1.3.3:compile
+ stax:stax-api:jar:1.0:compile
+ junitperf:junitperf:jar:1.8:test
+ stax:stax-ri:jar:1.0:test
+ xalan:xalan:jar:2.5.1:test
+ jdom:jdom:jar:1.0:compile
+ xml-apis:xml-apis:jar:1.0.b2:compile
+ jaxen:jaxen:jar:1.0-FCS:compile
+ saxpath:saxpath:jar:1.0-FCS:compile
+ xalan:xalan:jar:2.5.0:compile
+ javax.transaction:jta:jar:1.1:compile
+ javax.security:jaas:jar:1.0.01:provided
+ javax.security:jacc:jar:1.0:provided
+ ant:ant:jar:1.6.5:provided
+ xml-apis:xml-apis:jar:1.3.04:compile
+ javassist:javassist:jar:3.4.GA:compile
+ org.hibernate:hibernate-cglib-repack:jar:2.1_3:compile
要進行測試,你當然會需要將該MOJO綁定到測試Maven項目,您需要事先安裝MOJO。在具有上述
POM中的Maven插件
- 運行
mvn clean install
創建一個新的測試Maven項目,宣佈插件。
爲MOJO插件配置上面可以是:
<plugin>
<groupId>sample.plugin</groupId>
<artifactId>test-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<id>t</id>
<goals>
<goal>foo</goal>
</goals>
<phase><!-- something --></phase>
</execution>
</executions>
</plugin>
如果使用的是Eclipse有一個dependencyManagement部分,這將列出所有與依賴傳遞依賴沿 – Pragnani