我有一个在其类路径(Java buildpath)中具有依赖项的项目。现在我已将其转换为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>com.test</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>ear</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>com.my.maven.plugin</groupId>
<artifactId>my-maven-plugin</artifactId>
<version>0.0.1</version>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
</project>
在my-maven-plugin
中,我已经覆盖了编译阶段 -
maven-plugin 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>com.test</groupId>
<artifactId>my-maven-plugin</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>maven-plugin</packaging>
<name>my-maven-plugin</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>3.3.9</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.3.9</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-compat</artifactId>
<version>3.3.9</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
<version>3.3.9</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-archiver</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5</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.surefire</groupId>
<artifactId>maven-surefire-common</artifactId>
<version>2.19.1</version>
</dependency>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-api</artifactId>
<version>2.19.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-annotations</artifactId>
<version>1.6</version>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.19.1</version>
</dependency>
</dependencies>
</project>
lifecycle.xml -
<?xml version="1.0" encoding="UTF-8"?>
<lifecycles>
<lifecycle>
<id>customLifeCycle</id>
<phases>
<phase>
<id>compile</id>
<executions>
<execution>
<goals>
<goal>mycompile</goal>
</goals>
</execution>
</executions>
</phase>
</phases>
</lifecycle>
</lifecycles>
的components.xml
<?xml version="1.0" encoding="UTF-8"?>
<component-set>
<components>
<component>
<role>org.apache.maven.artifact.handler.ArtifactHandler</role>
<role-hint>ear</role-hint>
<implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
<configuration>
<type>ear</type>
<extension>ear</extension>
<language>java</language>
<packaging>ear</packaging>
</configuration>
</component>
<component>
<role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
<role-hint>ear</role-hint>
<implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
<configuration>
<phases>
<process-resources>org.apache.maven.plugins:maven-resources-plugin:resources</process-resources>
<compile>com.test:my-maven-plugin:mycompile</compile>
<process-test-resources>org.apache.maven.plugins:maven-resources-plugin:testResources</process-test-resources>
<test-compile>org.apache.maven.plugins:maven-compiler-plugin:testCompile</test-compile>
<test>org.apache.maven.plugins:maven-surefire-plugin:test</test>
<install>org.apache.maven.plugins:maven-install-plugin:install</install>
<deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
</phases>
</configuration>
</component>
</components>
</component-set>
并且,重写编译mojo -
@Mojo( name = "mycompile", defaultPhase = LifecyclePhase.COMPILE )
public class MyCompileMojo extends AbstractMojo{
@Parameter( defaultValue = "${project}", readonly = true, required = true )
private MavenProject project;
public void execute() throws MojoExecutionException, MojoFailureException {
}
}
现在,在编译阶段,我想要一个存在于classpath中的JAR文件列表。我怎么才能得到它?我试过跟随 - 但大多数都返回目标文件夹路径和类文件夹路径
List<String> list1 = project.getCompileClasspathElements();
List<String> list2 = project.getRuntimeClasspathElements();
List<String> list3 = project.getSystemClasspathElements();
List<String> list4 = project.getTestClasspathElements();
List<Dependency> list5 = project.getCompileDependencies();
Properties list6 = project.getProperties();
List<Dependency> list7 = project.getSystemDependencies();
List<Dependency> list8 = project.getRuntimeDependencies();
我要编译的项目结构
答案 0 :(得分:4)
您缺少的关键因素是requiresDependencyResolution
,它代表了插件可用的一组依赖项。来自the Mojo API reference:
将此Mojo标记为要求在执行之前解析指定类路径中的依赖项。 [...]如果注释根本不存在,则mojo不得对与Maven项目相关的工件做出任何假设。
要访问项目的编译时依赖项,可以使用ResolutionScope.COMPILE
:
compile
解析范围=compile
+system
+provided
个依赖关系
除此之外,还有COMPILE_PLUS_RUNTIME
也可以访问运行时范围的依赖项,或者TEST
来添加测试范围的依赖项。当Maven插件不存在此参数时,Maven项目的类路径元素将不可用,这是您遇到的行为。
因此,如果您希望Maven插件获取当前Maven项目的依赖项的编译块JAR文件列表,您可以:
@Mojo(name = "mycompile", defaultPhase = LifecyclePhase.COMPILE, requiresDependencyResolution = ResolutionScope.COMPILE)
public class MyCompileMojo extends AbstractMojo {
@Parameter(defaultValue = "${project}", readonly = true, required = true)
private MavenProject project;
public void execute() throws MojoExecutionException, MojoFailureException {
try {
List<String> list = project.getCompileClasspathElements();
getLog().info(list.toString());
} catch (DependencyResolutionRequiredException e) {
throw new MojoFailureException("Couldn't resolve compile dependencies", e);
}
}
}
方法getCompileClasspathElements()
返回每个编译时依赖项的JAR文件的路径列表。它还将包含当前Maven项目的target/classes
文件夹的路径,因为它包含项目的已编译主Java源代码。上面的代码只会打印此列表。类似地,您可以将getTestClasspathElements()
与ResolutionScope.TEST
一起使用,以获得测试范围依赖项列表以及编译时依赖项。
如果您只想要依赖项的JAR文件的路径,而没有项目本身的类,则可以使用方法getArtifacts()
代替:
public void execute() throws MojoExecutionException, MojoFailureException {
Set<Artifact> artifacts = project.getArtifacts();
for (Artifact artifact : artifacts) {
System.out.println(artifact.getFile());
}
}
请注意,要使其正常工作,您需要确保compile
阶段(或test-compile
)已运行。这些名单是人口稠密的。运行mvn clean test
将确保插件可以访问测试范围依赖项,如果它声明requiresDependencyResolution
TEST
。同样,运行mvn clean compile
(以及将阶段更改为<phase>compile</phase>
)将确保插件可以访问编译范围依赖项,如果它声明requiresDependencyResolution
COMPILE
。< / p>
一些旁注:
lifecycle.xml
必须位于src/main/resources/META-INF/maven
内。请注意,此文件在您的设置中实际上完全未使用,因为您未在customLifeCycle
内使用新components.xml
,而是覆盖ear
; components.xml
必须位于src/main/resources/META-INF/plexus
内。请注意,<compile>com.test:my-maven-plugin:mycompile</compile>
必须与插件的组ID和工件ID匹配; 测试项目需要像这样使用插件:
<packaging>ear</packaging> <!-- because your lifecycle mapping override ear -->
<dependencies>
<!-- some dependencies like maven-core -->
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>3.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.test</groupId>
<artifactId>my-maven-plugin</artifactId>
<version>0.0.1-SNAPSHOT</version>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
然后您可以运行mvn clean package
,插件将正确打印maven-core
(例如)及其依赖项的JAR文件的路径。
答案 1 :(得分:0)
这对我有用。
找到了它package com.mkyong.io;
import java.net.URL;
import java.net.URLClassLoader;
public class App{
public static void main (String args[]) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader)cl).getURLs();
for(URL url: urls){
System.out.println(url.getFile());
}
}
}
答案 2 :(得分:0)
完成上一个答案后,您可以阅读所有类路径:
console.log
如果您需要深入了解依赖项:
public static List<String> getClassPaths() {
List<String> list = new ArrayList<String>();
Enumeration res;
try {
res = Thread.currentThread().getContextClassLoader().getResources(JarFile.MANIFEST_NAME);
while (res.hasMoreElements()) {
try {
URL url = (URL)res.nextElement();
InputStream is = url.openStream();
if (is != null) {
Manifest manifest = new Manifest(is);
Attributes mainAttribs = manifest.getMainAttributes();
String classpath = mainAttribs.getValue("Class-Path");
if (classpath != null)
list.add(classpath);
}
}
catch (Exception e) {
// Silently ignore wrong manifests or stop the compilation
}
}
} catch (IOException e1) {
// Silently ignore wrong manifests or stop the compilation
}
return list;
}