我在使用 Java 互操作时遇到了一个奇怪的问题。我围绕 BDB JE API 编写了一个小型专用包装器。当我在 repl (cider-repl) 中时,一切正常:我可以打开数据库、添加条目等。但是如果我从我的应用程序中的另一个函数调用 add-record 函数,我会得到一个 NPE,
NullPointerException clojure.lang.Reflector.invokeInstanceMethod (Reflector.java:26)
我开始觉得我疯了。这将打开数据库:
(defn opendb [envpath dbname]
(let [envconf (.setAllowCreate (EnvironmentConfig.) true)
env (Environment. (ensure-directory envpath) envconf)
dbconf (-> (DatabaseConfig.) (.setAllowCreate true) (.setDeferredWrite true))
database (.openDatabase env nil dbname dbconf)]
{:environment env :database database}))
这里是add-record
:
(defn add-record [dbm k v]
(let [key (DatabaseEntry. (.getBytes k "UTF-8"))
value (DatabaseEntry. (.getBytes v "UTF-8"))]
(.put (:database dbm) nil key value)))
这里真的没有什么特别的。这产生 NPE 的用法类似于
(let [cache (bdb/opendb "local-cache" "subject-map")]
;; do stuff
(doseq [node (function "that returns a sequence of maps")]
(bdb/add-record cache (:foo node) (:bar node)))
(bdb/closedb cache))
我prn
在 bb/add-record 中添加了 S 并且所有值都是 non- nil
,但我仍然得到 NPE。
这里正在发生一些微妙的事情,它正在躲避我。有人有想法吗?
提前致谢。
编辑:这是完整的堆栈跟踪:
Exception in thread "main" java.lang.NullPointerException
at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:26)
at sterling.bdbje$add_record.invoke(bdbje.clj:33)
at sterling.loaders$load_subject_batch.invoke(loaders.clj:214)
at sterling.loaders$load_subject_headings.invoke(loaders.clj:224)
at sterling.loaders$_main.doInvoke(loaders.clj:257)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at sterling.loaders.main(Unknown Source)
正如我所说,这对我来说毫无意义,但完全可以重现。