如何从我自己的Maven库修改项目的Maven测试执行阶段的命令行参数?
How to modify the command line arguments of the Maven test execution phase of a project from my own Maven library?
我想创建一个 Maven 库,它将作为测试的辅助工具,因此它只会在测试阶段使用,就像 Hamcrest
、AssertJ
等。这个库需要一个 Java 代理才能正常运行,这个 Java 代理需要在启动时加载,并且 而不是 在 运行 时间内(因此通过命令行选项 -javaagent
)?
假设有一个(第三方)应用程序使用我的 Maven 库,如下所示:
<dependency>
<groupId>my.org</groupId>
<artifactId>my.library</artifactId>
<version>1.0</version>
<scope>test</scope>
</dependency>
在我的库中,我的代理将打包在 jar
中,但也会有一些其他代码来帮助加载代理。因此,当第三方应用程序中的测试 运行 时,我的库中的 Java 代理应该会自动加载,无需任何用户干预(因此唯一必要的步骤是将我的库添加为依赖项)。
如何在加载时加载此代理?可能吗?如果使用简单的 Maven 库是不可能的,那么如果我创建一个 Maven 插件(因此第三方应用程序将我的插件包含在它的 pom.xml
中)是否可能?
之所以要在load-time而不是运行time加载代理是因为在Java9之后,需要在命令行中添加-Djdk.attach.allowAttachSelf=true
才能允许在 运行 时间内加载代理,所以如果我可以添加 -javaagent
为什么要添加该参数
你不能。想象一下如果没有用户的知识并且除了添加依赖项之外没有任何其他操作,您将转换她的应用程序字节代码,那么安全隐患!
添加依赖项是一回事,通过调用方法或启动 Java 代理来激活它是另一回事。这应该在客户端应用程序的控制之下。可以在运行时附加 Java 代理而不使用 -javaagent:
,但客户端应用程序必须通过调用代理提供程序中的初始化方法来显式执行此操作。如果该合同在您和您的用户之间成立,即如果用户通过调用该假设的初始化方法进行合作(在您要修改的 类 加载之前足够早),您就可以做到。
有什么大不了的?您希望为您的用户提供代理功能。为什么他们不能像往常一样启动代理?给JVM命令行加一个参数就这么费劲吗?
在 OP 还编辑了问题后更新: 对于 Maven Surefire(单元测试)或其孪生 Maven Failsafe(集成测试),您想使用 argLine
参数,以便在命令行上使用 Java 代理启动目标 JVM。有关示例,请参阅 。它是关于在命令行上使用AspectJ 编织代理启动测试,但原理是相同的。基本上,它是这样的:
<properties>
<myDependency.version>1.2.3</myDependency.version>
</properties>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.9</version>
<configuration>
<argLine>
-javaagent:${settings.localRepository}/my/group-id/my-dependency/${myDependency.version}/my-dependency-${myDependency.version}.jar
</argLine>
</configuration>
<dependencies>
<dependency>
<groupId>my.group-id</groupId>
<artifactId>my-dependency</artifactId>
<version>${myDependency.version}</version>
</dependency>
</dependencies>
</plugin>
您只需要记录如何使用您的测试代理,让您的所有下游用户都知道。
如果您不希望半手动指定代理的路径,您可以使用 Maven Dependency Plugin 的 dependency:properties
目标来自动生成所有依赖项,包含路径名。但这不是必须的,只是锦上添花。
我想创建一个 Maven 库,它将作为测试的辅助工具,因此它只会在测试阶段使用,就像 Hamcrest
、AssertJ
等。这个库需要一个 Java 代理才能正常运行,这个 Java 代理需要在启动时加载,并且 而不是 在 运行 时间内(因此通过命令行选项 -javaagent
)?
假设有一个(第三方)应用程序使用我的 Maven 库,如下所示:
<dependency>
<groupId>my.org</groupId>
<artifactId>my.library</artifactId>
<version>1.0</version>
<scope>test</scope>
</dependency>
在我的库中,我的代理将打包在 jar
中,但也会有一些其他代码来帮助加载代理。因此,当第三方应用程序中的测试 运行 时,我的库中的 Java 代理应该会自动加载,无需任何用户干预(因此唯一必要的步骤是将我的库添加为依赖项)。
如何在加载时加载此代理?可能吗?如果使用简单的 Maven 库是不可能的,那么如果我创建一个 Maven 插件(因此第三方应用程序将我的插件包含在它的 pom.xml
中)是否可能?
之所以要在load-time而不是运行time加载代理是因为在Java9之后,需要在命令行中添加-Djdk.attach.allowAttachSelf=true
才能允许在 运行 时间内加载代理,所以如果我可以添加 -javaagent
你不能。想象一下如果没有用户的知识并且除了添加依赖项之外没有任何其他操作,您将转换她的应用程序字节代码,那么安全隐患!
添加依赖项是一回事,通过调用方法或启动 Java 代理来激活它是另一回事。这应该在客户端应用程序的控制之下。可以在运行时附加 Java 代理而不使用 -javaagent:
,但客户端应用程序必须通过调用代理提供程序中的初始化方法来显式执行此操作。如果该合同在您和您的用户之间成立,即如果用户通过调用该假设的初始化方法进行合作(在您要修改的 类 加载之前足够早),您就可以做到。
有什么大不了的?您希望为您的用户提供代理功能。为什么他们不能像往常一样启动代理?给JVM命令行加一个参数就这么费劲吗?
在 OP 还编辑了问题后更新: 对于 Maven Surefire(单元测试)或其孪生 Maven Failsafe(集成测试),您想使用 argLine
参数,以便在命令行上使用 Java 代理启动目标 JVM。有关示例,请参阅
<properties>
<myDependency.version>1.2.3</myDependency.version>
</properties>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.9</version>
<configuration>
<argLine>
-javaagent:${settings.localRepository}/my/group-id/my-dependency/${myDependency.version}/my-dependency-${myDependency.version}.jar
</argLine>
</configuration>
<dependencies>
<dependency>
<groupId>my.group-id</groupId>
<artifactId>my-dependency</artifactId>
<version>${myDependency.version}</version>
</dependency>
</dependencies>
</plugin>
您只需要记录如何使用您的测试代理,让您的所有下游用户都知道。
如果您不希望半手动指定代理的路径,您可以使用 Maven Dependency Plugin 的 dependency:properties
目标来自动生成所有依赖项,包含路径名。但这不是必须的,只是锦上添花。