18

リフレクションを使用する必要がある Maven プラグインを作成しようとしています。プロジェクトでプラグインを実行し、プロジェクト内のクラスの完全な名前を付けると、プラグインはリフレクションによってそれをロードして、そこから情報を取得します。

ただし、使用時にクラスが見つからないため、クラスローダーには奇妙なことがあります

Class.forName("package.MyClass");

Guide to Maven Classloadingを見ると、プラグインのクラスローダーが別のプロジェクトで実行されているときに、そのプロジェクトのクラスにアクセスできるかどうかがわかりません。

4

5 に答える 5

19

もっと良い方法があると思いますが、私がそれを機能させる方法は次のとおりです。

mojo の先頭にある javadoc に以下を追加します。

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");
于 2009-05-19T14:44:31.617 に答える
13

これを使用して、ランタイムクラスパス要素を現在のクラスレルムに追加することを検討する必要があります。(を使用しPluginDescriptorて、クラスレルムを取得できます。

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

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

これは私にとって完璧に機能しました!

デイブが尋ねたように、これが:を取得する方法ですPluginDescriptor

/**
 * The plugin descriptor
 * 
 * @parameter default-value="${descriptor}"
 */
private PluginDescriptor descriptor;
于 2011-02-07T13:02:25.433 に答える
4

今日、まさにこの問題に出くわしました。上記の提案は私にはうまくいきませんでした。私の解決策をリストに提出すると思っていました。http://grepcode.com/file/repo1.maven.org/maven2/org.codehaus.mojo/hibernate3-maven-plugin/2.2/org/codehaus/mojo/で表示できる HibernateExporter mojo ソースを使用しました。hibernate3/HibernateExporterMojo.java?av=f

/**
 * @parameter expression="${project}"
 * @required
 * @readonly
 */
private MavenProject project;

private ClassLoader getClassLoader() throws MojoExecutionException
{
  try
  {
    List<String> classpathElements = project.getCompileClasspathElements();
    classpathElements.add(project.getBuild().getOutputDirectory() );
    classpathElements.add(project.getBuild().getTestOutputDirectory() );
    URL urls[] = new URL[classpathElements.size()];

    for ( int i = 0; i < classpathElements.size(); ++i )
    {
      urls[i] = new File( (String) classpathElements.get( i ) ).toURI().toURL();
    }
    return new URLClassLoader(urls, getClass().getClassLoader() );
  }
  catch (Exception e)//gotta catch em all
  {
    throw new MojoExecutionException("Couldn't create a classloader.", e);
  }
}

public void execute() throws MojoExecutionException
{
  ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
  Thread.currentThread().setContextClassLoader(getClassLoader());

   //... your code here ...
}

また、正しい 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>
于 2012-11-04T15:37:18.833 に答える
0

大丈夫です。独自のクラスローダを作成する必要があります カスタムクラスローダ

于 2021-04-16T06:53:54.570 に答える