Generating reflection-free Java wrappers

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.

4 Likes

This is great! Thanks for making a proper project out of it. I have enough projects to manage already so you are welcome to run with this one.

1 Like

Thanks! I’ll see how far I get with it.
I’m currently trying to work out the best way to support vararg methods, which is turning out to be a bit tricky, with lots of edge cases… but hopefully I’ll get something working soon.
Then I want to use it to generate a Clojure wrapper around Apache Spark, which should start exercising it pretty well, and probably throw up lots more issues to smooth out.

Hi @plexus,
I’ve been making some progress with this, and have vararg methods pretty much working now, but I have a quick question: Is there a reason that you let-bind the type-hinted arguments and then call the java method with them, as opposed to just type hinting in the method call?
I.e., when you do something like:

(let [this ^SomeClass this
      a (long a)]
  (.method this a))

could that be replaced with:

(.method ^SomeClass this (long a))

I think that would simplify the macro logic somewhat, but don’t want to break something subtle if that extra level of let binding is actually needed.

I can’t immediately remember if there was a specific reason why I did it this way. At first glance either approach should work.

OK thanks, I’m going to try simplifying it. Hopefully with *warn-on-reflection* set, I should notice if it breaks anything.