Skip to content

Instantly share code, notes, and snippets.

@kylc
Created August 21, 2025 01:29
Show Gist options
  • Select an option

  • Save kylc/14e93f5e8c8346b6da53ed6ea109e332 to your computer and use it in GitHub Desktop.

Select an option

Save kylc/14e93f5e8c8346b6da53ed6ea109e332 to your computer and use it in GitHub Desktop.
#!/usr/bin/env -S jank -I/usr/lib/jvm/java-21-openjdk-amd64/include -I/usr/lib/jvm/java-21-openjdk-amd64/include/linux -L/usr/lib/jvm/java-21-openjdk-amd64/lib/server -ljvm run
(ns clojure-interop)
(cpp/raw "
#include <jni.h>
JavaVM *vm;
JNIEnv *env;
std::string jvm_clojure_eval(const std::string code) {
if (vm == nullptr) {
JavaVMOption options[1];
options[0].optionString = \"-Djava.class.path=clojure-1.12.1.jar:spec.alpha-0.5.238.jar:core.specs.alpha-0.4.74.jar\";
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_21;
vm_args.options = options;
vm_args.nOptions = 1;
vm_args.ignoreUnrecognized = JNI_FALSE;
JNI_CreateJavaVM(&vm, (void **)&env, &vm_args);
}
jclass clojure_clazz = env->FindClass(\"clojure/java/api/Clojure\");
jstring jstr_core = env->NewStringUTF(\"clojure.core\");
jstring jstr_eval = env->NewStringUTF(\"eval\");
jstring jstr_read_string = env->NewStringUTF(\"read-string\");
jmethodID var_method = env->GetStaticMethodID(clojure_clazz, \"var\", \"(Ljava/lang/Object;Ljava/lang/Object;)Lclojure/lang/IFn;\");
jobject eval_var = env->CallStaticObjectMethod(clojure_clazz, var_method, jstr_core, jstr_eval);
jobject read_var = env->CallStaticObjectMethod(clojure_clazz, var_method, jstr_core, jstr_read_string);
jclass ifn_clazz = env->FindClass(\"clojure/lang/IFn\");
jmethodID ifn_invoke_method = env->GetMethodID(ifn_clazz, \"invoke\", \"(Ljava/lang/Object;)Ljava/lang/Object;\");
jstring code_jstr = env->NewStringUTF(code.c_str());
jobject invoke_read_string_result = env->CallObjectMethod(read_var, ifn_invoke_method, code_jstr);
jobject invoke_eval_result = env->CallObjectMethod(eval_var, ifn_invoke_method, invoke_read_string_result);
jstring jstr_pr_str = env->NewStringUTF(\"pr-str\");
jobject ifn_pr_str_method = env->CallStaticObjectMethod(clojure_clazz, var_method, jstr_core, jstr_pr_str);
jobject invoke_pr_str_result = env->CallObjectMethod(ifn_pr_str_method, ifn_invoke_method, invoke_eval_result);
return std::string(env->GetStringUTFChars((jstring)invoke_pr_str_result, NULL));
}
")
(defmacro jvm-eval [& body]
`(->>
(pr-str (quote (do ~@body)))
(cpp/jvm_clojure_eval )
(read-string)))
(println "Hello from jank" (clojure-version))
(println "----")
(->>
(jvm-eval
'("A list" "returned from" "JVM Clojure"))
(pr-str))
(jvm-eval
(println "Hello from Clojure" (clojure-version))
(println "Running on java" (System/getProperty "java.version"))
(println "The date is" (java.util.Date/new))
(import [javax.swing JFrame JButton])
(let [frame (JFrame. "Hello")
button (JButton. "Swing in jank?")]
(.add frame button)
(.pack frame)
(.setVisible frame true))
(Thread/sleep Long/MAX_VALUE))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment