Using Java frameworks from Clojure

17 views
Skip to first unread message

Hans Hübner

unread,
Oct 6, 2008, 3:21:03 AM10/6/08
to Clojure
Hi,

for a project, I would like to use a Java framework that exposes a
very Javaesque API, with dozens of classes that need to be
instantiated or used and with several interfaces that one needs to
implement in order to be called back by the framework. The interfaces
are particularily cumbersome, as most of them only specify one or two
methods. Now, exposing the innard of this library to my application
is something I'd like to avoid, as the object oriented API does not
mix well with a purely functional development style. On the borders
of my application, though, I will have to cope with the classes and
objects.

How do others approach this kind of problem? Are you just ignoring
the functional vs. object oriented mismatch and access Java objects
from everywhere? Do you use hand-written wrappers around the
libraries? Tools?

In my case, most of the interfaces are trivially small (provide only
one or a few member functions to be called back by the framework). A
macro wrapping up clojure/proxy a little nicer will do the job,
although I would still like to provide purely functional interfaces
and have the interface mechanics be hidden from the Clojure
application. For the larger classes of the framework, it would be
useful to somewhat mechanically translate objects in hash tables, so
that getters can be conveniently called.

Certainly, I would like to spare myself having to type in the names of
dozens of accessor functions and corresponding hash table keys. What
would be a good approach to automating this? Use reflection on the
classes and generate the functional interface? Would that be a
function called at the REPL that results in a file that is manually
edited, or would one do that at compile time and just generate a
richer and more complete interface?

Any thoughts on this would be greatly appreciated.

Thanks,
Hans

James Reeves

unread,
Oct 6, 2008, 8:34:50 AM10/6/08
to Clojure
On Oct 6, 4:21 am, Hans Hübner <hans.hueb...@gmail.com> wrote:
> for a project, I would like to use a Java framework that exposes a
> very Javaesque API, with dozens of classes that need to be
> instantiated or used and with several interfaces that one needs to
> implement in order to be called back by the framework.
> ...
> How do others approach this kind of problem?  Are you just ignoring
> the functional vs. object oriented mismatch and access Java objects
> from everywhere?  Do you use hand-written wrappers around the
> libraries?  Tools?

I don't think there's any one answer to this, as it really depends on
the library. I've written a functional wrapper around the Java servlet
interface, and I use a number of techniques. Which API in particular
are you trying to convert?

- James

Hans Hübner

unread,
Oct 6, 2008, 5:58:11 PM10/6/08
to Clojure
On 6 Okt., 10:34, James Reeves <weavejes...@googlemail.com> wrote:
> On Oct 6, 4:21 am, Hans Hübner <hans.hueb...@gmail.com> wrote:
>
> > for a project, I would like to use a Java framework that exposes a
> > very Javaesque API, with dozens of classes that need to be
> > instantiated or used and with several interfaces that one needs to
> > implement in order to be called back by the framework.
> > ...
> > How do others approach this kind of problem?  Are you just ignoring
> > the functional vs. object oriented mismatch and access Java objects
> > from everywhere?  Do you use hand-written wrappers around the
> > libraries?  Tools?
>
> I don't think there's any one answer to this, as it really depends on
> the library.

Certainly so - I am not looking for all-for-one solutions, but I would
like to learn what others think about this and how they handle the
functional/object-oriented mismatch. To me, this is a little ironic
as I have spent a good portion of my professional life writing object
wrappers around functional APIs, and now suddenly I need to do it the
other way round :)

> I've written a functional wrapper around the Java servlet
> interface, and I use a number of techniques. Which API in particular
> are you trying to convert?

The API I am working with is xlightweb, an asynchronous HTTP client/
server framework based on xSocket. API docs are at
http://xlightweb.sourceforge.net/core/apidocs/2_1/

Any thoughts would be greatly appreciated.

Thanks,
-Hans

James Reeves

unread,
Oct 6, 2008, 9:47:27 PM10/6/08
to Clojure
On Oct 6, 6:58 pm, Hans Hübner <hans.hueb...@gmail.com> wrote:
> The API I am working with is xlightweb, an asynchronous HTTP client/
> server framework based on xSocket.  API docs are athttp://xlightweb.sourceforge.net/core/apidocs/2_1/
>
> Any thoughts would be greatly appreciated.

I've been thinking about this, and I think I have a few points of
advice to give.

The most important thing I can think of is to remember that your
wrapper doesn't have to be comprehensive. Clojure has various
functions in the standard library to handle regular expressions, but
they don't attempt to be a complete replacement for working with
Pattern and Matcher objects. Falling back to Java classes is okay for
complex and unusual cases.

So keep it simple, and write wrappers for the common use-cases. Try to
stay functional, and take full advantage of all the standard Clojure
data structures, the Clojure standard library, and of first class
functions and macros.

For instance, here's a cut down version of some example code from the
xlightweb docs:

HttpClient httpClient = new HttpClient();

