2013-03-04 3 views
6

この問題はすでにCLJ-1172に報告されていますが、Clojureチームからのフィードバックはありませんでした。多分、ここの誰かが何が間違っているか教えてくれるかもこれは私のコードです:ランタイムでリソースをロードしようとすると、clojure.lang.CompilerのNPE

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

例外:

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) 

RTのように見えるとCompilerクラスは静的にお互いを参照してください。私はorg.clojure:clojure:1.5.0依存関係を使用しています。

答えて

8

クラスは、フィールドが正しい順序で初期化される限り、静的に互いを参照することができます。この場合、ClojureはCompilerより前にRTを初期化すると考えられます。

  1. 静的呼び出しをCompilerにすると、Javaはそのクラスのすべての静的フィールドを初期化します。
  2. Compiler.FNONCE(47行目)の静的初期化子はRTで静的メソッドを呼び出し、FNONCEの値が計算されて設定される前にクラス全体が初期化されます。
  3. RTのスタティックイニシャライザブロックは、299行で開始され、最終的にスタティックCompiler.LOADERフィールドを参照するスタティックメソッドを呼び出します。
  4. 通常、JVMはここでCompilerクラスを初期化しますが、現在はCompilerが初期化されており、現在の値を取得していることがわかります。フィールドはファイル内で宣言されている順番で初期化され、FNONCEの後にLOADERがあるので、nullの初期化されていない値が返され、逆参照されるとNPEが返されます。RT

ボトムライン:Compiler.loadにお電話し、あなたのエラーが離れて行く必要があります前にRTにいくつかの静的メソッドへの呼び出しを行う(または静的フィールドを読んで)。

クラス初期化の詳細については、Java Language Specificationの12.4項を参照してください。

+0

あなたは正しく、 'RT.init()'を呼び出すことで問題を解決することができます。ありがとう! – yegor256

関連する問題