Core Java

java.lang.NoClassDefFoundError: How to resolve – Part 3

This article is part 3 of our NoClassDefFoundError troubleshooting series. As I mentioned in my first article, there are many possible issues that can lead to a NoClassDefFoundError. This article will focus and describe one of the most common causes of this problem: failure of a Java class static initializer block or variable.

A sample Java program will be provided and I encourage you to compile and run this example from your workstation in order to properly replicate and understand this type of NoClassDefFoundError problem.

Java static initializer revisited

The Java programming language provides you with the capability to “statically” initialize variables or a block of code. This is achieved via the “static” variable identifier or the usage of a static {} block at the header of a Java class. Static initializers are guaranteed to be executed only once in the JVM life cycle and are Thread safe by design which make their usage quite appealing for static data initialization such as internal object caches, loggers etc.

What is the problem? I will repeat again, static initializers are guaranteed to be executed only once in the JVM life cycle…This means that such code is executed at the Class loading time and never executed again until you restart your JVM. Now what happens if the code executed at that time (@Class loading time) terminates with an unhandled Exception?

Welcome to the java.lang.NoClassDefFoundError problem case #2!

NoClassDefFoundError problem case 2 – static initializer failure

This type of problem is occurring following the failure of static initializer code combined with successive attempts to create a new instance of the affected (non-loaded) class.

Sample Java program

The following simple Java program is split as per below:

– The main Java program NoClassDefFoundErrorSimulator
– The affected Java class ClassA
– ClassA provides you with a ON/OFF switch allowing you the replicate the type of problem that you want to study

This program is simply attempting to create a new instance of ClassA 3 times (one after each other) . It will demonstrate that an initial failure of either a static variable or static block initializer combined with successive attempt to create a new instance of the affected class triggers java.lang.NoClassDefFoundError.

#### NoClassDefFoundErrorSimulator.java
package 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");
               System.out.println("http://javaeesupportpatterns.blogspot.com\n\n");              
                             
               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!");
        }
}
#### ClassA.java
package 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;
        }
}

Problem reproduction

In order to replicate the problem, we will simply “voluntary” trigger a failure of the static initializer code . Please simply enable the problem type that you want to study e.g. either static variable or static block initializer failure:

  // 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

Now, let’s run the program with both switch at OFF (both boolean values at false)
## Baseline (normal execution)

             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!     

For the initial run (baseline), the main program was able to create 3 instances of ClassA successfully with no problem.

## Problem reproduction run (static variable initializer failure)

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!

## Problem reproduction run (static block initializer failure)

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!

What happened? As you can see, the first attempt to create a new instance of ClassA did trigger a java.lang.ExceptionInInitializerError . This exception indicates the failure of our static initializer for our static variable & bloc which is exactly what we wanted to achieve.

The key point to understand at this point is that this failure did prevent the whole class loading of ClassA . As you can see, attempt #2 and attempt #3 both generated a java.lang.NoClassDefFoundError, why? Well since the first attempt failed, class loading of ClassA was prevented. Successive attempts to create a new instance of ClassA within the current ClassLoader did generate java.lang.NoClassDefFoundError over and over since ClassA was not found within current ClassLoader.

As you can see, in this problem context, the NoClassDefFoundError is just a symptom or consequence of another problem. The original problem is the ExceptionInInitializerError triggered following the failure of the static initializer code. This clearly demonstrates the importance of proper error handling and logging when using Java static initializers.

Recommendations and resolution strategies

Now find below my recommendations and resolution strategies for NoClassDefFoundError problem case 2:
– Review the java.lang.NoClassDefFoundError error and identify the missing Java class
– Perform a code walkthrough of the affected class and determine if it contains static initializer code (variables & static block)
– Review your server and application logs and determine if any error (e.g. ExceptionInInitializerError) originates from the static initializer code – Once confirmed, analyze the code further and determine the root cause of the initializer code failure. You may need to add some extra logging along with proper error handling to prevent and better handle future failures of your static initializer code going forward

Please feel free to post any question or comment.

The part 4 will start coverage of NoClassDefFoundError problems related to class loader problems.

Reference: java.lang.NoClassDefFoundError: How to resolve – Part 3 from our JCG partner Pierre-Hugues Charbonneau at the Java EE Support Patterns & Java Tutorial blog.

Pierre Hugues Charbonneau

Pierre-Hugues Charbonneau (nickname P-H) is working for CGI Inc. Canada for the last 10 years as a senior IT consultant. His primary area of expertise is Java EE, middleware & JVM technologies. He is a specialist in production system troubleshooting, root cause analysis, middleware, JVM tuning, scalability and capacity improvement; including internal processes improvement for IT support teams. P-H is the principal author at Java EE Support Patterns.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Nicolás
Nicolás
10 years ago

estimated:
happens I try to call a class library project java class from a java project standart and spews this error I have explained, and tried to fix it in all possible ways but nothing happens if you want to control what projects see

Rajkumar
Rajkumar
10 years ago

hi I am getting the error, when I tried to invoking a web service . I have deployed my client code in jboss. Class I am using to connect is SoapConnection.

2013-07-20 04:55:10,002 ERROR [STDERR] java.lang.NoClassDefFoundError: Could not initialize class javax.xml.soap.SOAPException
2013-07-20 04:55:10,002 ERROR [STDERR] at org.jboss.ws.core.soap.SOAPConnectionImpl.callInternal(SOAPConnectionImpl.java:115)
2013-07-20 04:55:10,002 ERROR [STDERR] at org.jboss.ws.core.soap.SOAPConnectionImpl.call(SOAPConnectionImpl.java:66)
2013-07-20 04:55:10,003 ERROR [STDERR] at com.wsi.sterling.api.webservice.APIWSIWebServiceClient.makeServiceCall(APIWSIWebServiceClient.java:382)
2013-07-20 04:55:10,003 ERROR [STDERR] at com.wsi.sterling.api.webservice.APIWSIWebServiceClient.retryWebServiceCall(APIWSIWebServiceClient.java:211)
2013-07-20 04:55:10,003 ERROR [STDERR] at com.wsi.sterling.api.webservice.APIWSIWebServiceClient.webServiceAdapter(APIWSIWebServiceClient.java:130)

Please help me in identifying the root cause of the issue.

Back to top button