首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >读取Maven项目中的Java构建路径条目

读取Maven项目中的Java构建路径条目
EN

Stack Overflow用户
提问于 2016-12-13 16:23:38
回答 3查看 2.2K关注 0票数 12

我有一个项目,它的类路径(Java buildpath)中有依赖项。现在,我已经将其转换为maven项目,并使用我定制的Maven插件对其进行编译。以下是我的POM文件-

代码语言:javascript
复制
<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-

代码语言:javascript
复制
    <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 -

代码语言:javascript
复制
<?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

代码语言:javascript
复制
 <?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 -

代码语言:javascript
复制
 @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 {
    }
}

现在,在编译阶段,我需要类路径中存在的JAR文件的列表。我怎么才能得到它呢?我已经尝试过了--但大多数都返回了目标文件夹路径和类文件夹路径

代码语言:javascript
复制
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();

我要编译的项目结构

EN

回答 3

Stack Overflow用户

发布于 2016-12-15 21:58:17

您缺少的关键成分是requiresDependencyResolution,它表示插件将可用的一组依赖项。来自the Mojo API reference

将此Mojo标记为需要在执行之前解析指定类路径中的依赖项。..。如果注释根本不存在,那么mojo就不能对与Maven项目相关联的工件做出任何假设。

要访问项目的编译时依赖项,可以使用ResolutionScope.COMPILE

compile解析范围= compile + system + provided依赖项

其中,还有访问运行时范围依赖项的COMPILE_PLUS_RUNTIME,或者添加测试范围依赖项的TEST。当该参数不存在于Maven插件时,Maven项目的类路径元素将不可用,这就是您遇到的行为。

因此,如果您希望Maven插件获得作为当前Maven项目的依赖项的compile- files文件的列表,您可以:

代码语言:javascript
复制
@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()方法:

代码语言:javascript
复制
public void execute() throws MojoExecutionException, MojoFailureException {
    Set<Artifact> artifacts = project.getArtifacts();
    for (Artifact artifact : artifacts) {
        System.out.println(artifact.getFile());
    }
}

请注意,要使其正常工作,您需要确保compile阶段(或test-compile)已经运行。这些列表是懒惰地填充的。如果插件声明了TESTrequiresDependencyResolution,那么运行mvn clean test将确保插件能够访问测试范围依赖项。类似地,如果插件声明了requiresDependencyResolution of COMPILE,那么运行mvn clean compile (同时将阶段更改为<phase>compile</phase>)将确保插件能够访问编译范围的依赖项。

几个附注:

  • 文件lifecycle.xml必须位于src/main/resources/META-INF/maven内部。注意,这个文件实际上在您的设置中完全没有使用,因为您没有在components.xml中使用新的customLifeCycle,而是覆盖了ear
  • 文件components.xml必须位于src/main/resources/META-INF/plexus中。注意,<compile>com.test:my-maven-plugin:mycompile</compile>必须与插件的组id和工件id相匹配;
  • 测试项目需要像这样使用插件:

ear org.apache.maven maven-core 3.0 com.test my-maven-plugin 0.0.1-SNAPSHOT true

然后,您可以运行mvn clean package,插件将正确打印maven-core (例如)及其dependencies.的JAR文件的路径

票数 4
EN

Stack Overflow用户

发布于 2016-12-13 17:19:39

这对我很有效。

我在这里找到的https://www.mkyong.com/java/how-to-print-out-the-current-project-classpath/

代码语言:javascript
复制
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());
        }
    }
}
票数 0
EN

Stack Overflow用户

发布于 2016-12-18 22:57:25

作为上一个答案的补充,您可以像这样读取所有Class-Path:

代码语言:javascript
复制
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;
}

如果您需要更深入地了解依赖关系:

代码语言:javascript
复制
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)
                        for (String lib : classpath.split(" ")) {
                            try {
                                list.addAll(getClassPathsFromJar(lib));
                            } catch (IOException ioe)
                            {
                                list.add(lib);
                            }
                        }
                }
            }
            catch (Exception e) {
                // Silently ignore wrong manifests or stop the compilation
            }
        }
    } catch (IOException e1) {
    // Silently ignore wrong manifests or stop the compilation
    }
    return list;
}

public static List<String> getClassPathsFromJar(String lib) throws IOException {
    List<String> entries = new ArrayList<String>();
    JarFile jar = new JarFile(lib);
    Manifest manifest = jar.getManifest();
    if (manifest == null) {
        entries.add(lib);
        return entries;
    }
    Attributes mainAttribs = manifest.getMainAttributes();
    String classpath = mainAttribs.getValue("Class-Path");
    if (classpath == null) {
        entries.add(lib);
        return entries;
    }
    for (String l : classpath.split(" ")) {
        entries.addAll(getClassPathsFromJar(l));
    }
    return entries;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41116511

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档