2011-05-12 151 views
7

Im'在Linux Red Hat上使用sun/oracle JVM 1.6_23在VMWare服務器內運行此代碼。java.lang.NoClassDefFoundError:在匿名內部類

有些時候JVM似乎無法訪問我的匿名內部類。

我的classpath很好,因爲它工作了一段時間。

所有我得到的是這樣的一個錯誤:

java.lang.NoClassDefFoundError : com/mycompany/impl/MyClassImpl$1 at 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

是否'$ MyClassImpl文件1.class'確實存在在類路徑的文件夾(或JAR文件中)中的一個? – 2011-05-12 10:23:37

+0

是的,文件在那裏。正如我所說,代碼工作一段時間,然後停下來工作。 – oneeyejack 2011-05-12 10:28:29

回答

4

最後,我想我們可能會把問題放在手邊。

我們正在jetty上運行此代碼,並且我們使用.war文件的自動部署。 默認情況下,jetty使用java.io.tmpdir來部署.war文件。

我們的問題只發生在linux上,大多在凌晨(第一位上班族使用該應用程序時)。

原因是在晚上清理/ tmp(通過我們的服務器上的LOGROTATE命令)。

經驗法則:永遠不要使用/ tmp很長時間,並且讓jetty在你自己的目錄中部署戰爭。

謝謝大家

+0

我遇到了與Eclipse Terminal插件相同的問題。我切換到Linux終端,並解決了。 – thSoft 2013-07-22 16:40:10

2

聽起來像JVM找不到匿名類的類文件。這將被命名爲'MyClassImpl $ 1.class' - 如果它不在類路徑中,則必須刪除它。如果存在,那麼JVM出現問題。

+0

我猜JVM有問題,但我希望我能學到什麼。 (正如我所說,在另一評論中,文件在那裏。),我知道我處於瘋狂的狀況。 – oneeyejack 2011-05-12 10:31:37

+0

@oneeyejack:文件存在的另一種可能性是由於某種原因,其訪問權限被更改,以致JVM無法再訪問它。 – 2011-05-12 10:39:14

+0

一切都在.war文件中,我認爲如果一切都在運行,那麼這不應該與權限問題有關。 Nick Fortescue談到了GC相關問題的可能性。我試圖找到合適的-XX選項來更好地瞭解發生的事情。 – oneeyejack 2011-05-12 12:04:40

1

這聽起來很奇怪。首先,如果代碼能夠工作一段時間,就像你說的那樣,文件必須在那裏。其次,JVM一旦使用它就很難從內存中卸載一個類。一些JVM可以在緊張的內存環境下或作爲GC的一部分執行它,但作爲一種優化,他們通常會堅持使用它。

我唯一的猜測是你在ClassLoaders改變的情況下使用JVM。如果你使用Netbeans(尤其是),但我認爲也是eclipse,那麼如果你部分重新編譯代碼,那麼類加載器可能不匹配。這是在IDE內運行嗎?

另一種方法是ClassLoader正在改變。如果您重新發布到正在運行的Web服務器或應用程序服務器,那麼舊類將不會有新的實例的匹配類加載器。 ClassLoader可能無法找到舊版本,即使該文件在那裏。你是否重新發布到應用程序/ Web服務器?

最後,我想這可能與序列化。如果該類是可序列化的,並且serialVersionUID不匹配,我想這可能會發生。你在這裏做任何對象序列化嗎?

+0

問題發生在碼頭服務器上,我們不使用任何熱門部署功能。該類不是可序列化的。 JVM是否有類似於PermGenSpace的問題? – oneeyejack 2011-05-12 11:35:45

+0

您使用哪種方法將您的罐子或目錄添加到碼頭類路徑中?它們被添加爲罐子或目錄嗎? http://docs.codehaus.org/display/JETTY/Classloading – 2011-05-12 12:03:09

+0

所有代碼都包含在.war文件中,我們將戰爭路徑設置爲: WebAppContext jettyWebAppContext = new WebAppContext(); \t \t jettyWebAppContext.setWar(war); \t \t jettyWebAppContext.setContextPath(normalizedContext); jettyServer.addHandler(jettyWebAppContext); – oneeyejack 2011-05-12 12:35:12