clojure:命名空间中的ExceptionInInitializerError。从非默认类路径加载 [英] clojure: ExceptionInInitializerError in Namespace.<init> loading from a non-default classpath

查看:79
本文介绍了clojure:命名空间中的ExceptionInInitializerError。从非默认类路径加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试从非默认类路径加载AOT编译的类时,收到以下异常:

In attempting to load an AOT-compiled class from a non-default classpath, I receive the following exception:

Traceback (innermost last):
  File "test.jy", line 10, in ?
        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 aot_demo.JavaClass.<clinit>(Unknown Source)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:247)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
java.lang.ExceptionInInitializerError: java.lang.ExceptionInInitializerError

我可以在以下琐碎的项目中重现此内容。 clj

(defproject aot-demo "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.3.0"]]
  :aot [aot-demo.core])

...和 src / aot_demo / core.clj 定义如下:

(ns aot-demo.core
  (:gen-class
    :name aot_demo.JavaClass
    :methods [#^{:static true} [lower [java.lang.String] java.lang.String]]))

(defn -lower [str] (.toLowerCase str))

那么下面的Jython脚本足以触发该错误:

The following Jython script is then sufficient to trigger the bug:

#!/usr/bin/jython
import java.lang.Class
import java.net.URLClassLoader
import java.net.URL
import os

customLoader = java.net.URLClassLoader(
    [java.net.URL('file://%s/target/aot-demo-0.1.0-SNAPSHOT-standalone.jar'
                  % (os.getcwd()))])

java.lang.Class.forName('aot_demo.JavaClass', True, customLoader)

但是,如果启动测试脚本,则不会出现 异常并在 CLASSPATH 变量中添加了uberjar。

However, the exception does not occur if the test script is started with the uberjar already in the CLASSPATH variable.

这是怎么回事?我正在尝试在Clojure中为BaseX数据库编写一个插件;上面的代码准确地表示了他们的插件加载机制如何为该问题提供SSCE。

What's going on here? I'm trying to write a plugin for the BaseX database in Clojure; the above accurately represents how their plugin-loading mechanism works for the purpose of providing a SSCE for this problem.

推荐答案

插件-应该扩展BaseX所使用的加载机制,以修改当前线程的上下文类加载器。对于给定的示例代码(在Jython中),这类似于以下内容:

The plugin-loading mechanism used by BaseX should be extended to modify the current thread's context classloader. For the given sample code (in Jython), this would look something like the following:

currentThread = java.lang.Thread.currentThread()
oldLoader = currentThread.getContextClassLoader()

currentThread.setContextClassLoader(customLoader)
try:
    cls = java.lang.Class.forName('aot_demo.JavaClass', True, customLoader)
finally:
    currentThread.setContextClassLoader(oldLoader)

这篇关于clojure:命名空间中的ExceptionInInitializerError。从非默认类路径加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