GluonMobile + Jackson = java.lang.NoClassDefFoundError: java.util.function.ToLongFunction

GluonMobile + Jackson = java.lang.NoClassDefFoundError: java.util.function.ToLongFunction

我正在将需要 Jackson 的桌面 JavaFx 应用程序移植到 GluonMobile,这是我第一次使用这个平台,我最终在下一个堆栈跟踪中遇到了 NoClassDefFoundError。

我想知道这是否需要 GluonMobile 不支持的功能,或者我是否只是忘记正确包含某些内容。

Apr 19, 2018 8:25:02 PM com.fasterxml.jackson.databind.ext.Java7Support <clinit>
WARNING: Unable to load JDK7 types (annotations, java.nio.file.Path): no Java7 support added
[WARN] java.lang.Class: Class.forName() failed to load 'javax.servlet.Servlet'. Use the -forcelinkclasses command line option or add <forceLinkClasses><pattern>javax.servlet.Servlet</pattern></forceLinkClasses> to your robovm.xml file to link it in.
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
TRACE Task Catching
 java.lang.NoClassDefFoundError: java.util.function.ToLongFunction
at java.lang.VMClassLoader.findClassInClasspathForLoader(Native Method)
at java.lang.PathClassLoader.findClass(PathClassLoader.java:193)
at java.lang.ClassLoader.loadClass(ClassLoader.java:515)
at java.lang.ClassLoader.loadClass(ClassLoader.java:475)
at com.fasterxml.jackson.datatype.jsr310.ser.InstantSerializer.<init>(InstantSerializer.java:38)
at com.fasterxml.jackson.datatype.jsr310.ser.InstantSerializer.<clinit>(InstantSerializer.java:35)
at com.fasterxml.jackson.datatype.jsr310.JavaTimeModule.<init>(JavaTimeModule.java:161)
at com.general.plugin.jackson.json.JacksonObjectMapper.<clinit>(JacksonObjectMapper.java:214)
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:218)
at java.lang.Class.forName(Class.java:176)
at com.general.core.startup.Configuration.getSharableInstance(Configuration.java:69)
at com.general.core.startup.AbstractClient.<init>(AbstractClient.java:39)
at com.objectdb.core.startup.Client.<init>(Client.java:31)
at com.objectdb.ui.service.ClientFactory.getDBClient(ClientFactory.java:39)
at com.objectdb.ui.service.ClientTask.getDBClient(ClientTask.java:13)
at com.objectdb.ui.startup.Main.call(Main.java:30)
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.lang.Thread.run(Thread.java:837)

此解决方案是一个需要一些工作的解决方法。 修复 Jackson 2.9.5 以在 gluon jfxmobile-plugin 1.3.10 中工作。

  1. 修复 jackson-databind 以便能够使用单个构造函数构建不可变对象。

1.1 放弃使用 JDK8 模块参数名称,因为这需要未实现的 VM 功能。 请改用 java.beans.ConstructorProperties.

1.2 Jackson 用于 ConstructorProperties 支持一些来自 JDK8 的接口,这些接口可以安全地包含在您的项目中。

java.beans.ConstructorProperties
java.beans.Transient

1.3 强制 link JDK7 支持

forceLinkClasses = [
    'com.fasterxml.jackson.databind.ext.Java7SupportImpl',
]
  1. 修复 jackson-datatype-jsr310。

2.1 它使用了一些可以安全包含在您的项目中的 JDK8 接口。

java.util.function.ToIntFunction
java.util.function.ToLongFunction

2.2 它使用了一些可以被 JDK6-7 实现安全替代的 JDK8 方法,只需在您的项目中包含 java 文件并查找 Time [=41= 的 pre-JDK8 back ports ].

JavaTimeModule.java
SerializerToPach.java

3.3 将您自己的 JavaTimeModule 指向您自己的序列化程序。 3.4 在您的 ObjectMapper 中注册您自己的 JavaTimeModule。

瞧,现在你可以使用最新的 Jackson 创建不可变对象并在 gluon jfxmobile-plugin 1.x

中使用 JDK8 Time 类