我正在尝试什么
我正在尝试java.util.TreeMap
在 J2ME 应用程序中使用。我知道它TreeMap
存在于 J2SE 但不存在于 J2ME 上,因此我已努力将 J2SE 6.0 移植TreeMap
到 J2ME 1.2 并将其包含在我的 Midlet Jar 中。这涉及移植一半的集合框架,但现在我(理论上)已经完成了它并想要测试它。
错误
但是当我在 SUN J2ME SDK 3.0 模拟器 (DefauldClclPhone2) 上启动我的应用程序时,我得到了这个异常:
java.lang.NoClassDefFoundError: java/util/TreeMap
java.lang.Class.invoke_verify(), bci=0
java.lang.Class.initialize(), bci=117
com.companyname.test.TestMidlet.<init>(), bci=19
java.lang.Class.newInstance(), bci=0
com.sun.midp.main.CldcMIDletLoader.newInstance(), bci=46
com.sun.midp.midlet.MIDletStateHandler.createMIDlet(), bci=66
com.sun.midp.midlet.MIDletStateHandler.createAndRegisterMIDlet(), bci=17
com.sun.midp.midlet.MIDletStateHandler.startSuite(), bci=27
com.sun.midp.main.AbstractMIDletSuiteLoader.startSuite(), bci=52
com.sun.midp.main.CldcMIDletSuiteLoader.startSuite(), bci=8
com.sun.midp.main.AbstractMIDletSuiteLoader.runMIDletSuite(), bci=161
com.sun.midp.main.AppIsolateMIDletSuiteLoader.main(), bci=26
在真实设备上,我得到"Error in Application"
但看不到实际的异常,因为我现在没有匹配的 SDK。
这个错误有什么奇怪的
我对我的申请成功通过预验证过程感到困惑。我总是经历过缺失的课程(几天前我有很多)会触发预验证器中的错误。所以我得出结论,在成功预验证后,设备上不能有任何东西NoClassDefFoundError
。
细节
我的 jar 中的目录结构如下所示:
test.jar
com
companyname
(my application classes, including the Midlet class)
java
lang
Comarable.class
Iterable.class
(some others which are missing on J2ME)
util
TreeMap.class
TreeSet.class
(many others which are missing on J2ME)
我还确保它TreeMap.class
是 Java 1.2 类文件格式。
我的目标是 CDLC 1.0 和 MIDP 1.0,所以我的预验证器正在使用类路径${wtk.home}/lib/cldc_1.0.jar, ${wtk.home}/lib/midp_1.0.jar
只是一个想法:在 J2ME 类加载器中是否有任何特殊检查阻止它从应用程序 jar加载一个java.util.*
或类?java.lang.*
我从来没有听说过,但也许他们做了这样的事情作为安全功能?
结论与解决方案
正如 Joachim Sauer 指出的那样,java.*
如果我定义了类,类加载器将不会加载它们。所以我不得不把它们移到另一个包,实际上是com.companyname.j2meport.java.util
. 虽然我自己的代码可以从那里导入这些类,但对于引用 java.util.TreeMap 的闭源第三方库来说,这不是一个选项。
我终于设法使用Retrotranslator 的扩展机制将这些引用更改为我自己的类,这是我已经在构建过程中使用的工具,但我并不完全了解它的功能。
我的 J2SE 库依赖于其他 J2SE 库,现在可以在 J2ME 上运行!