Я пишу приложение Flink на Kotlin, и классы данных (как и другие классы Kotlin) не определены как допустимые типы POJO.
Документация Flink гласит, что тип данных распознается как тип POJO (и допускает ссылку на поле «по имени»), если выполняются следующие условия:
- Класс публичный и автономный
- У класса есть открытый конструктор без аргументов
- Все нестатические, непереходные поля в классе являются либо общедоступными (и не окончательными), либо имеют общедоступные методы получения и установки, которые следуют соглашениям об именах Java-бинов.
Я получаю следующее при реализации класса данных Kotlin, который должен удовлетворять вышеупомянутым условиям, чтобы быть признанным в качестве POJO:
[main] INFO org.apache.flink.api.java.typeutils.TypeExtractor -
Class class <Class> cannot be used as a POJO type because not all
fields are valid POJO fields, and must be processed as GenericType.
Please read the Flink documentation on "Data Types & Serialization"
for details of the effect on performance.
Продолжая исследование, я рассмотрел метод TypeExtractor.isValidPojoField Флинка @ https://github.com/apache/flink/blob/master/flink-core/src/main/java/org/apache/flink/api/java/typeutils/TypeExtractor.java
В отдельном проекте я применил проверки полей с помощью java.lang.reflect.Modifier к простому классу данных Kotlin, чтобы попытаться сузить проблему.
data class SomeDataClass(
val topic: String = "",
val message: String = ""
)
Хотя поля класса Kotlin по умолчанию открыты для общего доступа, Modifier.isPublic распознает поля как закрытые. Кроме того, Modifier.isFinal распознает поля как окончательные.
val clazz = SomeDataClass::class.java
val fields = clazz.declaredFields
fields.forEach { it ->
println("field: $it")
println(it.genericType)
println("public? " + Modifier.isPublic(it.modifiers))
println("final? " + Modifier.isFinal(it.modifiers))
println("transient? " + Modifier.isTransient(it.modifiers))
println("static? " + Modifier.isStatic(it.modifiers))
}
>
field: private final java.lang.String SomeDataClass.topic
class java.lang.String
public? false
final? true
transient? false
static? false
Однако для этих полей создаются общедоступные методы получения и установки, поэтому этот объект все равно должен соответствовать критериям POJO.
println(clazz.declaredMethods.toList())
>
[public boolean SomeDataClass.equals(java.lang.Object),
public java.lang.String SomeDataClass.toString(),
public int SomeDataClass.hashCode(),
**public final java.lang.String SomeDataClass.getMessage(),**
public final SomeDataClass SomeDataClass.copy(java.lang.String,java.lang.String),
**public final java.lang.String SomeDataClass.getTopic(),**
public final java.lang.String SomeDataClass.component1(),
public final java.lang.String SomeDataClass.component2(),
public static SomeDataClass SomeDataClass.copy$default(SomeDataClass,java.lang.String,java.lang.String,int,java.lang.Object)]
Методы получения и установки, однако, являются окончательными, что заставляет меня поверить, что это проблема.
Я относительно новичок в разработке JVM, поэтому любая помощь будет принята с благодарностью. Я просмотрел список рассылки Flink Jira, Stack Overflow и Flink и не обнаружил аналогичных проблем.