繁体   English   中英

将 HotswapAgent/DCEVM 与 Clojure REPL 一起使用时出现 LinkageError

[英]LinkageError when using HotswapAgent/DCEVM with Clojure REPL

我正在尝试在混合的 Clojure/Java Leiningen 项目中使用HotswapAgent/DCEVM ,以避免在重新编译 Java 源代码后必须重新启动 REPL(我已经知道其他方法,例如 JRebel 和 Virgil)。

简而言之,问题是我在重新加载我重新编译的 Java class 后出现LinkageError ,而且似乎 class 没有重新加载。

为了提供更多详细信息,我设置了我的~/.lein/profiles.clj ,以便在:repl配置文件中,我们使用在此处找到的当前版本的 DCEVM JVM 来运行 REPL。 这是profiles.clj的相关部分:

{:repl
 {:plugins [[cider/cider-nrepl "0.22.4"]]
  :dependencies [[org.clojure/tools.nrepl "0.2.13"]]

  :java-cmd "/home/jonas/local/dcevm-11.0.6+1/bin/java"

  ... ;; Rest of profiles.clj

To reproduce the problem, I have set up a minimal mixed Leiningen Clojure and Java project with a small Java class AD with this code:

public class AD {
    public double _value;
    public double _deriv;

    public static int EXPONENT = 4;

    public AD(double value, double deriv) {
        _value = value;
        _deriv = deriv;
    }

    public AD mul(AD x) {
        return new AD(_value*x._value, _value*x._deriv + _deriv*x._value);
    }

    public AD raiseToPower() {
        AD result = new AD(1.0, 0.0);
        for (int i = 0; i < EXPONENT; i++) {
            result = result.mul(this);
        }
        return result;
    }

    public String toString() {
        return "AD(value=" + _value + ", deriv=" + _deriv + ")";
    }
}

以及一小段导入此 class 的 Clojure 代码:

(ns dcevm-complex-demo.ad
  (:import AD))

(defn variable [x]
  (AD. (double x) 1.0))

(defn raise-to-power
  "Evaluates f(x) = x^n and f'(x), n being the AD/EXPONENT static variable"
  [^AD ad-x]
  (.raiseToPower ad-x))

然后我在 Emacs/CIDER 中启动 Clojure REPL,加载dcevm-complex-demo.ad命名空间并评估表达式(raise-to-power (variable 3.0))生成结果AD(value=81.0, deriv=108.0) . 然后我修改Java源代码,比如我public static int EXPONENT = 4; public static int EXPONENT = 3; 并在终端中使用lein javac重新编译。 REPL 中的一条消息告诉我 class AD已重新加载。 但是,当我重新评估表达式(raise-to-power (variable 3.0))时,我希望得到结果AD(value=27.0, deriv=27.0) ,但我得到了这个错误:

dcevm-complex-demo.ad/raise-to-power (ad.clj:10) 处的执行错误 (LinkageError)。 loader constraint violation: when resolving method 'AD AD.raiseToPower()' the class loader clojure.lang.DynamicClassLoader @7c53a0c2 of the current class, dcevm_complex_demo/ad$raise_to_power, and the class loader 'app' for the method's defining class, AD , have different Class objects for the type AD used in the signature (dcevm_complex_demo.ad$raise_to_power is in unnamed module of loader clojure.lang.DynamicClassLoader @7c53a0c2, parent loader clojure.lang.DynamicClassLoader @1217a2dd; AD is in unnamed module of loader '应用程序')

这是完整的 REPL 交互的样子:

REPL 交互

如何使class AD的重新加载工作? I suspect that I might have to change the function clojure.lang.RT.baseLoader() ( clojure/lang/RT.java ) but I am not quite sure how to go about that.

lambda 重新定义在 dcvm8 和 dcvm11 中都存在问题。 此问题已在 dcevm v11.0.7+1 中得到解决。 根据您的日志,它可能会有所帮助。 https://github.com/TravaOpenJDK/trava-jdk-11-dcevm/releases/tag/dcevm-11.0.7+1

暂无
暂无

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

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