3

問題なく、play フレームワーク 2.1.3 で protobufs を使用しています。次に、protobufs を JSON に変換する必要があったため、含めました。

"com.googlecode.protobuf-java-format" % "protobuf-java-format" % "1.2"

Build.scala で。

を使用してprotobufをJSONに変換しようとしています

JsonFormat.printToString(message);

これにより、dev モード (play run で開始) で実行すると、次のエラーが発生します。

play.api.Application$$anon$1: Execution exception[[RuntimeException: java.lang.NoClassDefFoundError: com/google/protobuf/InvalidProtocolBufferException]]
...
Caused by: java.lang.NoClassDefFoundError: com/google/protobuf/InvalidProtocolBufferException
...
Caused by: java.lang.ClassNotFoundException: com.google.protobuf.InvalidProtocolBufferException
at java.net.URLClassLoader$1.run(URLClassLoader.java:202) ~[na:1.6.0_51]
at java.security.AccessController.doPrivileged(Native Method) ~[na:1.6.0_51]
at java.net.URLClassLoader.findClass(URLClassLoader.java:190) ~[na:1.6.0_51]
at java.lang.ClassLoader.loadClass(ClassLoader.java:306) ~[na:1.6.0_51]
at java.lang.ClassLoader.loadClass(ClassLoader.java:247) ~[na:1.6.0_51]
at sbt.PlayCommands$$anonfun$53$$anonfun$55$$anon$2.loadClass(PlayCommands.scala:535) ~[na:na]

プロダクション モードでプレイを開始すると、エラーは発生しません。

app フォルダーに protobuf-java-format のソース コードを配置すると、開発モードで動作させることができました。一時的な解決策としてこれは機能しますが、この問題に対処する正しい方法を知りたいです。

追加情報: 以下の提案に従って、play クラスパス、play 依存関係を確認し、システムを検索しましたが、含まれている jar のコピーは 1 つだけです。

問題なく実行できます:

Exception e = new InvalidProtocolBufferException()

protobuf-java-format ライブラリの静的メソッドを使用しようとすると、NoClassDefFoundError がスローされます。例えば:

XmlFormat.printToString(message)

開発モードでは動作しませんが、本番環境 (再生開始) では動作します。興味深いことに、見つからないと言っているクラスは異なります。

[RuntimeException: java.lang.NoClassDefFoundError: com/google/protobuf/Message]

他の場所では問題なく protobuf ライブラリのメソッドを使用しているため、それらがクラス パスに含まれていることはわかっています。

Google から、同様の問題を抱えている別のインスタンスを 1 つ見つけることができました: https://groups.google.com/forum/#!msg/play-framework/i0RNcu8PZOY/J7cy18xsg3oJ

コードをリファクタリングして機能させる方法を理解できませんでした。

4

1 に答える 1

0

クラスが 1.2 に存在することは確かですか? バージョン 2.3 に存在するようです。

http://grepcode.com/file/repo1.maven.org/maven2/com.google.protobuf/protobuf-java/2.3.0/com/google/protobuf/InvalidProtocolBufferException.java

クラスローダーの問題のように聞こえますが、protobuf-java-format jar が 1 つのクラスローダーにあり、他の jar にアクセスできません。最善の策は、アプリを実行しているときに、この jar と他の protobuf jar が同じディレクトリにあることを確認して、それらが同じクラスローダーにあることを確認することです。

他にできることは、それぞれでクラスを呼び出し、クラスローダーを取得し、クラスローダーの親を取得して、クラスローダーの階層がどのように見えるかを確認することです。

デバッグ時に使用できるもう 1 つの非常に便利なメソッドは、XXXXX.class.getProtectionDomain().getCodeSource().getLocation() です。

XXXXX を、クラスの読み込みに問題がなく、protobuf-java-format の読み込みに問題がある例外クラス、および protobuf-java-format のクラスのような protobuf に存在するクラスに置き換えます。これにより、JVM が 2 つの jar をどこからロードしているかがわかります。

于 2013-09-18T18:38:22.467 に答える