我正在尝试使用 HotswapAgentDCEVM 在一个混合的ClojureJava Leiningen项目中,为了避免在重新编译Java源代码后不得不重新启动REPL(我已经知道有其他的方法,比如JRebel和Virgil)。
简而言之。问题是 我得到一个 LinkageError
在我重新编译了一个Java类后,该类似乎没有被重新加载。
为了提供更多的细节,我已经在我的 ~/.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
为了重现这个问题,我建立了一个。最小的混合Leiningen Clojure和Java项目。 与一个小的Java类 AD
用这个代码。
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 + ")";
}
}
和一小段导入这个类的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))
然后我在EmacsCIDER中启动了一个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中的一条信息告诉我,该类的 AD
被重新加载。但是,当我重新评估表达式时,我发现 (raise-to-power (variable 3.0))
我希望结果是 AD(value=27.0, deriv=27.0)
但我却得到了这个错误。
在dcevm-complex-demo.adraise-to-power(ad.clj:10)处执行错误(LinkageError)。加载器约束违反:当解析方法'AD AD.raiseToPower()'时,当前类的类加载器clojure.lang. 动态类加载器@7c53a0c2的当前类dcevm_complex_demoad$raise_to_power和方法定义类AD的类加载器'app'在签名中使用的AD类型有不同的Class对象(dcevm_complex_demo. ad$raise_to_power 在 loader clojure.lang.DynamicClassLoader @7c53a0c2 的未命名模块中,父 loader clojure.lang.DynamicClassLoader @1217a2dd; AD 在 loader 'app' 的未命名模块中)
这就是完整的REPL交互的样子。
我怎么能让 课堂重装 AD
工作?我猜想我可能要改变功能 clojure.lang.RT.baseLoader()
(clojurelangRT.java),但我不太清楚该如何去做。
在dcevm8和dcevm11中都存在lambda重新定义的问题。这个问题在dcevm v11.0.7+1中得到了解决。根据你的日志,可以帮助你。https:/github.comTravaOpenJDKtrava-jdk-11-dcevmreleasestagdcevm-11.0.7+1。