5

より大きなプロジェクトの一部であるクライアントを強化しています。速度が不足しているため、CNI に切り替えることを余儀なくされたため、GNU-gcj コンパイラ (gnu 4.6.3) でネイティブ コードを生成する必要がありました。

コンパイルとリンクは正常に機能し (-findirect-dispatch フラグのおかげで)、出力の実行に問題はありません。しかし、クライアントとサーバー間の通信になると、クライアントはすぐに切断されます。理由:

[XStreamClient Reader] 警告 - クライアントが切断されました (例外: com.thoughtworks.xstream.io.StreamException: XmlPullParser を作成できません)

(この Exeption は、クライアントの gcj コンパイル バージョンでのみ表示されます。コードを Java インタープリターで実行すると、うまく動作します (ただし、遅すぎます^^)) --> 難しい部分は、ソースを取得できないことです。この例外は、クライアントが使用するコンパイル済み (Java クラス ファイル) ライブラリ内にあるため、この例外が発生する場所のコード。(そして、そのライブラリの作成者に連絡できません)

ライブラリが XppReader を呼び出し、XmlPullParserクラスを作成しようとして失敗したと思います。

XStream (バージョン 1.4.3) ライブラリ (およびその他の必要な *.jar) をアンパックし、作成された *.class ファイルをコンパイルしてからオブジェクト ファイルをリンクすることでバインドします。これは、他のすべてのライブラリでも機能するようです。(私のOS=Ubuntu)

この問題を克服するために私がすでに行ったこと: XStream/XmlPullParser と gcj を集中的に検索し、「xmlpull」ファイルと「kxml2」ファイルを別のバージョンに置き換えました。しかし、何も機能しませんでした。あなたの誰かが解決策の手がかりを持っていますか?

編集:

XmlPullParser の作成が失敗する理由は、 /services/org.xmlpull.v1.XmlPullParserFactory ファイルを含む META-INF ディレクトリが XmlPullParserFactory.newInstance 関数で見つからないためであることがわかりました。これは、*.jar の *.class ファイルのみをコンパイルおよびリンクしたためです。そのため、META-INF ディレクトリを実行可能ファイルにリンクして、関数が見つけてアクセスできる方法を見つけたらすぐに、問題を解決する必要があります。あなたの誰かがそうする方法をすでに知っていますか?

4

3 に答える 3

3

xmlpull には、xpp3 を実装として使用できる実装が必要だと思います。次のコードを pom.xml に追加し、必要に応じて、これらの jar ファイルを必要とするソフトウェアに追加してください。

<dependency>
    <groupId>xmlpull</groupId>
    <artifactId>xmlpull</artifactId>
    <version>1.1.3.1</version>
</dependency>
<dependency>
    <groupId>xpp3</groupId>
    <artifactId>xpp3</artifactId>
    <version>1.1.3.3</version>
</dependency>
于 2013-12-22T23:39:11.653 に答える
0

実装プラットフォームの選択でいくつかの間違いを犯したと思います。

  • おそらく、「速度のために」ネイティブコードで実装する必要はなかったでしょう。ほとんどの場合、特に時間をかけて Java コードのプロファイリングと最適化を行う場合は、ネイティブ コードとほぼ同等の速度を Jana で得ることができます。

  • あなたがそうしたと仮定すると、CNI は適切な選択ではありませんでした。Oracle HotSpot / OpenJDK リリースを使用できる JNI または JNA を使用したほうがよいでしょう。

  • GCJ は適切な選択ではありません。これは、(ご覧のとおり) 機能しないものもあり、デバッグがより困難なためです。(「 GNU の Java コンパイラ (GCJ) は死んでいますか?」も参照してください。 )

  • ソースコードを入手できないライブラリに依存するのは残念です。

私のアドバイスは、これらの「過ち」をできるだけ多く再検討することです。

于 2012-10-21T14:13:02.367 に答える
0

すでに質問に編集しているように、作成が失敗する理由は、次のコード行を使用して XmlPullParserFactory.newInstance メソッドが /META-INF/services/org.xmlpull.v1.XmlPullParserFactory ファイルにアクセスできないためです。

InputStream is = context.getResourceAsStream (RESOURCE_NAME);

(RESOURCE_NAME は "/META-INF/services/org.xmlpull.v1.XmlPullParserFactory" に等しい)

必要な META-INF ディレクトリを実行可能ファイルにバインドする方法が見つからなかったことを認めなければなりません。これは、最も洗練されたソリューションの 1 つでした。しかし、XmlPullParserFactory.javaファイル (および XStream ライブラリ) はオープン ソースであるため、上記のソース ファイルに 1 行のコードを追加し、古いクラスを新しいクラスに置き換えるだけで済みます。

関数ではpublic static XmlPullParserFactory newInstance (String classNames, Class context)、プログラムは RESOURCE_NAME ファイルからの読み取りのみを必要としますclassNames == null。したがって、これを回避するために行うことは、RESOURCE_NAME のファイル コンテンツを自分で classNames 変数に割り当て、そのために次のコード行を if (classNames == null || classNames.length() == 0 || "DEFAULT".equals(classNames)) ステートメントの上に配置することです。

classNames = "org.xmlpull.mxp1.MXParser,org.xmlpull.mxp1_serializer.MXSerializer";

「org.xmlpull.mxp1.MXParser,org.xmlpull.mxp1_serializer.MXSerializer」は私の RESOURCE_NAME ファイルの内容です。あなたのファイルの内容が私のものと異なる場合 -> 代わりにあなたのものを入れてください。

よろしく、クリス

于 2012-10-24T14:34:46.583 に答える