Sneaking Clojure in - Part 2

23 Feb 2017

I ended up turning to a Clojure REPL to solve an issue in that project I totally didn’t sneak Clojure into before and realized I did some things the hard way last time.

First up: you don’t need to create and compile a Java class from Clojure to call into Clojure code from Java. If I had actually read the Java Interop reference guide on Clojure.org, I would have noticed that there’s a section on calling Clojure from Java. It’s much, much easier.

If I define this namespace/function:

(ns project.util)

(defn get-my-thing []
  {:my :thing})

I can call it like so:

// In Java code:

// First, find the require function. Then use it to load the project.util namespace
IFn require = Clojure.var("clojure.core", "require");
require.invoke(Clojure.read("project.util"));

// After project.util is loaded, we can look up the function and call it directly.
IFn getMyThing = Clojure.var("project.util", "get-my-thing");
getMyThing.invoke();

Easy peasy. I don’t have to jump through the gen-class hoops, and bonus! I don’t have to compile my Clojure code ahead of time. I just need to make sure the source files are on the class path.

You should of course compile your Clojure code if you’re distributing an application built on it. It’ll load faster, plus you might not want it readable.

What I specifically didn’t want to hook into that project that I totally wasn’t sneaking Clojure into is a REPL: I want to be able to poke directly at the application’s state while it’s running. To do that, I’ll need to make sure that tools.nrepl is available on the classpath, and require/launch it from within the application.

I could probably use Clojure 1.8’s socket server repl instead, but I plan on using Cider to talk to it, so nrepl’s a better choice.

In Java code:

public static void launchNrepl(int port) {
  try {
    IFn require = Clojure.var("clojure.core", "require");
    require.invoke(Clojure.read("clojure.tools.nrepl.server"));

    // Note: passing "::" as the :bind parameter makes this listen on all interfaces.
    // You might not want that.
    IFn startServer = Clojure.var("clojure.tools.nrepl.server", "start-server");
    startServer.invoke(Clojure.read(":bind"), "::", Clojure.read(":port"), port);
  }
  catch (Exception e) {
    // log the error
  }
}

In my theoretical project where I totally didn’t do this I also load in a namespace of helper code I’ve written to wrap around the Java objects we already have written.


Which of Apple's game technologies can I use?

08 Feb 2017

Writing this down here because I didn’t see an easy reference to it anywhere and I just took the time to figure it out.

I’m starting a new game-ish thing and figuring out what I want to build it in. What technologies can I use? In particular, I’m looking at:

Read more...


Sneaking Clojure into an older Java project

18 Jan 2017

Now I’m not saying I did this, but if I was going to do it and took notes for future reference, this is how I’d sneak some Clojure code into an older, Ant based Java project.

Read more...


Getting started with groov's APIs

04 Jan 2017

I’m a developer on groov, and our just released R3.3a version includes a new place to store arbitrary data (we call it the Data Store), and our first public API: a way to get data in and out of those Data Stores. We also included support for CORS, so you can use it from a web page as well.

CORS can be a bit confusing, and on top of that a bunch of our customers use self-signed SSL certificates on their groov instances, so I thought I’d write down a getting started guide to get people past all of those bumps.

Read more...


Climate change and the 2016 Election

13 Sep 2016

I’ve always been registered independent, despite voting for the Democratic party most of the time. I don’t like that people identify as Democrat vs. Republican, or Liberal vs. Conservative, or whatever. I prefer looking at the policies of candidates, what issues they find important, and what character they show. Given that, I don’t care what label they choose for themselves.

Read more...