1

I generated a class using ASM and now I'm trying to load this class using the ContextClassLoader:

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

controllerclass is the Byte-array containing the class. The exception I get is:

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

I tried adding type hints, but that had no effect. How do I tell Clojure which method exactly to use? The types definitely match the ones shown in the javadoc of Java 8.

Daniel Ziltener
  • 647
  • 1
  • 6
  • 21

1 Answers1

2

The defineClass method is not even accessible in AppClassLoader since it inherits from URLClassLoader and defineClass is private in that class.

Generally, what you want to do is you want to register the class you compiled as a classloader resource so that it can find it natively using findClass.

Piotr Wilkin
  • 3,446
  • 10
  • 18
  • You may be right that it's an accessibility issue, but not about the details. The base `ClassLoader` provides three `protected` versions of `defineClass()` (and `SecureClassLoader` provides two more); the OP appears to be trying to use one of these. They would not normally be accessible to Java code other than in subclasses or elsewhere in the same package, but I'm not sure whether they would be expected to be usable via the Clojure / ASM technique the OP is using. – John Bollinger Nov 14 '17 at 14:12