Будет предоставлен образец Java-программы, и я призываю вас скомпилировать и запустить этот пример с вашей рабочей станции, чтобы правильно воспроизвести и понять этот тип проблемы NoClassDefFoundError.
Пересмотрен статический инициализатор Java
Язык программирования Java предоставляет вам возможность «статически» инициализировать переменные или блок кода. Это достигается с помощью «статического» идентификатора переменной или использования статического блока {} в заголовке класса Java. Статические инициализаторы гарантированно выполняются только один раз в жизненном цикле JVM и являются поточно-ориентированными по своей конструкции, что делает их использование весьма привлекательным для инициализации статических данных, таких как внутренние кэши объектов, средства ведения журнала и т. Д.
В чем проблема? Я повторю еще раз, статические инициализаторы гарантированно будут выполняться только один раз в жизненном цикле JVM… Это означает, что такой код выполняется во время загрузки класса и никогда не будет выполняться снова, пока вы не перезапустите JVM. Что произойдет, если код, выполненный в это время (время загрузки @Class), завершится необработанным исключением?
Добро пожаловать в проблемный случай java.lang.NoClassDefFoundError # 2!
Проблема NoClassDefFoundError, вариант 2 — статическая ошибка инициализатора
Проблема такого типа возникает после сбоя статического кода инициализатора в сочетании с последовательными попытками создания нового экземпляра затронутого (незагруженного) класса.
Пример Java-программы
Следующая простая Java-программа разделена, как показано ниже:
  — Основная Java-программа NoClassDefFoundErrorSimulator 
  — Уязвимый класс Java ClassA 
  — ClassA предоставляет вам переключатель ON / OFF, позволяющий вам воспроизвести тип проблемы, которую вы хотите изучить 
Эта программа просто пытается создать новый экземпляр ClassA 3 раза (один за другим). Он продемонстрирует, что первоначальный сбой статической переменной или инициализатора статического блока в сочетании с последовательной попыткой создания нового экземпляра затронутого класса вызывает триггеры java.lang.NoClassDefFoundError.
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
 | 
#### NoClassDefFoundErrorSimulator.javapackage org.ph.javaee.tools.jdk7.training2;/** * NoClassDefFoundErrorSimulator * @author Pierre-Hugues Charbonneau * */public class NoClassDefFoundErrorSimulator {                /**         * @param args         */        public static void main(String[] args) {               System.out.println("java.lang.NoClassDefFoundError Simulator - Training 2");               System.out.println("Author: Pierre-Hugues Charbonneau");                                             try {                                        // Create a new instance of ClassA (attempt #1)                       System.out.println("FIRST attempt to create a new instance of ClassA...\n");                               ClassA classA = new ClassA();                                      } catch (Throwable any) {                       any.printStackTrace();               }                                           try {                                        // Create a new instance of ClassA (attempt #2)                       System.out.println("\nSECOND attempt to create a new instance of ClassA...\n");                               ClassA classA = new ClassA();                                      } catch (Throwable any) {                                          any.printStackTrace();               }                                    try {                                        // Create a new instance of ClassA (attempt #3)                       System.out.println("\nTHIRD attempt to create a new instance of ClassA...\n");                               ClassA classA = new ClassA();                                      } catch (Throwable any) {                                          any.printStackTrace();               }                                           System.out.println("\n\ndone!");        }} | 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
 | 
#### ClassA.javapackage org.ph.javaee.tools.jdk7.training2;/** * ClassA * @author Pierre-Hugues Charbonneau * */public class ClassA {                private final static String CLAZZ = ClassA.class.getName();        // Problem replication switch ON/OFF        private final static boolean REPLICATE_PROBLEM1 = true; // static variable initializer        private final static boolean REPLICATE_PROBLEM2 = false; // static block{} initializer                // Static variable executed at Class loading time        private static String staticVariable = initStaticVariable();                // Static initializer block executed at Class loading time        static {                              // Static block code execution...               if (REPLICATE_PROBLEM2) throw new IllegalStateException("ClassA.static{}: Internal Error!");        }                public ClassA() {               System.out.println("Creating a new instance of "+ClassA.class.getName()+"...");        }                /**         *         * @return         */        private static String initStaticVariable() {                              String stringData = "";                              if (REPLICATE_PROBLEM1) throw new IllegalStateException("ClassA.initStaticVariable(): Internal Error!");                              return stringData;        }} | 
Проблема воспроизведения
Чтобы повторить проблему, мы просто «добровольно» вызовем сбой статического кода инициализатора. Пожалуйста, просто включите тип проблемы, которую вы хотите изучить, например, ошибка статической переменной или статического блока:
| 
 1 
2 
3 
 | 
// Problem replication switch ON (true) / OFF (false)      private final static boolean REPLICATE_PROBLEM1 = true; // static variable initializer      private final static boolean REPLICATE_PROBLEM2 = false; // static block{} initializer | 
  Теперь давайте запустим программу с обоими переключателями в положении OFF (оба логических значения в false) 
  ## Базовая линия (нормальное исполнение) 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
 | 
             java.lang.NoClassDefFoundError Simulator - Training 2                                                     Author: Pierre-Hugues Charbonneau                                                     http://javaeesupportpatterns.blogspot.com                                                   FIRST attempt to create a new instance of ClassA...                                                    Creating a new instance of org.ph.javaee.tools.jdk7.training2.ClassA...                                        SECOND attempt to create a new instance of ClassA...                                        Creating a new instance of org.ph.javaee.tools.jdk7.training2.ClassA...                                        THIRD attempt to create a new instance of ClassA...                                        Creating a new instance of org.ph.javaee.tools.jdk7.training2.ClassA...                                        done! | 
