我在Linux Red Hat上使用sun / oracle JVM 1.6_23在VMWare服务器中运行此代码。
有些时候,JVM似乎无法访问我的匿名内部类。
我的类路径很好,因为它可以工作一段时间。
我得到的只是这样的错误:
java.lang.NoClassDefFoundError
:com/mycompany/impl/MyClassImpl$1
在com.mycompany.impl.MyClassImpl.markAsDeletable
(MyClassImpl.java
:45)。
第45行是下面的第一行,它无法找到我的新谓词
DomaineVO domaineVO = Iterables.find(domainesVO, new Predicate<DomaineVO>() {
@Override
public boolean apply(DomaineVO input) {
return input.getId().equals(domaine.getIdentifier().toString());
}
});
有什么想法吗?
答案 0 :(得分:4)
最后,我想我们可能已经指出了这个问题。
我们在jetty上运行此代码,并且我们使用.war文件的自动部署。 默认情况下,jetty使用java.io.tmpdir来部署.war文件。
我们的问题只出现在linux上,大部分时间都在凌晨(第一个上班族使用该应用程序时)。
原因是在晚上清理/ tmp(在我们的服务器上通过LOGROTATE命令进行)。
经验法则:永远不要使用/ tmp太长时间,并让jetty在你自己的目录中部署战争。
谢谢大家
答案 1 :(得分:2)
听起来好像JVM找不到匿名类的类文件。这将被命名为'MyClassImpl $ 1.class' - 如果它不存在于类路径中,则必须删除它。如果它存在则JVM出现问题。
答案 2 :(得分:1)
这听起来很奇怪。首先,如果代码工作了一段时间,正如您所说,文件必须在那里。其次,JVM在使用后很少从内存中卸载它。一些JVM会在紧张的内存情况下或作为GC的一部分来完成它,但作为一种优化,它们通常会坚持下去。
我唯一的猜测是你在ClassLoaders正在改变的情况下使用JVM。如果您正在使用Netbeans(尤其是)但我认为也是eclipse,那么如果您部分重新编译代码,则类加载器可能不匹配。这是在IDE中运行吗?
另一种选择是改变ClassLoader。如果重新发布到正在运行的Web服务器或应用程序服务器,则旧类将没有新实例的匹配类加载器。 ClassLoader可能无法找到旧版本,即使该文件存在。您是否正在重新发布到应用程序/ Web服务器?
最后,我想这可能与序列化有关。如果类是Serializable,并且serialVersionUID不匹配,我想这可能会发生。你在这里进行任何对象序列化吗?