Generating reflection-free Java wrappers

I don’t understand how you would disambiguate ambiguous types? My understanding is that type hints are only needed when it just simply isn’t possible to know, because there are multiple possibilities and only the programmer knows which one is needed.

Like try it on say:

public class Foo {
    public String bar(int a) {
        return "a";
    public int bar(String a) {
        return 10;
    public String bar(String a) {
        return "b";

I like where this is going!

I made something similar for mapping to and from data beans – could be a nice compliment for some APIs:

1 Like

In this case you would get

(defn bar [^Foo this g__123]
    (instance? java.lang.Integer g__123)
    (.bar this ^java.lang.Integer g__123)

    (instance? String g__123)
    (.bar this ^String g__123)))

(which still needs to be improved to prevent unnecessary boxing)

Which does have some type checks but it doesn’t reflect on the class and method, which is a big difference. In this case your return types differ, which is why there is no return type hint. But like I said I think that is a pretty rare scenario.

Oh interesting… Is that actually better then reflection? In terms of performance and compatibility with graalVM?

Also, what about scenarios where there are multiple concrete classes or interfaces?

I do believe it’s better. With reflection you have to at runtime

  • get the class of the object you’re calling a method on
  • list its methods
  • filter them by arity and type of the arguments
  • filter them by visibility
  • find the one that is left, invoke it through the reflection API

in the above cases each call to .bar is unambiguous, the compiler can know which one it is, and emit byte code that calls it directly.

Also, what about scenarios where there are multiple concrete classes or interfaces?

When you create the wrapper you need to pick the class or interface you’re wrapping, only objects that are assignable to that type will be able to be used with those generated functions. If there’s an interface then you should prefer that over the concrete object.

Nice! I never had to deal much with the Bean stuff (except for a project in uni involving enterprise java beans, still gives me the shivers), but this looks really useful.

Many Java APIs are replete with them, if only to model data with. This library was motivated by using the AWS SDK from Clojure, for example. (Today I just use Cognitect’s AWS lib for this case.)


I see. Ya, actually that’s pretty neat, I think you’re on to something.

Would be nice if you could also have it so the macro throws when there is ambiguity, and allows you to explicitly type hint them. That would achieve maximal performance.

Or we should benchmark the different approach. Cause it is true the JIT might be able to optimize the instance of away.

I like the idea of just lifting functions into a namespace (inverting the OOP stuff basically).
I did something like this out of necessity, but for a narrower use-case: selectively exposing private fields with accessor functions that had no business being private (from jfreechart I think, maybe piccolo2d). I came off of that thinking "why isn’t this the default for interop? just have a library of functions automatically generated. Then you went and did it, hah!

1 Like

This is great, data hiding can be so overrated :slight_smile:

Does this still work on Java 9+?

This seems pretty cool and exactly what I need at the moment!!! :smile:

Nice! Do let me know what you think once you’ve managed to use it a bit!

I haven’t tested it, but it’s definitely on the way out due to the breaking changes they introduced (you know…not allowing you to be a consenting adult in favor of modularity - silliness IMO).

It should work (with warnings and/or jvm startup flags) for the time being, but at some point using reflection to crack open object vaults will be verboten. Thankfully, I’m likely to still be on java 1.8 by then due to the nature of my work :wink:

This also reminds me of an old lib I wrote to get better transparency of Java objects: gavagai. It creates objects that expose a lazy map-like interface for java beans and bean-like objects in a recursive way. You can customize precisely what you want to expose and how you optionally want to transform values. It emits functions that are annotated to do no reflection on access.

By the way, it has had no commit in over 4 years, and still works perfectly with clojure 1.10.1 and Java 12, kudos for stability!

1 Like

This would be a great foundation for implementing datafy/nav for all kinds of objects.


this looks pretty interesting. I have done a similar-ish thing for java.time, the output of which is in this lib: It’s a bit different in that it is .cljc and has to deal with a few irregularities in the underlying js impl of java.time.

I also found type hinting a bit of a struggle and so quite a bit is still tbd… I might leverage some of your code to help with that :-).

Btw I had a quick go with e.g. java.time.ZoneId and see the overloaded ‘of’ method is missing the (String,bool) version.

@henry_w where are you seeing this ZoneId/of method, I can only find (String) and (String,Map) versions.

ah sorry, it has default visibility, not public. so not expected

Hey, so I have taken bits of this to generate better type hinting in my java.time lib - thanks again.

One case that is still problematic is java.time.Year#isLeap. There’s a static and non-static versions with the same name - urghh. it remains special-cased for now.

btw I’ve been referring to the java.time lib as a ‘vacuum wrapper’, as in this kind of thing - in case you’re looking for names/analogies.

This is really cool! I’ve been thinking of doing something similar for a while (not necessarily the reflection-free part, although that is definitely a bonus, but automatically generating idiomatic Clojure wrappers around Java APIs) but hadn’t got around to it yet.
I’ve been trying it out, and have started making some changes to get it working for me:

  • I’ve fixed a bug with way arguments are counted: it wasn’t consistent between static/non-static methods, so would fail if you have a class with e.g. public void foo(int a) & public static void foo(int a, int b)
  • I’ve started looking into adding support for vararg methods, as I will need that

I hope you don’t mind that I’ve created a github repo (forked from your gist, so it’s clear what code is yours) to develop it further, here. As you’ve done most of the hard work setting up the foundations, it would be great to be able to make use of that, but I don’t want to be seen as trying to take credit for your work - so let me know if you want me to take it down, or make any changes to clarify the status.