遇到一个项目,在使用Gradle进行编译的时候一段stream代码编译不过去,具体问题与下面文章类似
sorting - Very confused by Java 8 Comparator type inference - Stack Overflow
如果项目无特殊要求,可以通过简单的修改代码进行解决。
但是当前项目这部分属于遗留代码,不允许进行更改,且这部分代码在Eclipse中是不会报错的,要求必须在当前的限制下解决问题。
经过查询原来Eclipse编译时是通过ECJ(the Eclipse Compiler for Java),而Gradle在进行编译打包时使用的是JDK(javac)进行编译,并且两个编译器对某些代码的处理是有差异的,导致了这部分代码在Eclipse可以正常编译通过。
接下来的就是查找是否可以通过Gradle使用ECJ进行编译
根据下面这个文章进行了配置,虽然使用了org.eclipse.jdt:ecj的最新版3.34.0,但是并不能解决问题
Gradle: How to compile Java by eclipse ECJ (JDT core) by running Gradle 4.1 task - Stack Overflow
编译时提示提示"Unrecognized option : -h"
转而求助ChatGPT
可惜不管怎么换prompt,ChatGPT提供的方案基本都比较雷同,大部分的结果都是编译的时候提示"Unrecognized option : -source"。在经过了一番跟compileJava各种参数的折腾后,仍然无法解决问题。偶然间想起之前通过“gradle+ecj”搜到过gradle的插件
其中近期仍在维护的只有io.github.themrmilchmann.ecj
GiHub:https://github.com/TheMrMilchmann/gradle-ecj
改成直接使用ecj插件,终于需要ECJ编译的部分代码可以编译通过了
plugins {
id "io.github.themrmilchmann.ecj" version "0.2.0"
}
接下来遇到的问题是,所有使用lombok的部分都提示找不到相关方法,看来使用ecj插件以后,导致涉及到lombok的部分没有正确编译
而gradle的dependencie中已经配置了对应的lombok依赖
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.28'
annotationProcessor 'org.projectlombok:lombok:1.18.28'
}
又经过了各种尝试,包括改用lombok插件,修改各种版本,甚至觉得是不是JDK版本过新导致的,又进行了JDK的降级,连带降级插件的版本,仍然未解决相关问题。
而ProjectLombok的官网并未提供基于gradle的整合方案,最后甚至感觉是不是这种情况就是没有解决方案。
但是问题最终总要解决,在放弃了一些调查结果后,重新开始在网上查找资料,无意间看到这篇文章
Use Maven Compiler Plugin with Eclipse Compiler and Lombok - Stack Overflow
其中通过java命令支持ecj和lombok整合的编译方式,让我想到了之前调查中一直提示"Unrecognized option : -source"的部分
最终在使用ecj插件的情况下,通过compileJava中增加“jvmArgs”相关参数,终于顺利的通过了编译
完整的build.gradle文件如下
plugins {
id 'java'
id 'war'
id 'org.springframework.boot' version '3.0.0'
id 'io.spring.dependency-management' version '1.1.0'
id 'com.github.node-gradle.node' version '3.5.0'
id "io.github.themrmilchmann.ecj" version "0.2.0"
}
group 'org.example'
version '1.0-SNAPSHOT'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok:1.18.28'
annotationProcessor 'org.projectlombok:lombok:1.18.28'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
wrapper {
gradleVersion = '7.5.1'
}
compileJava {
sourceCompatibility = 17
targetCompatibility = 17
options.compilerArgs << "-parameters"
options.fork = true
options.forkOptions.jvmArgs += '-javaagent:lib/lombok-1.18.28.jar'
}
war {
archiveFileName = 'springboot-gradle-sample.war'
}
lombok-1.18.28.jar文件放在项目根目录/lib中
最终可能仍然有一些参数冗余,不过主要的问题已经解决。