Play framework java.lang.NoClassDefFoundError only in dev mode

若如初见. 提交于 2019-12-10 21:18:08

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!