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-class
directive inside thens
macro cannot refer to classes generated as a side effect of:require
in the same form. The code emitted by thens
macro callsgen-class
before calling any of therequire
s. Thus the required namespaces are not yet compiled whengen-class
is called.gen-class
is called before any classes fromdefrecord
are generated.The behavior of
ns
can be seen in the source code and also in the repl usingmacroexpand
:To work around the problem, we can call
gen-class
afterns
. For example: