in my Clojure library testlib
, i've got a namespace with a :gen-class
directive that looks like this:
(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.
However, if i lein install
, include testlib
in another project jartest
, and then use it in a test namespace below
(ns jartest.core
(:import [com.some_long_path NewClass]))
(NewClass.)
(NewClass/getValues "some string")
invoking NewClass
constructor gives an exception
CompilerException java.lang.NoClassDefFoundError: Could not initialize class com.some_long_path.NewClass
and getValues
as a consequence gives
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. 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.
Also, i've tried decompiling generated com.some_long_path.NewClass
class file, and there is a static initializer block that looks like this:
static
{
Util.loadWithClass("/com/some_long_path/NewClass", NewClass.class);
}
Most probably the above-mentioned error is thrown from within 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. Changing the code to use clojure.java.io/resource
fixed the problem. 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.
Heres hoping this isnt the highest voted answer.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.