0

I have a code which initializes a class as:

private static MyClass myObj = new MyClass();

And I am using myObj in my code below. This works fine if Java 6 is used. But when I use Java 7, NullPointerException is thrown.

java.lang.NullPointerException
Exception in thread "main" java.lang.ExceptionInInitializerError

As a work around, I put a null check for myObj before using it and made it work.

But I am still confused if there is any changes in Java 7 implementation that made static initialization fail?

EDIT : Found similar issue was faced by OpenAM.

9
  • 3
    Seems strange. Hard to say without seeing more code, but this will probably help: stackoverflow.com/questions/19058766/… Commented May 13, 2015 at 21:10
  • 6
    Really need more code. java.lang.ExceptionInInitializerError means the NPE throws from somewhere in the static initializer section. Are you sure that the NPE isn't thrown from the MyClass constructor? Commented May 13, 2015 at 21:13
  • 1
    I'm guessing that your classes have a cycle in initializing values (e.g. class A's static field initial value depends on class B's static field which depends on class A...), and the exception depends on the load order of the classes, whose control flow might be data-dependent. Commented May 13, 2015 at 21:14
  • Generally speaking, the Java ecosystem is extremely conservative wrt compatibility (unlike say Python). Something as important as the observable behavior of class loading/initialization is unlikely to change from version to version... Commented May 13, 2015 at 21:16
  • Paste your actual MyClass. It's hard to tell what's causing the NullPointerException like this. Commented May 13, 2015 at 21:22

2 Answers 2

2

We'll need more code sample and exception stacktrace to diagnostic.

Pure speculation, I know that in Java 7, they changed class initialization a little bit

https://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.2

For each class or interface C, there is a unique initialization lock LC. The mapping from C to LC is left to the discretion of the Java Virtual Machine implementation. The procedure for initializing C is then as follows:

  1. Synchronize on the initialization lock, LC, for C. This involves waiting until the current thread can acquire LC.

this is different from previous java where the class object itself is used as the lock.

Still, it's quite unlikely that it's responsible for your case.

Sign up to request clarification or add additional context in comments.

4 Comments

To be precise, the Java 7 approach can be different. As far as I can tell, the new wording is more permissive; it does not appear to rule out the old behavior.
@JohnBollinger - no idea why they even made the change; I would bet they are compelled to, because they are actually using a different lock.
Keeping the initialization locks separate from the classes themselves reserves them for use by the class initialization process. In particular, it prevents static initializer blocks from accessing them, with the concomitant risk of introducing a deadlock into the class initialization process. It may also be intended to allow implementations to use a different locking implementation for initialization locks.
@JohnBollinger - but more locks = more deadlocks :) actually, LC could be used to reduce locks. for example, if there is just one global LC for all, there will be no deadlock ... anyway, it is quite likely that JVM7 indeed overhauled class initialization procedure.
0

You could try:

public class X {

   private static MyClass myObj;

   static {
      myObj = new MyClass();
   }

}

Altough the static method is usually used to perform multiple operations

1 Comment

Why do you think this is any different?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.