IHttpResponse response = httpClient.call(new GetRequest("http://
www.gmx.com/index.html"));
System.out.println(response.getStatus());

BlockingBodyDataSource bodyChannel = response.getBlockingBody();
System.out.println(bodyChannel.readString());

httpClient.send(new HttpRequestHeader("GET", "http://www.gmx.com/
index.html"), respHdl);

httpClient.close();

A more Clojure-like way of writing it might be:

(with-open client (new HttpClient)
(let [response (get-url client "http://www.gmx.com/index.html")]
(.printLn *out* (read-body response)))
(get-url client "http://www.gmx.com/index.html" handler-function))

Although, since this is HTTP, you're not actually keeping any
connections open, unless they happen to belong to the same domain. So
maybe you could cut out the client altogether, by generating a new one
each time:

(let [response (get-url "http://www.gmx.com/index.html")]
(.printLn *out* (read-body response)))
(get-url "http://www.gmx.com/index.html" handler-function))

Really, it depends what you think you'll be using the library for most
often, and what other people will want to do. Maybe most of the time
all people want is the body of the HttpResponse, so:

(.printLn *out* (read-url "http://www.gmx.com/index.html"))

So long as people can go back and use the Java API to do the complex
stuff, I figure the best way to approach wrapper libraries is to make
it as easy and as straightforward as possible for people to start
using it.

- James

Hans Huebner

unread,
Oct 6, 2008, 10:51:40 PM10/6/08
to clo...@googlegroups.com
On Mon, Oct 6, 2008 at 17:47, James Reeves <weave...@googlemail.com> wrote:
> The most important thing I can think of is to remember that your
> wrapper doesn't have to be comprehensive. [...]

> So long as people can go back and use the Java API to do the complex
> stuff, I figure the best way to approach wrapper libraries is to make
> it as easy and as straightforward as possible for people to start
> using it.

My use case for this library involves a lot of the more complex stuff,
so my wrapper actually needs to be comprehensive enough. I will need
all asynchronous functionality that I can find, and I will need a lot
of the methods that the classes provide. Rather than just moving
forward with my application and extend the wrapper as needed, my plan
therefore is to first invest enough into the infrastructure so that I
won't have to return to it again and again while writing application
code, maybe correcting ad-hoc wrapper design decisions and having to
redesign things when I was hoping to make progress on the application.

Your simple example, creating a wrapper around the http client, really
shows off the problem quite well: True, for most use cases, people
will just have the library fetch the given URL and be done with it.
But what about query parameters, how would the be usefully
represented? POST-requests with bodies? What about cookies? If one
is lucky, one finds good on the fly solutions, or can get away with a
few native API calls intermixed with wrapper invocations. If one is
not, there will be existing code using an existing API that needs to
be rewritten, and maybe even users that depend on the simplicistic
design and now somehow expect you to support it.

Thus, I somehow need to either transform much of the whole thing into
a functional library, or I need to use the Java API from my
application, maybe applying a little syntatic sugar here and there.

For the callback interfaces, just using 'proxy' will propably be the
easiest, although I will propably go with a 'proxy-fns' macro that
expect fns instead of function bodies for the handler - any sizeable
application will dispatch to a named function from the interface
anyway, and repeating the argument names in the invocation of the
function seems redundant. Maybe 'proxy' should work like this in the
first place. http://paste.lisp.org/display/68075 has an example of
what proxy-fns would do.

For object property getters and setters, I would like to be able to
read properties using a keyword as the key, similar to hash table
access, instead of having to invoke a getter. I would like this to be
both lazy and fast at the same time, and as getters might have
arbitary performance characteristics, creating a hash table on the fly
and populate it by calling all the getters would not be the right
thing (also, there would be suprising caching in the wrapper). Thus,
what I propably want is a mechanism that establishes the mapping
between a keyword and a getter (and setter) method of the class at
compile time. Is that a sensible approach?

Again, thank you, James, for your input. Your and any additional
input is greatly appreciated.

-Hans

James Reeves

unread,
Oct 6, 2008, 11:27:24 PM10/6/08
to Clojure
On Oct 6, 11:51 pm, "Hans Huebner" <hans.hueb...@gmail.com> wrote:
> Your simple example, creating a wrapper around the http client, really
> shows off the problem quite well:  True, for most use cases, people
> will just have the library fetch the given URL and be done with it.
> But what about query parameters, how would the be usefully
> represented?  POST-requests with bodies?  What about cookies?

I'm not sure if this helps, but in my Compojure project, I build up
response objects based on the type of the object being returned.

(GET "/" 200) ; returns HTTP code 200
(GET "/" "Hello") ; adds to the response body
(GET "/" {"X-Header" "something}) ; adds a header
(GET "/" (new Cookie ...)) ; adds a cookie to the response
(GET "/" (new File ...)) ; streams a file to the response
(GET "/" [200 {"X-Test" "Foo"} "Hello"]) ; vector combines multiple
effects

Maybe you could take a similar approach with your xlightweb interface?

(post-url "http://example.com" {:name "blah"} (new Cookie ...)
callback-function)

> For object property getters and setters, I would like to be able to
> read properties using a keyword as the key, similar to hash table
> access, instead of having to invoke a getter.  I would like this to be
> both lazy and fast at the same time, and as getters might have
> arbitary performance characteristics, creating a hash table on the fly
> and populate it by calling all the getters would not be the right
> thing (also, there would be suprising caching in the wrapper).

This could be useful. I've written some functions that find all of an
object's getters and use them to populate a hash-map, but it would be
nice to have a direct proxy onto the object.

- James
Reply all
Reply to author
Forward
0 new messages