繁体   English   中英

仅在开发模式下播放框架java.lang.NoClassDefFoundError

[英]Play framework java.lang.NoClassDefFoundError only in dev mode

我正在使用protobufs与play框架2.1.3没有问题。 然后我需要将protobufs转换为JSON,所以我包括了

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

在Build.scala中。

试图将任何protobuf转换为JSON使用

JsonFormat.printToString(message);

在开发模式下运行时会导致以下错误(从播放运行开始)

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]

如果在生产模式下开始播放,我没有任何错误。

如果我把protobuf-java-format的源代码放在我的app文件夹中,我已经能够在开发模式下工作了。 作为临时解决方案,这是有效的,但我想知道处理这个问题的正确方法。

附加信息:根据下面的建议,我检查了播放类路径,播放依赖关系,并搜索了我的系统,我只包含了一个jar的副本。

我可以毫无问题地运行:

Exception e = new InvalidProtocolBufferException()

当我尝试使用protobuf-java-format库中的任何静态方法时,抛出NoClassDefFoundError。 例如:

XmlFormat.printToString(message)

在开发模式下不起作用,但在生产中起作用(播放开始)。 有趣的是,它说它找不到的课程是不同的:

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

我正在使用protobuf库中的方法而没有其他地方的问题,所以我知道它们被包含在类路径中。

从谷歌,我已经能够找到另一个有类似问题的实例: https//groups.google.com/forum/#!msg / play-framework / i0RNcu8PZOY / J7cy18xsg3oJ

我无法弄清楚如何重构代码以使其工作。

你确定该课程存在于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格式的jar在一个无法访问另一个jar的类加载器中。 最好的办法是确保在运行应用程序时,此jar和另一个protobuf jar最终位于同一目录中,因此它们最终位于同一个类加载器中。

你可以做的其他事情是在每个中调用类并获取类加载器,并且让类加载器父类也可以查看类加载器的层次结构。

调试时另一个非常有用的方法是XXXXX.class.getProtectionDomain()。getCodeSource()。getLocation()

将XXXXX替换为protobuf中存在的类,就像您的类没有加载问题的Exception类一样,protobuf-java-format在加载问题时也遇到问题,并且还有来自protobuf-java-format的任何类。 这将告诉您JVM从哪里加载两个罐子。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM