简体   繁体   English

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

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

in my Clojure library testlib , i've got a namespace with a :gen-class directive that looks like this:在我的 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]))

If i try to import this class inside another namespace in the testlib project (after invoking compile ), i can invoke getValues method without errors.如果我尝试在testlib项目的另一个命名空间中import这个类(在调用compile ),我可以调用getValues方法而不会出错。

However, if i lein install , include testlib in another project jartest , and then use it in a test namespace below不过,如果我lein install ,包括testlib在另一个项目jartest ,然后在下面的测试命名空间使用

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

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

invoking NewClass constructor gives an exception调用NewClass构造函数会出现异常

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

and getValues as a consequence givesgetValues作为结果给出

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

However, if i remove the require s from NewClass namespace definition above, the code works even in another library.但是,如果我从上面的NewClass命名空间定义中删除require ,该代码甚至可以在另一个库中工作。 So the problem is caused by some missing dependencies, although i've made sure that all dependencies of testlib are also included in jartest , and that testlib.core namespace is AOT-compiled.所以问题是由一些缺少的依赖项引起的,尽管我已经确保testlib所有依赖testlib也包含在jartest ,并且testlib.core命名空间是 AOT 编译的。

Also, i've tried decompiling generated com.some_long_path.NewClass class file, and there is a static initializer block that looks like this:另外,我尝试反编译生成的com.some_long_path.NewClass类文件,并且有一个静态初始化块,如下所示:

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

Most probably the above-mentioned error is thrown from within loadWithClass .很可能上述错误是从loadWithClass抛出的。 But how do i find out what exactly is wrong?但我如何找出到底是哪里出了问题?

Thanks!谢谢!

UPDATE: I was able to figure out what was wrong in the namespace i was requiring through a binary search for errors (commenting out code until things worked again).更新:我能够通过二进制搜索错误找出我需要的命名空间中有什么问题(注释掉代码,直到事情再次运行)。 It turned out that some files were slurp ed from resources folder in testlib , but they were not present in jartest project.原来,一些文件被slurp编辑从resources文件夹中testlib ,但他们并没有出现在jartest项目。 Changing the code to use clojure.java.io/resource fixed the problem.更改代码以使用clojure.java.io/resource解决了该问题。 However, the question still stands - how to find out exactly what was the problem, without resorting to brute force methods?然而,问题仍然存在 - 如何在不诉诸蛮力方法的情况下确切地找出问题所在?

Here is the obligatory answer- there isnt a better way, without understanding the dependency tree more deeply, which often can only be done by commenting stuff out and seeing what now works.这是强制性的答案 - 没有更好的方法,没有更深入地理解依赖树,这通常只能通过注释掉内容并查看现在有效的方法来完成。 That has been my experience with java classloading from clojure and using gen-class.这是我从 clojure 加载 java 类和使用 gen-class 的经验。

Heres hoping this isnt the highest voted answer.继承人希望这不是最高投票的答案。

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

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