4

私が試していること

java.util.TreeMapJ2MEアプリケーションで使用しようとしています。TreeMapこれはJ2SEには存在しますが、J2MEには存在しないことを知っているのでTreeMap、J2SE6.0をJ2ME1.2に移植し、MidletJarに含めるように努力しました。これには、コレクションフレームワークの半分の移植が含まれていましたが、今では(理論的には)それで終わり、テストしたいと思っています。

エラー

しかし、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また、それがJava1.2クラスのファイル形式であることを確認しました。

CDLC1.0とMIDP1.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で実行されるようになりました。

4

2 に答える 2

8

で始まるパッケージからクラスをロードできるのは、ブートストラップブートローダーのみjava.です。

これは、クラスを別のパッケージに移動する必要があることを意味します。

詳細については、 ClassLoader.defineClass()のJavaDocを参照してください。

于 2009-08-18T12:36:49.150 に答える
3

どちらの場合も正しいです-CLDC1.0にはNoClassDefFoundErrorが含まれていません(CLDC1.0仕様を参照)。また、独自のjava。*クラスを作成することはできません。上記の回答のリンクを参照してください。

于 2009-08-18T12:40:08.013 に答える