问题
I am working with protobufs with the play framework 2.1.3 without issues. I then needed to convert the protobufs to JSON, so I included
"com.googlecode.protobuf-java-format" % "protobuf-java-format" % "1.2"
in Build.scala.
Trying to covert any protobuf to JSON using
JsonFormat.printToString(message);
This leads to the following error when running in dev mode (started with 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]
If play is started in production mode I do not have any errors.
I have been able to get it to work in dev mode if I put the source code for protobuf-java-format in my app folder. As a temporary solution this works, but I would like to know the correct way to deal with this problem.
Additional information: Per suggestion below, I have checked play classpath, play dependencies, and searched my system and I only have one copy of the jar being included.
I can run without problems:
Exception e = new InvalidProtocolBufferException()
NoClassDefFoundError is thrown when I try to use any static method from protobuf-java-format library. For example:
XmlFormat.printToString(message)
Does not work in dev mode but does work in production (play start). Interestingly the class it says it can't find is different:
[RuntimeException: java.lang.NoClassDefFoundError: com/google/protobuf/Message]
I am using the methods from the protobuf library without problems elsewhere, so I know they are being included in the class path.
From google, I have been able to find one other instance that has similar problems: https://groups.google.com/forum/#!msg/play-framework/i0RNcu8PZOY/J7cy18xsg3oJ
I have not been able to figure out how to refactor the code to make it work.
回答1:
Are you sure that class exists in 1.2? I see it exists in version 2.3.
http://grepcode.com/file/repo1.maven.org/maven2/com.google.protobuf/protobuf-java/2.3.0/com/google/protobuf/InvalidProtocolBufferException.java
It is sounding like a classloader issue then where the protobuf-java-format jar is in one classloader that has no access to the other jar. The best bet is to make sure this jar and the other protobuf jar end up in the same directory when you are running the app so they end up in the same classloader.
Other things you can do is call class in each and get the classloader and fool around with getting the classloaders parents as well to see what the classloader heirarchy looks like.
Another very useful method to play around with when debugging is XXXXX.class.getProtectionDomain().getCodeSource().getLocation()
replace XXXXX with a class that exists in protobuf like that Exception class that your class is having no problem loading and protobuf-java-format is having a problem loading and also any class from protobuf-java-format. This will tell you where the JVM is loading the two jars from.
来源:https://stackoverflow.com/questions/18878707/play-framework-java-lang-noclassdeffounderror-only-in-dev-mode