2012-03-26 2 views
0

Clojureによって生成されたクラスによって公開される静的メソッド(epadEval)と呼ばれるJava/Scalaの混合物ca.gsimard.spacecraft.client.clojail)。 clojail.cljでScala/Clojure interopはPC上で動作しますが、java.lang.ExceptionInInitializerErrorを使って別のクラスで失敗します


(Leinengenスタンドアロンジャーにコンパイル: "レインuberjar")main.scalaにおいて

(ns ca.gsimard.spacecraft.client.clojail 
    (:use [clojail core testers]) 
    (:gen-class 
    :name ca.gsimard.spacecraft.client.clojail 
    :methods [#^{:static true} [epadEval [String] String]])) 

(defn -epadEval 
    "Evaluate string s within a clojail sandbox." 
    [s] 
    (let [writer (java.io.StringWriter.)] 
    (*sb* (safe-read (str "(print " s ")")) {#'*out* writer}) 
    (str writer))) 


(Iは.jarファイルをインポートEclipseプロジェクトで)Leinengenによって以前に生成:

import ca.gsimard.spacecraft.client.clojail 
println("Epad: " + clojail.epadEval("(+ 1 2 3)")) 

私は脂肪のjarを構築することにより、プロジェクトを展開し、それを実行します。

PC1(Linux)のオン

:PC2(Windows 7の)オン

Epad: 6 

Exception in thread "main" java.lang.ExceptionInInitializerError 
    at clojure.lang.Namespace.<init>(Namespace.java:34) 
    at clojure.lang.Namespace.findOrCreate(Namespace.java:176) 
    at clojure.lang.Var.internPrivate(Var.java:149) 
    at ca.gsimard.spacecraft.client.clojail.<clinit>(Unknown Source) 
    at ca.gsimard.spacecraft.client.Epad$.eval(EpadClient.scala:78) 
    at ca.gsimard.spacecraft.client.Main$.main(MainClient.scala:25) 
    at ca.gsimard.spacecraft.client.Main.main(MainClient.scala) 
Caused by: java.lang.NullPointerException 
    at clojure.core$eval1697$fn__1698.invoke(core.clj:6135) 
    at clojure.core$eval1697.invoke(core.clj:6135) 
    at clojure.lang.Compiler.eval(Compiler.java:6465) 
    at clojure.lang.Compiler.load(Compiler.java:6902) 
    at clojure.lang.RT.loadResourceScript(RT.java:357) 
    at clojure.lang.RT.loadResourceScript(RT.java:348) 
    at clojure.lang.RT.load(RT.java:427) 
    at clojure.lang.RT.load(RT.java:398) 
    at clojure.lang.RT.doInit(RT.java:434) 
    at clojure.lang.RT.<clinit>(RT.java:316) 
    ... 7 more 

私は何が起こっているのかについてかなり無知だ:私が知っているすべてはあまりありませんが起こっているということです。 Clojureクラスはロードされていないようです。 (ns ..)と(defn ..)の間に(println ..)コマンドを追加すると、PC2上に何も印刷されないので、呼び出し時ではなく読み込み時に問題があるようです。

これが失敗するのと同じWindows7コンピュータでは、(-emad)メソッド呼び出し(-epadEval ..)を使ってClojureのみのスタンドアロンのuberjarを構築して正常に実行できることに注意してください。

ここで何が起こっているのでしょうか?

編集:これは、java -verboseと以下のように実行しました。私が理解しているところから、関数epadEvalが定義される前に呼び出されます! JVMのロード中に例外が発生するclojure.core。それ以前に[Loaded ca.gsimard.spacecraft.client.clojail ...]が見つかりませんでした。

[Loaded clojure.core$eval1697$fn__1698 from __JVM_DefineClass__] 
[Loaded clojure.core$eval1697 from __JVM_DefineClass__] 
Exception in thread "main" [Loaded java.lang.Throwable$PrintStreamOrWriter from 
C:\Program Files\Java\jre7\lib\rt.jar] 
[Loaded java.lang.Throwable$WrappedPrintStream from C:\Program Files\Java\jre7\lib\rt.jar] 
[Loaded java.util.IdentityHashMap$KeySet from C:\Program Files\Java\jre7\lib\rt.jar] 
java.lang.ExceptionInInitializerError 
    at clojure.lang.Namespace.<init>(Namespace.java:34) 
    at clojure.lang.Namespace.findOrCreate(Namespace.java:176) 
    at clojure.lang.Var.internPrivate(Var.java:149) 
    at ca.gsimard.spacecraft.client.clojail.<clinit>(Unknown Source) 
    at ca.gsimard.spacecraft.client.Epad$.eval(EpadClient.scala:78) 
    at ca.gsimard.spacecraft.client.Main$.main(MainClient.scala:25) 
    at ca.gsimard.spacecraft.client.Main.main(MainClient.scala) 
[Loaded java.util.Objects from C:\Program Files\Java\jre7\lib\rt.jar] 
Caused by: java.lang.NullPointerException 
    at clojure.core$eval1697$fn__1698.invoke(core.clj:6135) 
    at clojure.core$eval1697.invoke(core.clj:6135) 
    at clojure.lang.Compiler.eval(Compiler.java:6465) 
    at clojure.lang.Compiler.load(Compiler.java:6902) 
    at clojure.lang.RT.loadResourceScript(RT.java:357) 
    at clojure.lang.RT.loadResourceScript(RT.java:348) 
    at clojure.lang.RT.load(RT.java:427) 
    at clojure.lang.RT.load(RT.java:398) 
    at clojure.lang.RT.doInit(RT.java:434) 
    at clojure.lang.RT.<clinit>(RT.java:316) 
    ... 7 more 
[Loaded java.lang.Shutdown from C:\Program Files\Java\jre7\lib\rt.jar] 
[Loaded java.lang.Shutdown$Lock from C:\Program Files\Java\jre7\lib\rt.jar] 

誰もが尋ねる前に、はい、(アッカ俳優を使って)このアプリで複数のスレッドがあり、はい、epadEvalへの呼び出しは、そのような俳優の受信機能をから行われます。 Windows 7を実行しているPC(クラッシュしている場所)には、Linuxを実行している2コアのラップトップ(これはクラッシュしない)より多くのコアがあります。私の推測では、今私のラップトップのスレッドで一貫してラッキーだと思っています。

  • これは意味がありますか?
  • clojailクラスが完全にロードされていて、一部のスレッドがその静的関数の1つを呼び出そうとする前に、どうすればよいですか?
+0

これは疑わしいhttp://dev.clojure.org/jira/browse/CLJ-260のようです。おそらくあなたのスカラーコードがクラスローダーで遊んでいるのでしょうか?また、参照してください:http://stackoverflow.com/questions/9814005/clojure-exceptionininitializererror-in-namespace-init-loading-from-a-non-defa – sw1nn

+0

いいえ私はクラスローダーで遊んでいません、運良く私のためです。 – gsimard

答えて

0

Akkaは、現在のスレッド(ActorSystemを作成するスレッド)コンテキストクラスローダー(存在する場合)を使用します。ここで遊べますか?

+0

Leiningenを使ってclojure jarをパッケージ化し、その後にsbtを使ってビルドするのではなく、Maven3(これはScala/Java/Clojureプロジェクト)を使ってすべてを再構築しました。もう問題はありません。私はこれの背後にある本当の問題を突き止めることができなかったことに失望していましたが、私はそれがclojure jarの部分が完全に事前にロードされていることを確認していない呼び出し元のスレッドと関係があると推測しています。 – gsimard

0

これらの問題は、マシン間の環境の違いによるものです。あなたはIDEについて言及していません(もしあればEclipseですか?)

JVMのバージョンを確認し、あなたが思うJVMを使用していることを確認することが重要です。たとえば、LinuxではopenJDKを、WindowsではOracle JDKを使用できます。 両方のマシンでjava --versionを実行して設定を確認してください。

ご支援いただけるよう、設定に関する詳細情報を掲載してください。

+0

main.scala: (以前はLeinengenによって以前に生成された.jarをインポートする** Eclipseプロジェクトで) JVMバージョンに関するご意見ありがとうございます。これらのうち私は今すぐアクセスすることはできません。 – gsimard

2

これは別の回答でも指摘されているように、これは環境の違いがほぼ確実です。このような冗長モードで

実行中のJava:

java -verbose -jar project.jar 

は、クラスのロードに関する多くの情報を提供します。運があれば、例外が発生する直前にクラスがロードされていた有益な情報を推測することができます。

関連する問題