Для начального запуска (базовый уровень) основная программа смогла успешно создать 3 экземпляра ClassA без проблем.
## Запуск воспроизведения проблемы (ошибка инициализатора статической переменной)
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
 | 
java.lang.NoClassDefFoundError Simulator - Training 2                                                     Author: Pierre-Hugues Charbonneau                                                     http://javaeesupportpatterns.blogspot.com                                        FIRST attempt to create a new instance of ClassA...                                        java.lang.ExceptionInInitializerError                                                             at org.ph.javaee.tools.jdk7.training2.NoClassDefFoundErrorSimulator.main(             NoClassDefFoundErrorSimulator.java:21             )                                                     Caused by:              java.lang.IllegalStateException             : ClassA.initStaticVariable(): Internal Error!                                                             at org.ph.javaee.tools.jdk7.training2.ClassA.initStaticVariable(             ClassA.java:37             )                                                             at org.ph.javaee.tools.jdk7.training2.ClassA.<clinit>(            ClassA.java:16             )                                                             ... 1 more                                        SECOND attempt to create a new instance of ClassA...                                        java.lang.NoClassDefFoundError: Could not initialize class org.ph.javaee.tools.jdk7.training2.ClassA                                                             at org.ph.javaee.tools.jdk7.training2.NoClassDefFoundErrorSimulator.main(           NoClassDefFoundErrorSimulator.java:30             )                                        THIRD attempt to create a new instance of ClassA...                                        java.lang.NoClassDefFoundError: Could not initialize class org.ph.javaee.tools.jdk7.training2.ClassA                                                             at org.ph.javaee.tools.jdk7.training2.NoClassDefFoundErrorSimulator.main(           NoClassDefFoundErrorSimulator.java:39>             )                                        done! | 
## Запуск воспроизведения проблемы (ошибка инициализатора статического блока)
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
 | 
java.lang.NoClassDefFoundError Simulator - Training 2                                                     Author: Pierre-Hugues Charbonneau                                                     http://javaeesupportpatterns.blogspot.com                                                      FIRST attempt to create a new instance of ClassA...                                        java.lang.ExceptionInInitializerError                                                            at org.ph.javaee.tools.jdk7.training2.NoClassDefFoundErrorSimulator.main(             NoClassDefFoundErrorSimulator.java:21             )                                                     Caused by:              java.lang.IllegalStateException>             : ClassA.static{}: Internal Error!                                                            at org.ph.javaee.tools.jdk7.training2.ClassA.<clinit>(             ClassA.java:22             )                                                            ... 1 more                                        SECOND attempt to create a new instance of ClassA...                                        java.lang.NoClassDefFoundError: Could not initialize class org.ph.javaee.tools.jdk7.training2.ClassA                                                            at org.ph.javaee.tools.jdk7.training2.NoClassDefFoundErrorSimulator.main(             NoClassDefFoundErrorSimulator.java:30             )                                        THIRD attempt to create a new instance of ClassA...                                        java.lang.NoClassDefFoundError: Could not initialize class org.ph.javaee.tools.jdk7.training2.ClassA                                                            at org.ph.javaee.tools.jdk7.training2.NoClassDefFoundErrorSimulator.main(             NoClassDefFoundErrorSimulator.java:39             )                                        done! | 
Что произошло? Как вы можете видеть, первая попытка создать новый экземпляр ClassA инициировала java.lang.ExceptionInInitializerError. Это исключение указывает на сбой нашего статического инициализатора для нашей статической переменной & блока, что именно то, что мы хотели достичь.
Ключевой момент, который необходимо понять, заключается в том, что этот сбой предотвратил загрузку всего класса ClassA. Как вы можете видеть, попытка № 2 и попытка № 3 сгенерировали java.lang.NoClassDefFoundError, почему? Ну, так как первая попытка не удалась, загрузка класса ClassA была предотвращена. Последовательные попытки создать новый экземпляр ClassA в текущем ClassLoader действительно генерировали java.lang.NoClassDefFoundError снова и снова, поскольку ClassA не был найден в текущем ClassLoader.
Как вы можете видеть, в этом контексте проблемы NoClassDefFoundError — это просто симптом или следствие другой проблемы. Первоначальная проблема — это ExceptionInInitializerError, срабатывающая после сбоя статического кода инициализатора. Это ясно демонстрирует важность правильной обработки ошибок и ведения журнала при использовании статических инициализаторов Java.
Рекомендации и стратегии решения
  Теперь найдите ниже мои рекомендации и стратегии решения для проблемы 2 проблемы NoClassDefFoundError: 
  — Просмотрите ошибку java.lang.NoClassDefFoundError и определите отсутствующий класс Java. 
  — Выполните пошаговое выполнение кода для затронутого класса и определите, содержит ли он статический код инициализатора (переменные и статический блок) 
  — Просмотрите журналы сервера и приложения и определите, возникла ли какая-либо ошибка (например, ExceptionInInitializerError) из кода статического инициализатора. — После подтверждения проанализируйте код еще раз и определите основную причину сбоя кода инициализатора.  Возможно, вам придется добавить некоторые дополнительные журналы вместе с надлежащей обработкой ошибок, чтобы предотвратить и лучше обрабатывать будущие сбои вашего кода статического инициализатора в будущем. 
Пожалуйста, не стесняйтесь оставлять любые вопросы или комментарии.
Часть 4 начнет рассмотрение проблем NoClassDefFoundError, связанных с проблемами загрузчика классов.
Ссылка: java.lang.NoClassDefFoundError: Как решить — часть 3 от нашего партнера по JCG Пьера-Хьюга Шарбонно из блога по шаблонам поддержки Java EE и учебному пособию по Java .