Skip Navigation

Inspect Java Objects with Clojure

Published: 2019-02-09


The more I work with Clojure, the more frustration I found to work with Java objects. Mostly, it feels an unnecessary process to go through the class definition to find the getter methods to access the data I want, especially when the data is buried under multiple layers of classes deep.

In this article, I’ll explain a recipe to create a graphical inspector UI to explore Java objects, frustration free! The key is to use the clojure.inspector for the visualization and for recursively converting Java beans to Clojure data structure.

Note: Thanks to reddit user @vvvvalvalval to point out Programming at the REPL: Data Visualization is also a great place to learn more about inspecting values in the REPL. I was inspired by it to write this article. If you are just starting to learn Clojure REPL, definitely check out the link first!

Tools - clojure.inspector and

On the official website, clojure.inspector is:

Graphical object inspector for Clojure data structures.

It provides three APIs: inspect, inspect-table, and inspect-tree. To differentiate them, the first thing to notice is that inspect and inspect-tree doesn’t have any assumption on the shape of the input data, while inspect-table assumes the data is sequential and its elements all have the same length. Secondly, inspect-tree creates a expendable tree to explore data if the data is hierarchical. Here are some examples below. We’ll be focusing more on inspect-tree in the rest of the article.

;; try this in your repl

(require '[clojure.inspector :as insp])
(def d [{:a "a1" :b "b1"} {:a "a2" :b "b2"} {:a "a3" :b "b3"}])
(insp/inspect d)
(insp/inspect-table d)
(insp/inspect-tree d)

The built-in clojure.inspctor namespace is very useful for exploring data and the interactive development for Clojure. Instead of printing everything down in the repl, using a graphical tool like this is a much superior experience, in my opinion.

Next question is, when we do interop with Java, Java objects doesn’t automatically become Clojure data types like clojure.lang.IPersistentMap. The built-in function bean is helpful. However, the time that I really need to inspect a Java object is usually when the object has too many layers of classes nested. In this case, I found the library is the right tool. is:

Functions for recursively converting Java beans to Clojure and vice versa. Future home of Java beans and properties support from the old clojure-contrib


To demonstrate, let’s setup a Java & Clojure polyglot project with Leiningen like this:

(defproject inspector "0.1.0-SNAPSHOT"
  ;; ...
  :dependencies [[org.clojure/clojure "1.10.0"]
                 [org.clojure/ "0.1.1"]]
  :source-paths      ["src/clojure"]
  :java-source-paths ["src/java"])

In order to make this work, we need to implement our Java class as a JavaBean. Here’s the Java class to inspect:

package inspector;

public class MyClass implements {
    private String name;
    private InnerClassA a;

    public MyClass() { = "MyClass";
        this.a = new InnerClassA();

    public String getName() {return;}
    public void setName(String name) { = name;}
    public InnerClassA getA() {return this.a;}
    public void setA(InnerClassA a) {this.a = a;}

    public static class InnerClassA implements {
        private String name;
        public InnerClassA() { = "InnerClassA";}
        public String getName() {return;}
        public void setName(String name) { = name;}

Now you can connect to the REPL and do:

;; Transform java object to clojure map
(-> (inspector.MyClass.)
;; {:a {:name "InnerClassA"}, :name "MyClass"}

;; The inverse works too if the JavaBean is implemented correctly
(->> {:name "hi" :a {:name "hey"}}
     (java/to-java inspector.MyClass))

;; Now you can use inpsect-tree to visualize the map
(-> (inspector.MyClass.)

Here’s the inspector GUI you’ll see: alt clojure inspector

Though, there’re some limitations, for one:

public class MyClass implements {
    // ...
    public MyClass getSelf() {return this;}
    // ...

In this case, you’ll find an StackOverflowError when calling java/from-java function. This is because all the get* methods are consider getter methods to access class member and were invoked recursively. In the example above, you just need to rename getSelf to returnSelf or any name without the “get” prefix to avoid the error.


Clojure is really great for:

  1. Transforming data (e.g., and
  2. Exploring data (e.g. clojure.inspector)

Using the simple recipe explained in the article, I found it more and more pleasant to do interop with Java in the Clojure world.

If you find this article helpful, please help me to share it!

This work is licensed under a Creative Commons Attribution 4.0 International License.