我熟悉Maven插件开发,我需要一个问题的帮助。
据我了解,将复杂的对象传递给Maven插件非常容易,但是传递类呢?
可以说我正在编写自己的仅包含2个类的插件。
Message.java
package abstractmessage;
public abstract class Message {
public abstract String getMessage();
}
MessageMojo.java
/**
* @goal message
*/
public class MessageMojo extends AbstractMojo {
/**
* @parameter expression="${message.messageClass}"
*/
private String messageClass ;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
Message message = null;
try {
Class<?> clazz = Class.forName(messageClass);
message = (Message) clazz.newInstance();
} catch (Exception e) {
getLog().error(e);
}
getLog().info(message.getMessage());
}
}
因此,插件需要扩展Message类的名称,并尝试对其进行动态初始化。
在实际的Maven-Project中扩展的Message类如下所示。
package message;
import abstractmessage.Message;
public class RealMessage extends Message {
@Override
public String getMessage() {
return "Hello plugin. From MavenProject.";
}
}
pom.xml使用该插件。
<build>
<plugins>
<plugin>
<artifactId>message-plugin</artifactId>
<groupId>message-plugin</groupId>
<version>1.0</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>message</goal>
</goals>
</execution>
</executions>
<configuration>
<messageClass>message.RealMessage</messageClass>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<artifactId>message-plugin</artifactId>
<groupId>message-plugin</groupId>
<version>1.0</version>
</dependency>
</dependencies>
但是当我执行maven:test时,我得到一个
java.lang.ClassNotFoundException: message.RealMessage
为什么这样?
最佳答案
您的插件的类加载器无权访问项目的类。它只能访问自己的类及其依赖项。
您有两个选择。
方法一是制作一个新的类加载器,以从当前项目及其依赖项中加载类。 surefire plugin是执行此操作的插件的一个示例-它可以加载已编译的单元测试类,并在未处于fork模式时运行它们。
从依赖关系创建新的类加载器并不是一件容易的事,但是首先,您需要在Mojo上放置@requiresDependencyResolution test
,并抓住项目的依赖关系(如果要包含的话,还有项目的build输出目录)搜索中的项目类),然后从这些JAR和目录中构造一个URLClassLoader。 Surefire的generateTestClasspath() method可能会作为起点。
另一种选择是在单独的项目中编译RealMessage
类,构建单独的JAR,并将其作为对消息插件的依赖。
在这种情况下,您的构建部分如下所示:
<build>
<plugins>
<plugin>
<artifactId>message-plugin</artifactId>
<groupId>message-plugin</groupId>
<version>1.0</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>message</goal>
</goals>
</execution>
</executions>
<configuration>
<messageClass>message.RealMessage</messageClass>
</configuration>
<dependencies>
<groupId>message-plugin-additions</groupId>
<artifactId>message-plugin-additions</artifactId>
<version>1.0</version>
</dependencies>
</plugin>
</plugins>
</build>
其中
message-plugin-additions
项目包含message.RealMessage
类。如果您愿意使用一个单独的项目,这可能会比第一种选择简单得多。