Kotlin 没有看到龙目岛访问器?

使用 Kotlin 1.0.0发行版(在 IntelliJ 15中编译)。

println(myPojoInstance.foo)

当它尝试编译引用龙目岛 POJO 的代码(在 IntelliJ 或 Gradle 中)时,会出现错误“ Can not access‘ foo’: it is‘ private’in“ MyPojo”。这是真的,它们都是私有的,我的对象有@Value@Builder 用于 lombok 注释。

我尝试过专门调用 getFoo () ,但它显示“ getFoo 的未解析引用”。也许有一些技巧可以让 Kotlin 知道如何处理 Lombok 注释?

26635 次浏览

Generally, no, it doesn't. The reason of that behavior is that Lombok is an annotation processor for javac but when the kotlin compiler runs it uses javac as well but with no annotation processing so this is why kotlin don't see declarations that wasn't yet generated.

The only workaround for now is to define strict compilation order: Java first and after that kotlin. Unfortunately this approach has great disadvantage: you can't use Kotlin code from Java in this case. To workaround it you may need multimodule project that may cause a lot of pain

As it was mentioned in comments above, delombok helps. In case of maven build it would be:

<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>${lombok.version}.0</version>
<executions>
<execution>
<id>delombok</id>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
<configuration>
<formatPreferences>
<javaLangAsFQN>skip</javaLangAsFQN>
</formatPreferences>
<verbose>true</verbose>
</configuration>
</execution>
<execution>
<id>test-delombok</id>
<phase>generate-test-sources</phase>
<goals>
<goal>testDelombok</goal>
</goals>
<configuration>
<verbose>true</verbose>
</configuration>
</execution>
</executions>
</plugin>

To add to Sergey Mashkov's response (adding here I don't have enough rep points to comment on it), here's an example app of a Gradle multi-project setup where Kotlin can see the Lombok-generated code (without kapt or delomboking. Caveats do apply - namely, Kotlin can call the Java code, but Java can't call the Kotlin code in that particular module (as this would create a circular dependency). This kind of build might be suitable if you have an existing Java codebase and all new code is written in Kotlin, though.

I would love to see full Lombok/Kotlin support, however. While Kotlin is fully interoperable with Java, the reality is that Lombok is very widely used, and this issue may prevent a large number of developers who would like to switch to Kotlin from doing so.

Looks like it works if you use delombok according to site and add the target/generated-sources/delombok folder in the pom.xml under build > plugins > plugin > kotlin-maven-plugin

There is a Kotlin compiler plugin for lombok. It is still experimental and it can be used with Gradle or Maven.

It only supports a hand full of annotations, including

  • @Getter, @Setter
  • @NoArgsConstructor, @RequiredArgsConstructor, and @AllArgsConstructor
  • @Data
  • @With
  • @Value

Seem to work as expected. Unfortunately, they do not support the @Builder annotation but you can request to be added in YouTrack

See the Lombok compiler plugin in the kotlin documentation for more information.

Update 1

The @Builder annotation ticket mentioned above has been fixed! The target version for the fix is 1.8.0-Beta.