如何记录pom工件和版本

waxmsbnn  于 2021-08-20  发布在  Java
关注(0)|答案(1)|浏览(224)

在projecta中,我有一个 MethodA 在里面 ClassA ,projectaJAR作为maven依赖项添加到不同的项目中,并且不同的项目正在调用 MethodA .
要求是
无论何时 MethodA 属于 ClassA 被任何其他项目调用时,我们需要记录被调用的项目工件id和版本,考虑到这些项目pom.xml中添加了项目依赖项。
笔记
以下仅适用于自项目(projecta)、创建属性文件和启用maven资源筛选

Create a property file

 src/main/resources/project.properties
 with the below content

version=${project.version}
artifactId=${project.artifactId}
Now turn on maven resource filtering

<resource>
 <directory>src/main/resources</directory>
 <filtering>true</filtering>
</resource>

方法

public class ClassA {
    final static Logger logger = Logger.getLogger(ClassA.class);

    public void MethodA{
        final Properties properties = new Properties();
        properties.load(this.getClassLoader().getResourceAsStream("project.properties"));
        logger.info(properties.getProperty("version"));
        logger.info(properties.getProperty("artifactId"));
          } 
}

在项目b中调用methoda时,我在logger中得到以下输出

version=${project.version}
   artifactId=${project.artifactId}    which is incorrect.

预期产出:

version = 1.0.0
artifactId = ProjectB

有没有更好的方法来记录调用项目工件id?如果 MethodA 是由projectc调用的,我们需要获取projectc artifactid和version。
要求:我们有30多个项目从projecta调用methoda,所以我们不应该在调用项目中做任何更改。

1bqhqjot

1bqhqjot1#

解决方案a:maven资源过滤

如果将pom代码段放在正确的pom部分,则应正确替换变量:

<build>
  <resources>
    <resource>
      <directory>src/main/resources</directory>
      <filtering>true</filtering>
    </resource>
  </resources>
</build>

您可以在中查看结果 target/classes 文件夹。在我通过添加一个空参数列表修复了错误的伪代码之后 () 并替换了无意义的 this.getClassLoader() 通过 getClass().getClassLoader() ,代码甚至可以编译并执行一些有意义的操作。在向stackoverflow这样的公共平台发布内容之前,您是否进行过测试?

import java.io.IOException;
import java.util.Properties;

public class ClassA {
  public void methodA() throws IOException {
    final Properties properties = new Properties();
    properties.load(getClass().getClassLoader().getResourceAsStream("project.properties"));
    System.out.println(properties.getProperty("version"));
    System.out.println(properties.getProperty("artifactId"));
  }

  public static void main(String[] args) throws IOException {
    new ClassA().methodA();
  }
}

从intellij idea运行时的控制台日志 mvn compile (因为我们需要maven来处理资源并将它们复制到 target/classes ):

1.9.8-SNAPSHOT
util

或者不管您的模块名称和版本是什么。
如果您看到的是变量名,要么您的类路径不指向jar,而是指向源目录,要么您有多个带有 project.properties 文件和其中一个文件中忘记了资源筛选。将加载在类路径上最先找到的文件。因此,在一个多模块项目中,最好使用不同的文件名,否则,如果先找到哪一个,或多或少是一种侥幸。
下一个问题是让方面或其他模块知道要加载哪个资源文件,以便更好地以某种方式链接到类或包名称,以便其他模块能够从包名称猜出资源文件。那么,您确实需要在模块之间分离干净的包名。我真不知道是否值得这么麻烦。

解决方案b:模板化maven插件+package-info.java+自定义注解

另一个想法是使用资源过滤或类似的插件 org.codehaus.mojo:templating-maven-plugin 用于将版本直接替换为 package-info.java 文件,然后在运行时从包信息中获取值。我用这个插件做了一个快速的本地测试,效果很好。我建议现在保持简单,只解决资源过滤问题。如果您需要我刚才描述的更通用的解决方案,请告诉我。

项目结构

更新:为了向您展示一个干净的解决方案,我将我侵入其中一个项目的快速解决方案提取到一个新的maven多模块项目中,如下所示:
比如说,我们有一个具有3个子模块的父pom: annotation -包含要在中的包上使用的注解 package-info.java 文件夹。可以很容易地修改为也适用于类。 library -应用程序模块要访问的示例库 application -示例应用程序
您可以在github上找到完整的项目:https://github.com/kriegaex/so_maven_artifactinforuntime_68321439
项目的目录布局如下所示:

$ tree
.
├── annotation
│   ├── pom.xml
│   └── src
│       └── main
│           └── java
│               └── de
│                   └── scrum_master
│                       └── stackoverflow
│                           └── q68321439
│                               └── annotation
│                                   └── MavenModuleInfo.java
├── application
│   ├── pom.xml
│   └── src
│       ├── main
│       │   ├── java
│       │   │   └── de
│       │   │       └── scrum_master
│       │   │           └── stackoverflow
│       │   │               └── q68321439
│       │   │                   └── application
│       │   │                       └── Application.java
│       │   └── java-templates
│       │       └── de
│       │           └── scrum_master
│       │               └── stackoverflow
│       │                   └── q68321439
│       │                       └── application
│       │                           └── package-info.java
│       └── test
│           └── java
│               └── de
│                   └── scrum_master
│                       └── stackoverflow
│                           └── q68321439
│                               └── application
│                                   └── ModuleInfoTest.java
├── library
│   ├── pom.xml
│   └── src
│       └── main
│           ├── java
│           │   └── de
│           │       └── scrum_master
│           │           └── stackoverflow
│           │               └── q68321439
│           │                   └── library
│           │                       └── LibraryClass.java
│           └── java-templates
│               └── de
│                   └── scrum_master
│                       └── stackoverflow
│                           └── q68321439
│                               └── library
│                                   └── package-info.java
└── pom.xml

