Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NPE in clojure.lang.Compiler when trying to load a resource

Tags:

java

clojure

I already reported this problem in CLJ-1172, but didn't receive any feedback from Clojure team. Maybe someone here can tell me what's wrong. This is my code:

import clojure.lang.Compiler;
Compiler.load(new StringReader("(+ 5 6)"));

Exception in runtime:

java.lang.ExceptionInInitializerError
  at clojure.lang.Compiler.<clinit>(Compiler.java:47)
Caused by: java.lang.NullPointerException
  at clojure.lang.RT.baseLoader(RT.java:2043)
  at clojure.lang.RT.load(RT.java:417)
  at clojure.lang.RT.load(RT.java:411)
  at clojure.lang.RT.doInit(RT.java:447)
  at clojure.lang.RT.<clinit>(RT.java:329)

Looks like RT and Compiler classes statically refer to each other. I'm using org.clojure:clojure:1.5.0 dependency.

like image 615
yegor256 Avatar asked Mar 04 '13 17:03

yegor256


1 Answers

It's OK for classes to statically refer to each other as long as their fields get initialized in the right order. In this case, Clojure probably expects RT to be initialized before Compiler. Here's the sequence of events:

  1. When you make a static call to Compiler, Java initializes all the static fields in that class.
  2. The static initializer for Compiler.FNONCE (line 47) calls a static method in RT, which causes that whole class to be initialized before the value of FNONCE is computed and set.
  3. The static initializer block for RT that begins on line 299 calls a static method which eventually refers to the static Compiler.LOADER field.
  4. The JVM would normally initialize the Compiler class here, but it sees that Compiler is currently being initialized and just grabs the current value. Fields are initialized in the order they are declared in the file, and since LOADER comes after FNONCE the un-initialized value of null is returned, throwing a NPE when it's dereferenced in RT.

Bottom line: make a call to some static method in RT (or read a static field) before your call to Compiler.load and your error should go away.

More details on the specifics of class initialization is available in section 12.4 of the Java Language Specification.

like image 159
Alex Avatar answered Oct 30 '22 06:10

Alex