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.

codingenious
  • 8,385
  • 12
  • 60
  • 90
  • 3
    Seems strange. Hard to say without seeing more code, but this will probably help: http://stackoverflow.com/questions/19058766/java-static-initialization-order – Oliver Dain May 13 '15 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? – Radiodef May 13 '15 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. – Nayuki May 13 '15 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... – Nayuki May 13 '15 at 21:16
  • Paste your actual `MyClass`. It's hard to tell what's causing the `NullPointerException` like this. – carlspring May 13 '15 at 21:22
  • As Radiodef said there is an exception occuring in your constructor most probably. Add a Try-catch in your constructor and print the stacktrace. – Mecon May 13 '15 at 21:24
  • Also ... try to load this class during applications startup. This way your app will not even start if this static initializer stuff is causing error. So.. try to write something that will let you avoid writing a null check. – Mecon May 13 '15 at 21:26
  • I don't have code of MyClass, actually it's not mine but 3rd party code. I had same feeling that NPE is thrown by constructor of MyClass but it works fine with Java 6. I can not understand why? – codingenious May 14 '15 at 00:31
  • I was searching for the issue online, and found this : https://bugster.forgerock.org/jira/browse/OPENAM-1110 (seems OpenAM faced similar issue.) – codingenious May 14 '15 at 00:32

2 Answers2

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.

Community
  • 1
  • 1
ZhongYu
  • 19,446
  • 5
  • 33
  • 61
  • 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. – John Bollinger May 13 '15 at 21:34
  • @JohnBollinger - no idea why they even made the change; I would bet they are compelled to, because they are actually using a different lock. – ZhongYu May 13 '15 at 21:45
  • 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. – John Bollinger May 13 '15 at 21:58
  • @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. – ZhongYu May 13 '15 at 22:10
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

RedPelle
  • 285
  • 4
  • 17