请注意 src/java-templates 库和应用程序模块中的目录,包含 package-info.java 文件夹。目录名是模板化maven插件的默认名称,使插件配置不那么冗长。

母体聚甲醛

<?xml version="1.0" encoding="UTF-8"?>
<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>de.scrum-master.stackoverflow.q68321439</groupId>
  <artifactId>maven-artifact-info-runtime</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
  </properties>

  <modules>
    <module>annotation</module>
    <module>library</module>
    <module>application</module>
  </modules>

  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>templating-maven-plugin</artifactId>
          <version>1.0.0</version>
          <executions>
            <execution>
              <id>filter-src</id>
              <goals>
                <goal>filter-sources</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>

</project>

模块注解

<?xml version="1.0" encoding="UTF-8"?>
<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>

  <parent>
    <groupId>de.scrum-master.stackoverflow.q68321439</groupId>
    <artifactId>maven-artifact-info-runtime</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>annotation</artifactId>

</project>
package de.scrum_master.stackoverflow.q68321439.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PACKAGE)
public @interface MavenModuleInfo {
  String groupId();
  String artifactId();
  String version();
}

模块库

<?xml version="1.0" encoding="UTF-8"?>
<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>

  <parent>
    <groupId>de.scrum-master.stackoverflow.q68321439</groupId>
    <artifactId>maven-artifact-info-runtime</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>library</artifactId>

  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>templating-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

  <dependencies>
    <dependency>
      <groupId>de.scrum-master.stackoverflow.q68321439</groupId>
      <artifactId>annotation</artifactId>
      <version>${project.version}</version>
    </dependency>
  </dependencies>

</project>
package de.scrum_master.stackoverflow.q68321439.library;

public class LibraryClass {}

请注意,以下文件需要位于 library/src/main/java-templates/de/scrum_master/stackoverflow/q68321439/library/package-info.java . 在这里,您可以看到我们如何通过模板化maven插件,在构建过程中将maven属性替换为相应的值:

/**
 * This is the package description (...)
 */
@MavenModuleInfo(groupId = "${project.groupId}", artifactId = "${project.artifactId}", version = "${project.version}")
package de.scrum_master.stackoverflow.q68321439.library;

import de.scrum_master.stackoverflow.q68321439.annotation.MavenModuleInfo;

模块应用

<?xml version="1.0" encoding="UTF-8"?>
<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>

  <parent>
    <groupId>de.scrum-master.stackoverflow.q68321439</groupId>
    <artifactId>maven-artifact-info-runtime</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>application</artifactId>

  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>templating-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

  <dependencies>
    <dependency>
      <groupId>de.scrum-master.stackoverflow.q68321439</groupId>
      <artifactId>annotation</artifactId>
      <version>${project.version}</version>
    </dependency>
    <dependency>
      <groupId>de.scrum-master.stackoverflow.q68321439</groupId>
      <artifactId>library</artifactId>
      <version>${project.version}</version>
    </dependency>
    <dependency>
      <groupId>de.scrum-master.stackoverflow.q68321439</groupId>
      <artifactId>library</artifactId>
      <version>${project.version}</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

</project>
package de.scrum_master.stackoverflow.q68321439.application;

public class Application {
  public static void main(String[] args) {}
}

请注意,以下文件需要位于 application/src/main/java-templates/de/scrum_master/stackoverflow/q68321439/application/package-info.java . 在这里,您可以看到我们如何通过模板化maven插件,在构建过程中将maven属性替换为相应的值:

/**
 * This is the package description (...)
 */
@MavenModuleInfo(groupId = "${project.groupId}", artifactId = "${project.artifactId}", version = "${project.version}")
package de.scrum_master.stackoverflow.q68321439.application;

import de.scrum_master.stackoverflow.q68321439.annotation.MavenModuleInfo;
package de.scrum_master.stackoverflow.q68321439.application;

import de.scrum_master.stackoverflow.q68321439.annotation.MavenModuleInfo;
import de.scrum_master.stackoverflow.q68321439.library.LibraryClass;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class ModuleInfoTest {
  @Test
  public void test() {
    String groupId = "de.scrum-master.stackoverflow.q68321439";

    MavenModuleInfo libMavenInfo = logAndGetMavenModuleInfo("Library Maven info", LibraryClass.class.getPackage());
    assertEquals(groupId, libMavenInfo.groupId());
    assertEquals("library", libMavenInfo.artifactId());

    MavenModuleInfo appMavenInfo = logAndGetMavenModuleInfo("Application Maven info", Application.class.getPackage());
    assertEquals(groupId, appMavenInfo.groupId());
    assertEquals("application", appMavenInfo.artifactId());
  }

  private MavenModuleInfo logAndGetMavenModuleInfo(String message, Package aPackage) {
    MavenModuleInfo moduleInfo = aPackage.getAnnotation(MavenModuleInfo.class);
    System.out.println(message);
    System.out.println("  " + moduleInfo.groupId());
    System.out.println("  " + moduleInfo.artifactId());
    System.out.println("  " + moduleInfo.version());
    return moduleInfo;
  }
}

运行maven构建

现在通过运行maven构建 mvn clean test :

(...)
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ application ---
[INFO] Surefire report directory: C:\Users\alexa\Documents\java-src\SO_Maven_ArtifactInfoRuntime_68321439\application\target\surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running de.scrum_master.stackoverflow.q68321439.application.ModuleInfoTest
Library Maven info
  de.scrum-master.stackoverflow.q68321439
  library
  1.0-SNAPSHOT
Application Maven info
  de.scrum-master.stackoverflow.q68321439
  application
  1.0-SNAPSHOT
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.094 sec
(...)

相关问题