繁体   English   中英

如何调试 Leiningen 生成的 jar 中的静态初始化程序错误?

[英]How to debug static initialiser errors in jars generated by Leiningen?

在我的 Clojure 库testlib ,我有一个带有:gen-class指令的命名空间,如下所示:

(ns com.some_long_path.NewClass
  (:import (java.util List ArrayList))
  (:gen-class
     :name com.some_long_path.NewClass
     :methods [^{:static true} [getValues [String] java.util.List]]
  )
  (:require
    [testlib.core :refer [var1 var2]]))

(defn getValues [^String]
  (java.util.ArrayList. [3 5]))

如果我尝试在testlib项目的另一个命名空间中import这个类(在调用compile ),我可以调用getValues方法而不会出错。

不过,如果我lein install ,包括testlib在另一个项目jartest ,然后在下面的测试命名空间使用

(ns jartest.core
  (:import [com.some_long_path NewClass]))

(NewClass.)
(NewClass/getValues "some string")

调用NewClass构造函数会出现异常

CompilerException java.lang.NoClassDefFoundError: Could not initialize class com.some_long_path.NewClass

getValues作为结果给出

CompilerException java.lang.IllegalStateException: Attempting to call unbound fn: #'com.some_long_path.NewClass/getValues

但是,如果我从上面的NewClass命名空间定义中删除require ,该代码甚至可以在另一个库中工作。 所以问题是由一些缺少的依赖项引起的,尽管我已经确保testlib所有依赖testlib也包含在jartest ,并且testlib.core命名空间是 AOT 编译的。

另外,我尝试反编译生成的com.some_long_path.NewClass类文件,并且有一个静态初始化块,如下所示:

static
{
  Util.loadWithClass("/com/some_long_path/NewClass", NewClass.class);
}

很可能上述错误是从loadWithClass抛出的。 但我如何找出到底是哪里出了问题?

谢谢!

更新:我能够通过二进制搜索错误找出我需要的命名空间中有什么问题(注释掉代码,直到事情再次运行)。 原来,一些文件被slurp编辑从resources文件夹中testlib ,但他们并没有出现在jartest项目。 更改代码以使用clojure.java.io/resource解决了该问题。 然而,问题仍然存在 - 如何在不诉诸蛮力方法的情况下确切地找出问题所在?

这是强制性的答案 - 没有更好的方法,没有更深入地理解依赖树,这通常只能通过注释掉内容并查看现在有效的方法来完成。 这是我从 clojure 加载 java 类和使用 gen-class 的经验。

继承人希望这不是最高投票的答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM