Hecl Java Integration

Yesterday, I took the Java integration I’d been building into the Hecl Android port, and moved it into its own directory, so now it’s built in to the command line/j2se (non JavaME) version of Hecl for people to experiment with. Here’s a slightly modified version of my posting on the subject:

I created a java/ subdirectory with an org.hecl.java package that does a few things. The core of the system is in JavaCmd and Reflection. The first creates commands out of Java classes. It utilizes, obviously, the reflection stuff in Reflection. Both are, at the moment, sort of hacky and tentative, but work. For instance, I checked in this bit of test suite today:

test java-2 {
   java java.util.Hashtable ht
   set hasht [ht -new {}]
   $hasht put foo "bar"
   $hasht get foo
} {bar}

The ‘java’ command takes a class, and string, and creates a new Hecl command ‘ht’ that is tied to the Hashtable class.

ht -new {} (could have been -new [list]) is how we call the constructor. After this, $hasht points to a Hashtable, and we can utilize its methods. Up to a point, at least – there have to be mappings in Reflection to deal correctly with types. For instance, there isn’t a mapping for Enumeration right now, so calling the
.keys() method wouldn’t do the right thing.

There are some more bits and pieces of magic:

  • Static methods are called like this:

      java java.lang.System sys
      sys gc
    

    Which calls System.gc().

  • Static fields, for now, are called like this, although once again, I’m still thinking about the syntax:

      sys -field err
    

    Which is of course System.err

  • In addition to -new, when you instantiate an object, you can pass in things like -text "foo", and that will attempt to call setText("foo"). This is a convenient way, in Android, at least, of setting up an object from within Hecl, without requiring the use of the XML layout files.

  • Furthermore, in order to deal with constants in a convenient way, something that’s reasonably common in certain types of API’s (like Android), the following pieces of code are equivalent:

      layout.setOrientation(LinearLayout.VERTICAL);
      $layout setorientation VERTICAL
    

    What’s happening in the Hecl code is that VERTICAL is looked up in the context of the class that’s calling it, so as to avoid having to do [layout -field VERTICAL] to fetch the value. This won’t work everywhere, and I suppose it could be criticized as too much ‘magic’. Naturally, these sorts of things will evolve as the code does, and survive if they’re useful and don’t create problems, or die out if they cause bugs and aren’t utilized.

There are some open issues with the ongoing work:

  • I like the API for already instantiated objects, but I’m not 100% wedded to the idea of -new for instantiation. The fact that it takes a list is also a bit tricky, because if you want to do something like construct an argument to be passed in, you might end up with something like this:

      callback -new [list [list SelectDemo $spinner]]
    

    which I don’t find all that pleasant. You can’t just do -new [list
    SelectDemo $spinner]
    because then it thinks it’s got two arguments,
    when it really only has one, which happens to be a list.

  • The APIs created like this tend to follow Java pretty closely, for obvious reasons, and can be a bit verbose at times. I’m still thinking about this. One idea might be to provide Hecl wrappers that make common operations easier.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s