I have a defrecord called ConstraintLookup in sre.plan.dsl.constraint namespace.
I want to use its generated class in a gen-class method placed on the sre.plan.compiler namespace:
(ns sre.plan.compiler
(:require
[sre.plan.dsl.constraint :as constraint])
(:import (sre.plan.dsl.constraint ConstraintLookup))
(:gen-class
:name sre.plan.Compiler
:methods [^:static [makeConstraintLookupFromTargetsAndBounds
[Iterable Iterable] ConstraintLookup]]))
I am AOT compiling with nebula-clojure plugin and Gradle. The compiler emits an error when it encounters the ns declaration:
> Task :sre:compileClojure
Exception in thread "main" java.lang.ClassNotFoundException: java.lang.ConstraintLookup, compiling:(sre/plan/compiler.clj:1:1)
Similarly when using fully qualified sre.plan.dsl.constraint.Constraint in the method declaration I get:
Exception in thread "main" java.lang.ClassNotFoundException: sre.plan.dsl.constraint.ConstraintLookup, compiling:(sre/plan/compiler.clj:1:1)
What is the problem here? I am lost.
UPDATE:
The referenced ns looks like this:
(ns sre.plan.dsl.constraint
(:require [clojure.set :refer :all]
[clojure.algo.generic.functor :refer :all]))
(defrecord ConstraintLookup [free bound])
UPDATE:
It seems to me that in gen-class you have to use fully qualified class names no matter what. However I still don't understand why doesn't the version with the fully qualified name work.
There is a good chance the
:gen-classdirective inside thensmacro cannot refer to classes generated as a side effect of:requirein the same form. The code emitted by thensmacro callsgen-classbefore calling any of therequires. Thus the required namespaces are not yet compiled whengen-classis called.gen-classis called before any classes fromdefrecordare generated.The behavior of
nscan be seen in the source code and also in the repl usingmacroexpand:To work around the problem, we can call
gen-classafterns. For example: