代号一 - Form.initLaf 抛出随机 "Illegal Access" 错误

Codename one - Form.initLaf throws random "Illegal Access" errors

在我的应用程序中,我在看似随机的地点和时间收到 "IllegalAccess" 错误。 唯一的共同点是堆栈跟踪:

java.lang.IllegalAccessError: class sun.reflect.GeneratedConstructorAccessor3 cannot access its superclass sun.reflect.ConstructorAccessorImpl
at sun.misc.Unsafe.defineClass(Native Method)
at sun.reflect.ClassDefiner.defineClass(ClassDefiner.java:63)
at sun.reflect.MethodAccessorGenerator.run(MethodAccessorGenerator.java:399)
at sun.reflect.MethodAccessorGenerator.run(MethodAccessorGenerator.java:394)
at java.security.AccessController.doPrivileged(Native Method)
at sun.reflect.MethodAccessorGenerator.generate(MethodAccessorGenerator.java:393)
at sun.reflect.MethodAccessorGenerator.generateConstructor(MethodAccessorGenerator.java:92)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:55)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
**at com.codename1.ui.Form.initLaf(Form.java:969)**
at com.codename1.ui.Dialog.initLaf(Dialog.java:499)
at com.codename1.ui.Component.<init>(Component.java:687)
at com.codename1.ui.Container.<init>(Container.java:187)
at com.codename1.ui.Container.<init>(Container.java:199)
at com.codename1.ui.Form.<init>(Form.java:181)
at com.codename1.ui.Form.<init>(Form.java:172)
at com.codename1.ui.Dialog.<init>(Dialog.java:288)
at com.codename1.ui.Dialog.<init>(Dialog.java:275)
at com.codename1.ui.Dialog.<init>(Dialog.java:248)
at com.codename1.ui.Dialog.show(Dialog.java:994)
at com.codename1.ui.Dialog.show(Dialog.java:793)
at com.codename1.ui.Dialog.show(Dialog.java:746)
at com.codename1.ui.Dialog.show(Dialog.java:711)
at com.codename1.ui.Dialog.show(Dialog.java:652)
at com.codename1.ui.Dialog.show(Dialog.java:807)
at com.codename1.ui.Display.mainEDTLoop(Display.java:983)
at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)
at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)

标有 ** .. ** 的行是我的注释,因为这是引发错误的 Form class 的方法。 当我打开一个新表单、一个对话框(继承自表单)或任何涉及创建新表单的内容时,都会随机出现此问题。

我不知道如何调试它,因为似乎不是我的代码导致了这个问题。

有任何调试甚至解决问题的技巧吗?

编辑

错误不仅限于创建表单,在内部化对象时也可能发生。查看堆栈跟踪:

<same as above stacktrace after Class.newinstance>
at java.lang.Class.newInstance(Class.java:442)
at com.codename1.io.Util.readObject(Util.java:690)
at com.codename1.io.Util.readObject(Util.java:668)
at com.lequi.ep.dtos.ChatDTO.internalize(ChatDTO.java:47)
at com.codename1.io.Util.readObject(Util.java:693)

编辑 2

通过对这个问题进行更多测试,到目前为止我发现了一个模式。无论我创建哪种窗体或对话框,都取决于我实例化它们的次数。恰好第13次我要实例化一个表单(无论哪个屏幕),弹出这个错误。我不需要做任何事情,只需打开屏幕并返回即可。可以重现错误的相关代码片段:

// main form activity 
<omitted for brevity>
chatButton.addActionListener(e -> {
    new ChatScreen(this).show();
});

public ChatScreen(Form origin) {
    super("Chat", new BorderLayout());
    setUIID("ChatHistory");

    getToolbar().setBackCommand("", e -> {
        origin.showBack();
    });
    <omitted for brevity>
 }

设置第二个开发环境后,一对一导入我的 git 项目,没有任何问题,并且注意到此错误不会发生在移动设备本身上,问题可能仅限于我的具体环境。

我还不知道为什么会这样,但是影响可以忽略不计

这可能是因为您没有在代码中足够早地调用 Util.register()。请注意,您不应在 init(Object) 回调之前执行此操作。

但是,如果您 read/write 调用之前的对象(例如作为静态初始化程序的结果)将产生这样的异常。

其他潜在问题包括 returns getClass().getName() 而不是硬编码字符串的代码。由于混淆,这可能会严重失败。第一步是查看 ChatDTO 的第 47 行。该行读取的对象是什么?为什么?

还有谁调用了 at com.codename1.io.Util.readObject(Util.java:693) 以及什么时候调用的?

对象不读取自身。