I am working on a little prototype project that attempts to drive a Java-based system (a workflow orchestration engine) from Clojure and running into a stumbling block. The system relies heavily on the usage of annotated Java interfaces to define the workflows to be executed; I am in the process of porting some Java-based example code to try and get a handle on how things might work:
(gen-interface
:name com.example.flow.workflow.greeting.GreetingWorkflow
:methods [[^{WorkflowMethod {;; FIXME needs a primitive int argument
:executionStartToCloseTimeoutSeconds 10
:taskList "HelloActivity"}}
getGreeting [String] String]])
For reference, the example Java code looks like:
public interface GreetingWorkflow {
@WorkflowMethod(
executionStartToCloseTimeoutSeconds = 10,
taskList = TASK_LIST
)
String getGreeting(String name);
}
AOT-compilation is successful, but then during execution I see the following error:
Incorrectly typed data found for annotation element
public abstract int com.foobar.WorkflowMethod.executionStartToCloseTimeoutSeconds()
(Found data of type java.lang.Long[10])
The annotation parameter requires an int
and doesn’t like that it’s given a Long
instead. The docs for this exception state that it is:
Thrown to indicate that a program has attempted to access an element of an annotation whose type has changed after the annotation was compiled (or serialized). This exception can be thrown by the API used to read annotations reflectively.
A couple of attempts I made to coerce the value in the annotation map looked like:
:executionStartToCloseTimeoutSeconds (unchecked-int 10)
which resulted in the follow AOT compilation error:
Unexpected error (ClassCastException) macroexpanding gen-interface at (com/example/flow/workflow/greeting.clj:71:1).
class clojure.lang.Var cannot be cast to class java.lang.Class
(clojure.lang.Var is in unnamed module of loader 'app'; java.lang.Class is in module java.base of loader 'bootstrap')
Applying a type hint:
:executionStartToCloseTimeoutSeconds #^int 10
resulted in the following AOT-compilation error:
Syntax error (IllegalArgumentException) compiling at (com/example/flow/workflow/greeting.clj:77:0).
Metadata can only be applied to IMetas
If I am missing something obvious, or anyone has any suggestions for further exploration, I’d appreciate your input. As an aside, my motivation in this is that I’d eventually like to declare these workflows as edn data files that refer to Clojure functions that do the work, and generate the necessary Java interfaces and classes using (gen-interface)
and (gen-class)
.