在ClassLoader上调用`defineClass`会导致“找不到匹配的方法”

时间:2017-11-14 13:59:46

标签: java clojure classloader contextclassloader

我使用ASM生成了一个类,现在我正在尝试使用ContextClassLoader加载这个类:

(.defineClass classloader (str pkg "." classname) controllerclass 0 (count controllerclass))

controllerclass是包含该类的字节数组。我得到的例外是:

java.lang.IllegalArgumentException: No matching method found: defineClass for class sun.misc.Launcher$AppClassLoader, compiling:(fxml_test.clj:29:1)
Exception in thread "main" java.lang.IllegalArgumentException: No matching method found: defineClass for class sun.misc.Launcher$AppClassLoader, compiling:(fxml_test.clj:29:1)
        at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3700)
        at clojure.lang.Compiler.compile1(Compiler.java:7609)
        at clojure.lang.Compiler.compile(Compiler.java:7676)
        at clojure.lang.RT.compile(RT.java:413)
        at clojure.lang.RT.load(RT.java:458)
        at clojure.lang.RT.load(RT.java:426)
        at clojure.core$load$fn__6548.invoke(core.clj:6046)
        at clojure.core$load.invokeStatic(core.clj:6045)
        at clojure.core$load.doInvoke(core.clj:6029)
        at clojure.lang.RestFn.invoke(RestFn.java:408)
        at clojure.core$load_one.invokeStatic(core.clj:5848)
        at clojure.core$compile$fn__6553.invoke(core.clj:6056)
        at clojure.core$compile.invokeStatic(core.clj:6056)
        at clojure.core$compile.invoke(core.clj:6048)
        at user$eval246$fn__255.invoke(form-init5690492012618124781.clj:1)
        at user$eval246.invokeStatic(form-init5690492012618124781.clj:1)
        at user$eval246.invoke(form-init5690492012618124781.clj:1)
        at clojure.lang.Compiler.eval(Compiler.java:7062)
        at clojure.lang.Compiler.eval(Compiler.java:7052)
        at clojure.lang.Compiler.eval(Compiler.java:7052)
        at clojure.lang.Compiler.load(Compiler.java:7514)
        at clojure.lang.Compiler.loadFile(Compiler.java:7452)
        at clojure.main$load_script.invokeStatic(main.clj:278)
        at clojure.main$init_opt.invokeStatic(main.clj:280)
        at clojure.main$init_opt.invoke(main.clj:280)
        at clojure.main$initialize.invokeStatic(main.clj:311)
        at clojure.main$null_opt.invokeStatic(main.clj:345)
        at clojure.main$null_opt.invoke(main.clj:342)
        at clojure.main$main.invokeStatic(main.clj:424)
        at clojure.main$main.doInvoke(main.clj:387)
        at clojure.lang.RestFn.applyTo(RestFn.java:137)
        at clojure.lang.Var.applyTo(Var.java:702)
        at clojure.main.main(main.java:37)
Caused by: java.lang.IllegalArgumentException: No matching method found: defineClass for class sun.misc.Launcher$AppClassLoader
        at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:53)
        at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:28)
        at clojurefx.controllergen$gen_fx_controller_class.invokeStatic(controllergen.clj:198)
        at clojurefx.controllergen$gen_fx_controller_class.invoke(controllergen.clj:185)
        at clojurefx.fxml$load_fxml_with_controller.invokeStatic(fxml.clj:13)
        at clojurefx.fxml$load_fxml_with_controller.invoke(fxml.clj:12)
        at clojure.lang.AFn.applyToHelper(AFn.java:156)
        at clojure.lang.AFn.applyTo(AFn.java:144)
        at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3695)
        ... 32 more

我尝试添加类型提示,但这没有效果。如何告诉Clojure使用哪种方法?这些类型与Java 8的javadoc中显示的类型完全匹配。

1 个答案:

答案 0 :(得分:2)

defineClass方法甚至无法在AppClassLoader中访问,因为它继承自URLClassLoader,而defineClass在该类中是私有的。

通常,您要做的是要将您编译的类注册为类加载器资源,以便它可以使用findClass本地查找它。