gpt4 book ai didi

java - Scala/Clojure 互操作可以在 PC 上运行,但在另一台 PC 上失败并出现 java.lang.ExceptionInInitializerError

转载 作者:行者123 更新时间:2023-12-02 07:54:00 26 4
gpt4 key购买 nike

我有一个用 Java/Scala 混合编写的项目,其中调用由 Clojure 生成的类 (ca.gsimard.spacecraft.client.clojail) 公开的静态方法 (epadEval)。

在 clojail.clj 中:
(用Leinengen编译成独立的jar:“lein uberjar”)

(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)))

在 main.scala 中:
(在 Eclipse 项目中,我导入了先前由 Leinengen 生成的 .jar):

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

我通过构建一个 fat jar 来部署该项目并运行它:

在 PC1 (Linux) 上:

Epad: 6

在 PC2 (Windows 7) 上:

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 计算机上,我可以成功构建并运行仅 Clojure 的独立 uberjar,并使用 (-main) 方法调用 (-epadEval..)。

知道这里发生了什么吗?

编辑:我已经按照下面的建议使用java -verbose运行了这个。据我了解,函数epadEval在定义之前就被调用了!当 JVM 仍在加载 clojure.core 时,会发生异常。在此之前我没有看到任何[已加载 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]

在有人问之前,是的,这个应用程序中有多个线程(使用 Akka Actors),是的,对 epadEval 的调用是通过此类 Actor 的 receive 函数完成的。运行 Windows 7(会崩溃)的 PC 比我运行 Linux(不会崩溃)的 2 核笔记本电脑拥有更多内核。我的猜测是,我现在对笔记本电脑上的线程一直很幸运。

  • 这个猜测有道理吗?
  • 如何确保在某些线程尝试调用其静态函数之一之前 clojail 类已完全加载?

最佳答案

正如另一个答案中所指出的,这几乎肯定是环境差异。

以详细模式运行 java,如下所示:

java -verbose -jar project.jar

将提供大量有关类加载的信息。运气好的话,您将能够推断出在异常发生之前加载的类的一些有用信息。

关于java - Scala/Clojure 互操作可以在 PC 上运行,但在另一台 PC 上失败并出现 java.lang.ExceptionInInitializerError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9876868/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com