Skip to content

Instantly share code, notes, and snippets.

@jamesdavidson
Created April 16, 2025 00:24
Show Gist options
  • Save jamesdavidson/d8edca06d83e2786c87dbcd755465906 to your computer and use it in GitHub Desktop.
Save jamesdavidson/d8edca06d83e2786c87dbcd755465906 to your computer and use it in GitHub Desktop.
ClojureJVM repl inside .NET via IKVM
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="IKVM" Version="8.10.3" />
</ItemGroup>
</Project>
using java.net; // yes this is weird, it is IKVM magic
var homeDir = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
var workDir = Environment.CurrentDirectory;
var urls = new URL[] {
new URL($"file:{homeDir}/.m2/repository/org/clojure/clojure/1.11.1/clojure-1.11.1.jar"),
new URL($"file:{homeDir}/.m2/repository/org/clojure/core.specs.alpha/0.2.62/core.specs.alpha-0.2.62.jar"),
new URL($"file:{homeDir}/.m2/repository/org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218.jar"),
};
var classLoader = new java.net.URLClassLoader(urls);
var RT = classLoader.loadClass("clojure.lang.RT");
var rtInitSignature = "public static void clojure.lang.RT.init()";
var rtInit = RT.getMethods().Where(m => m.ToString() == rtInitSignature).First();
java.lang.System.setProperty("clojure.server.repl","{:port 5555 :accept clojure.core.server/repl :server-daemon false}");
java.lang.ClassLoader previous = java.lang.Thread.currentThread().getContextClassLoader();
java.lang.Thread.currentThread().setContextClassLoader(classLoader);
try
{
rtInit.invoke(null);
} finally {
java.lang.Thread.currentThread().setContextClassLoader(previous);
}
Console.Out.WriteLine("listening on 5555, ctrl+c to exit");
// rlwrap nc localhost 5555
// (require '[clojure.walk :as walk])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment