java.lang.NoClassDefFoundError: в анонимном внутреннем классе - PullRequest
7 голосов
/ 12 мая 2011

Я запускаю этот код в Linux Red Hat с JVM sun / oracle 1.6_23 внутри сервера VMWare.

Через некоторое время 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());
            }
        });

Есть идеи?

Ответы [ 3 ]

4 голосов
/ 14 июня 2012

Наконец, я думаю, что мы могли бы указать на проблему.

Мы выполняем этот код на пристани и используем автоматическое развертывание файлов .war.По умолчанию Jetty использует java.io.tmpdir для развертывания файлов .war.

Наша проблема была только в Linux, и в основном рано утром (как только первый офисный работник использовал приложение).

Причиной была очистка / tmp ночью (сделанная командой LOGROTATE на наших серверах).

Практические правила: никогда не используйте / tmp слишком долгое время и заставьте развертывание JettyВойна в вашем собственном каталоге.

Спасибо всем

2 голосов
/ 12 мая 2011

Похоже, что JVM не может найти файл класса для анонимного класса. Это будет называться «MyClassImpl $ 1.class» - если его нет в пути к классам, что-то должно быть удалено. Если он присутствует, значит, что-то не так с JVM.

1 голос
/ 12 мая 2011

Это звучит очень странно. Во-первых, если код работает какое-то время, как вы говорите, файл должен быть там. Во-вторых, JVM редко выгружает класс из памяти после его использования. Некоторые JVM будут делать это в ситуациях с нехваткой памяти или в составе GC, но в качестве оптимизации они обычно останавливаются.

Мое единственное предположение - вы используете JVM в ситуации, когда меняются ClassLoaders. Если вы используете Netbeans (особенно), но я думаю, что также затмение, то, если вы частично перекомпилируете код, загрузчики классов могут не совпадать. Это работает в IDE?

Альтернативой является изменение ClassLoader. Если вы повторно выпустите на работающий веб-сервер или сервер приложений, то у старого класса не будет соответствующего загрузчика классов для нового экземпляра. ClassLoader может не найти старую версию, даже если файл там есть. Вы повторно выпускаете приложение / веб-сервер?

Наконец, я полагаю, что это возможно с сериализацией. Если класс Serializable, и serialVersionUID не совпадают, я думаю, это может произойти. Вы делаете здесь какую-либо сериализацию объектов?

...