J2ME 找不到我的 java.util.TreeMap 实现

发布于 2024-08-02 08:33:13 字数 2503 浏览 4 评论 0原文

我正在尝试

在 J2ME 应用程序中使用 java.util.TreeMap 。我知道 TreeMap 存在于 J2SE 上,但不存在于 J2ME 上,因此我做了一些努力将 J2SE 6.0 TreeMap 移植到 J2ME 1.2 并将其包含在我的 Midlet Jar 中。这涉及到移植一半的集合框架,但现在我(理论上)已经完成了,并且想要测试它。

错误

但是当我在 SUN J2ME SDK 3.0 模拟器 (DefaultClclPhone2) 上启动我的应用程序时,我收到此异常:

  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

在真实设备上,我收到 “应用程序中的错误” 但看不到实际的异常,因为我现在没有匹配的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< /code>

只是一个想法:J2ME 类加载器中是否有任何特殊检查可以阻止它从某个类加载 java.util.*java.lang.* 类应用程序罐子?我从来没有听说过,但也许他们做了这样的事情作为安全功能?

结论和解决方案

正如 Joachim Sauer 指出的那样,如果我定义了类,类加载器将不会加载 java.* 中的类。所以我不得不将它们移动到另一个包,实际上是 com.companyname.j2meport.java.util。虽然我自己的代码可以从那里导入这些类,但这对于引用 java.util.TreeMap 的闭源第三方库来说不是一个选项。

我终于设法使用 Retrotranslator 的扩展机制(我的一个工具)将这些引用更改为我自己的类。已经在我的构建过程中使用,但我并不完全了解其功能。

我的 J2SE 库依赖于其他 J2SE 库,现在可以在 J2ME 上运行!

What I'm trying

I'm trying to use java.util.TreeMap in a J2ME application. I know that TreeMap is present on J2SE but not on J2ME, so I've made some efforts to port the J2SE 6.0 TreeMap to J2ME 1.2 and included it in my Midlet Jar. This involved porting half of the collections framework, but now I'm (theoretically) done with that and want to test it.

The error

But when I start my app on a SUN J2ME SDK 3.0 emulator (DefauldClclPhone2) I get this exception:

  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

On a real device I get "Error in Application" but can't see the actual Exception because I don't have the matching SDK right now.

What's so stange about that error

I'm puzzled by the fact that my application successfully underwent the preverification process. I always experienced that a missing class (and I had many of them some days ago) triggers an error in the preverifier. So I concluded that after successfull preverification there cannot be any NoClassDefFoundError on the device.

Details

The directory structure inside my jar looks like this:

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)

I also made sure that TreeMap.class is in the Java 1.2 class file format.

I'm targeting CDLC 1.0 and MIDP 1.0, so my preverifier is using the classpath ${wtk.home}/lib/cldc_1.0.jar, ${wtk.home}/lib/midp_1.0.jar

Just a thought: Is there any special check in the J2ME classloader that prevents it from loading a java.util.* or java.lang.* class from an application jar? I never heard of that, but maybe they did something like this as a security feature?

Conclusion and Solution

As Joachim Sauer pointed out, the classloader will not load classes in java.* if I defined them. So I had to move them to another package, actually to com.companyname.j2meport.java.util. While my own code could then import those classes from there, this is not an option for closed-source third-party-libs which refer to java.util.TreeMap.

I finally managed to change these references to my own classes using the extension mechanism of Retrotranslator, a tool I was already using in my build process but of whose capabilities I was not fully aware.

My J2SE library, which has dependencies on other J2SE libraries, now runs on J2ME!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夜灵血窟げ 2024-08-09 08:33:13

只有 bootstrap 引导加载程序可以从以 java. 开头的包中加载类。

这意味着您必须将您的类移至另一个包中。

请参阅 ClassLoader.defineClass() 了解详细信息。

Only the bootstrap bootloader can load classes from packages that start with java..

This means that you will have to move your class into another package.

See the JavaDoc of ClassLoader.defineClass() for details.

青瓷清茶倾城歌 2024-08-09 08:33:13

在这两种情况下,您都是对的 - CLDC1.0 不包括 NoClassDefFoundError (请参阅 CLDC1 .0 规范),并且不可以创建自己的 java.* 类;请参阅上面答案中的链接。

You are right in both cases -- CLDC1.0 does not include NoClassDefFoundError (see the CLDC1.0 spec), and no you may not create your own java.* classes; see the link in the above answer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文