使用Maven编译插件与Eclipse编译器和Lombok一起使用

5
有没有一种方法可以在ECJ中编译Lombok代码,而不需要为Maven进程设置Lombok作为Java Agent
如果我不使用Lombok作为代理运行mvn,下面的片段将无法工作。
<profile>
    <id>ecj</id>
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <compilerId>eclipse</compilerId>
                    </configuration>
                    <dependencies>
                        <dependency>
                            <groupId>org.codehaus.plexus</groupId>
                            <artifactId>plexus-compiler-eclipse</artifactId>
                            <version>2.8-SNAPSHOT</version>
                        </dependency>
                        <dependency>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>1.16.8</version>
                        </dependency>
                    </dependencies>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</profile>

MAVEN_OPTS=-javaagent:lombok.jar mvn -P ecj 的执行结果是编译成功。

然而,仅运行 mvn -P ecj 会出现通常的无 lombok 错误,如:__ 无法解析为一种类型

我尝试使用 com.reubenpeeris.maven:lombok-eclipse-compiler:1.3 ,但它失败了,并显示 编译失败 未识别选项:target/generated-sources/annotations,我想这意味着该编译器太旧了。

我还尝试添加

<fork>true</fork>
<compilerArgs>
    <arg>-javaagent:lombok.jar</arg>
</compilerArgs>

但是它似乎没有任何效果。
2个回答

1
简而言之,没有办法。但是有解决方法。
Eclipse实现是“plexus-compiler-eclipse”,它不接受“fork”参数,因为它使用内部jvm。因此,它只能接受像“MAVEN_OPTS”这样的jvm选项。
然而,默认实现是“plexus-compiler-javac”,支持自定义“executable”。解决方法可能是将“fork”设置为“true”,并指定“executable”。可能像这样:
#!/bin/bash
exec java -javaagent:/path/to/lombok.jar -jar /path/to/ecj.jar $@

或者,直接使用项目中的ecj,在pom.xml中定义-AJAVAC:(-AXXX=XXX可被javac接受)
#!/bin/bash

# save as maven-compiler-javac
for last; do
  :
done

if [ ${last:0:1} == "@" ]; then
  file=${last:1}
  if [ -f "$file" ]; then
    # tail -1 $file
    while read line; do
      last="$line"
    done < "$file"
  fi
  # "xxx" -> xxx
  length=${#last}
  length=$((length - 2))
  last=${last:1:$length}
fi

if [ ${last:0:8} == "-AJAVAC=" ]; then
  exec java ${last:8} $@
else
  exec javac $@
fi

改变pom.xml文件:
<!-- to use ${org.projectlombok:lombok:jar} and so -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.10</version>
    <executions>
        <execution>
            <id>set-properties</id>
            <goals>
                <goal>properties</goal>
            </goals>
        </execution>
    </executions>
</plugin>

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.5.1</version>
    <configuration>
        <fork>true</fork>
        <executable>${basedir}/maven-compiler-javac</executable>
        <!-- plexus-compiler-eclipse use org.codehaus.plexus:plexus-compiler-eclipse, i prefer org.eclipse.jdt.core.compiler:ecj -->
        <!-- if you're developing lombok extension, you should add -Xbootclasspath/a: -->
        <compilerArgument>-AJAVAC=-javaagent:${org.projectlombok:lombok:jar}=ECJ -jar ${org.eclipse.jdt.core.compiler:ecj:jar}</compilerArgument>
    </configuration>
</plugin>

maven-compiler-javac 可执行文件应该是上述 bash 脚本之一吗? - Jakub Bochenski
@JakubBochenski 是的,你可以使用第二个 shell 脚本。但是,如果你正在开发 Lombok 扩展,你可以使用一个更复杂的脚本,它会自动从 classpath 添加 bootclasspath。你可以访问 https://github.com/liudongmiao/lombok-mybatis-param 了解更多详情。 - liudongmiao

0

这是我能够做到的最好的不使用为整个Maven进程设置javaagent:

   <profile>
        <id>ecj</id>
        <build>
            <plugins>
                <plugin>
                    <artifactId>maven-dependency-plugin</artifactId>
                    <executions>
                        <execution>
                            <id>copy-compiler</id>
                            <goals>
                                <goal>copy</goal>
                            </goals>
                            <phase>compile</phase>
                            <configuration>
                                <artifactItems>
                                    <artifactItem>
                                        <artifactId>lombok</artifactId>
                                        <groupId>org.projectlombok</groupId>
                                        <version>${lombok.version}</version>
                                    </artifactItem>
                                    <artifactItem>
                                        <groupId>org.eclipse.jdt.core.compiler</groupId>
                                        <artifactId>ecj</artifactId>
                                        <version>4.5.1</version>
                                    </artifactItem>
                                </artifactItems>
                                <stripVersion>true</stripVersion>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>exec-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <id>ecj-compile</id>
                            <goals>
                                <goal>exec</goal>
                            </goals>
                            <phase>compile</phase>
                            <configuration>
                                <executable>java</executable>
                                <classpathScope>compile</classpathScope>
                                <arguments>
                                    <argument>-javaagent:target/dependency/lombok.jar</argument>
                                    <argument>-jar</argument>
                                    <argument>target/dependency/ecj.jar</argument>
                                    <argument>-d</argument>
                                    <argument>none</argument>
                                    <argument>-properties</argument>
                                    <argument>.settings/org.eclipse.jdt.core.prefs</argument>
                                    <argument>-cp</argument>
                                    <classpath />
                                    <argument>${project.build.sourceDirectory}</argument>
                                </arguments>
                            </configuration>
                        </execution>
                        <execution>
                            <id>ecj-test-compile</id>
                            <goals>
                                <goal>exec</goal>
                            </goals>
                            <phase>test-compile</phase>
                            <configuration>
                                <executable>java</executable>
                                <classpathScope>test</classpathScope>
                                <arguments>
                                    <argument>-javaagent:target/dependency/lombok.jar</argument>
                                    <argument>-jar</argument>
                                    <argument>target/dependency/ecj.jar</argument>
                                    <argument>-d</argument>
                                    <argument>none</argument>
                                    <argument>-properties</argument>
                                    <argument>.settings/org.eclipse.jdt.core.prefs</argument>
                                    <argument>-cp</argument>
                                    <classpath />
                                    <argument>${project.build.testSourceDirectory}</argument>
                                </arguments>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接