Maven 2 Maven插件可以';t荷载等级

Maven 2 Maven插件可以';t荷载等级,maven-2,maven-plugin,Maven 2,Maven Plugin,我正在尝试制作一个需要使用反射的maven插件。我想要一个项目来运行插件,并给它项目中一个类的全名,插件将通过反射加载它以从中获取信息 但是类加载器有些奇怪,因为当我使用它时,它找不到类 Class.forName("package.MyClass"); 看看这个,我不太清楚当我的插件的类加载器在不同的项目中运行时,是否可以访问该项目的类。我肯定有更好的方法,但下面是我如何让它工作的: 将以下内容添加到mojo顶部的javadoc中: @requiresDependencyResolution

我正在尝试制作一个需要使用反射的maven插件。我想要一个项目来运行插件,并给它项目中一个类的全名,插件将通过反射加载它以从中获取信息

但是类加载器有些奇怪,因为当我使用它时,它找不到类

Class.forName("package.MyClass");

看看这个,我不太清楚当我的插件的类加载器在不同的项目中运行时,是否可以访问该项目的类。

我肯定有更好的方法,但下面是我如何让它工作的:

将以下内容添加到mojo顶部的javadoc中: @requiresDependencyResolution运行时

添加MavenProject参数:

/**
 * @parameter expression="${project}"
 * @required
 * @readonly
 */
private MavenProject project;
然后,您可以在运行时获取依赖项,并创建自己的类加载器:

List runtimeClasspathElements = project.getRuntimeClasspathElements();
URL[] runtimeUrls = new URL[runtimeClasspathElements.size()];
for (int i = 0; i < runtimeClasspathElements.size(); i++) {
  String element = (String) runtimeClasspathElements.get(i);
  runtimeUrls[i] = new File(element).toURI().toURL();
}
URLClassLoader newLoader = new URLClassLoader(runtimeUrls,
  Thread.currentThread().getContextClassLoader());
Class bundle = newLoader.loadClass("package.MyClass");

您应该考虑使用此来将运行时类路径元素添加到当前类域中。(您可以使用

PluginDescriptor
检索类领域

List<String> runtimeClasspathElements = project.getRuntimeClasspathElements();
ClassRealm realm = descriptor.getClassRealm();

for (String element : runtimeClasspathElements)
{
    File elementFile = new File(element);
    realm.addURL(elementFile.toURI().toURL());
}

今天我遇到了这个问题。上面的建议对我不起作用,我想我会将我的解决方案提交到列表中。我使用了HibernateExporter mojo源代码,可以在以下位置查看:

/**
*@parameter expression=“${project}”
*@必需
*@readonly
*/
私人马文项目;
私有类加载器getClassLoader()引发MojoExecutionException异常
{
尝试
{
List classpathElements=project.getCompileClasspathElements();
添加(project.getBuild().getOutputDirectory());
添加(project.getBuild().getTestOutputDirectory());
URL URL[]=新URL[classpathElements.size()];
对于(int i=0;i
还要确保您使用的是正确的MavenProject类

<dependency>
  <groupId>org.apache.maven</groupId>
  <artifactId>maven-core</artifactId>
  <version>3.0.3</version>
</dependency>

<dependency>
  <groupId>org.apache.maven</groupId>
  <artifactId>maven-plugin-api</artifactId>
  <version>3.0.3</version>
</dependency>

org.apache.maven
马文堆芯
3.0.3
org.apache.maven
maven插件api
3.0.3

这对我和maven3来说很有效,可以将依赖项放到插件类路径中

诀窍是使用@Component注入PluginDescriptor。否则它将无法正确设置

@Component
private MavenProject project;
@Component
private PluginDescriptor descriptor;

private void addDependenciesToClasspath(String artifactId) {
    for (Artifact artifact : project.getDependencyArtifacts()) {
        if (artifact.getArtifactId().equals(artifactId)) {
            try {
                final URL url = artifact.getFile().toURI().toURL();
                final ClassRealm realm = descriptor.getClassRealm();
                realm.addURL(url);
            }
            catch (MalformedURLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

没关系,我们需要自己制作类加载器

如何从MyMojo的execute方法中获得PluginDescriptor的句柄?嘿,Dave,我调整了我的答案,希望它能帮助你。(你不需要设置器,因为这是通过afair反射设置的)。这是一个很好的答案。它与公认的答案相同,但更全面地探索了Maven的ClassRealm内容。(不要轻视公认的答案,因为这肯定有提前两年的好处。)对于Maven 3.2.5+,被接受的答案对我来说不起作用,这非常有效。我希望找到更多关于Maven类领域的文档。如中所述,现在,您必须使用@Component注入PluginDescriptor。此处不鼓励仅链接的答案。链接可能会随着时间的推移而中断,从而使您的答案无效。请包含摘要你的答案是什么,以及为什么它可能比已经提供的其他答案更好。
<dependency>
  <groupId>org.apache.maven</groupId>
  <artifactId>maven-core</artifactId>
  <version>3.0.3</version>
</dependency>

<dependency>
  <groupId>org.apache.maven</groupId>
  <artifactId>maven-plugin-api</artifactId>
  <version>3.0.3</version>
</dependency>
@Component
private MavenProject project;
@Component
private PluginDescriptor descriptor;

private void addDependenciesToClasspath(String artifactId) {
    for (Artifact artifact : project.getDependencyArtifacts()) {
        if (artifact.getArtifactId().equals(artifactId)) {
            try {
                final URL url = artifact.getFile().toURI().toURL();
                final ClassRealm realm = descriptor.getClassRealm();
                realm.addURL(url);
            }
            catch (MalformedURLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}