exec-maven-plugin javassist从依赖

时间:2015-11-17 12:35:59

标签: java maven javassist

我的pom.xml文件定义如下:

<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>com.mydomain</groupId>
    <artifactId>maven</artifactId>
    <version>1.5.0-SNAPSHOT</version>
    <relativePath>../../pom.xml</relativePath>
</parent>

<artifactId>entities</artifactId>
<packaging>jar</packaging>

<name>entities</name>
<url>http://maven.apache.org</url>

<dependencies>
    <dependency>
        <groupId>com.mydomain</groupId>
        <artifactId>mydependency</artifactId>
        <version>1.5.0-SNAPSHOT</version>
    </dependency>
</dependencies>

<build> 
    <plugins>
    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>1.4.0</version>
        <executions>
            <execution>
                <id>FirstGenerator</id>
                <goals>
                    <goal>java</goal>
                </goals>
                <phase>process-classes</phase>
                <configuration>
                    <mainClass>com.mydomain.entities.util.FirstGenerator</mainClass>
                    <arguments>
                        <argument>${project.build.outputDirectory}</argument>
                    </arguments>
                </configuration>
            </execution>
            <execution>
                <id>SecondGenerator</id>
                <goals>
                    <goal>java</goal>
                </goals>
                <phase>process-classes</phase>
                <configuration>
                    <includeProjectDependencies>true</includeProjectDependencies>
                    <mainClass>com.mydomain.entities.util.SecondGenerator</mainClass>
                    <arguments>
                        <argument>${project.build.outputDirectory}</argument>
                        <argument>${project.basedir}\..\libraries\mydependency\target\classes</argument>
                    </arguments>
                </configuration>
            </execution>
        </executions>
    </plugin>
</plugins>
</build>

在构建期间,它会调用两个生成器,FirstGenerator和SecondGenerator。

SecondGenerator的main方法使用以下行调用另一个静态方法:

ClassnameEncoder cne = new ClassnameEncoder();

CtClass CLASSNAMEENCODER = CP.get("com.mydomain.mydependency.serialization.encoder.ClassnameEncoder");

当我从TestNG调用此方法时,它可以正常工作。

但是当我尝试maven build(mvn clean install)时,它会抛出以下异常:

javassist.NotFoundException: com.mydomain.mydependency.serialization.encoder.ClassnameEncoder
        at javassist.ClassPool.get(ClassPool.java:450)

因此,类加载器设法从依赖的不同项目加载ClassnameEncoder类,并创建它的实例,但在下一行中,javassist无法找到相同的类。

我尝试向插件添加依赖项,更改目标,调整类路径,但我无法解决此问题。有谁知道我做错了什么?

1 个答案:

答案 0 :(得分:0)

似乎 Javassist 在其默认 ClassPool 中仅加载使用 -cp 或通过 CLASSPATH 环境变量给出的类路径。通过查看 exec-maven-plugin 源代码,情况并非如此 (https://github.com/mojohaus/exec-maven-plugin/blob/master/src/main/java/org/codehaus/mojo/exec/ExecJavaMojo.java)。 主类在同一个 JVM 中执行:

try {
  Class<?> bootClass = Thread.currentThread().getContextClassLoader().loadClass( bootClassName );
                    
  MethodHandles.Lookup lookup = MethodHandles.lookup();

  MethodHandle mainHandle = lookup.findStatic(bootClass, "main", MethodType.methodType( void.class, String[].class ) );
                    
  mainHandle.invoke( arguments );
 } catch (...) { ...}

解决方案是使用当前类加载器中的类扩展 ClassPool:

ClassPool classPool = ClassPool.getDefault();    
classPool.appendClassPath(new LoaderClassPath(this.getClass().getClassLoader()));