Use Maven Compiler Plugin with Eclipse Compiler an

2019-05-11 00:41发布

Is there a way to compile lomboked code in ECJ without setting lombok as javaaagent for the maven process?

The snippet below only works if I run mvn with lombok as agent

<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 results in successfull compilation.

However running just mvn -P ecj spews the usual no-lombok errors like: __ cannot be resolved to a type

I tried using com.reubenpeeris.maven:lombok-eclipse-compiler:1.3 but this fails with Compilation failure Unrecognized option: target/generated-sources/annotations, which I think means this compiler is too old.

I also tried adding

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

but it doesn't seem to have any effect.

2条回答
成全新的幸福
2楼-- · 2019-05-11 00:58

In short, there is no way. However, there is wrokaround.

The eclipse implementation is plexus-compiler-eclipse, it doesn't accept fork argument, as it uses the internal jvm. So, it can only accept jvm options like MAVEN_OPTS.

However, the default implementation is "plexus-compiler-javac", which supports custom executable. The workaround may like this: set fork to true, and specify the executable. It maybe like this:

#!/bin/bash
exec java -javaagent:/path/to/lombok.jar -jar /path/to/ecj.jar $@

or, use the ecj from the project directly, define -AJAVAC in the pom.xml: (-AXXX=XXX is acceptable by 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

change the 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>
查看更多
我只想做你的唯一
3楼-- · 2019-05-11 01:02

Here is the best I was able to do without setting the javaagent for whole maven process:

   <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>
查看更多
登录 后发表回答