Daily Archives: 19/05/2012

Beyond DirectJNgine 2.1 (II)

In my first entry about what to add to DJN 2.1+, I though I had a pretty complete list of “important” features. But I forgot this one…

Important features

  • Be able to receive hererogenous data in Java methods

    What do I mean? Sometimes it happens that you really truly have to handle data of an unknown type, much like myFunction does:

    MyRemoteThing.myFunction( 55, .... );
    MyRemoteThing.myFunction( "hello", ... );
    MyRemoteThing.myFunction( {value1:33, value2:"Unknown"}, ... );
    MyRemoteThing.myFunction( [5, "bye"] );
    MyRemoteThing.myFunction( [1, "anyway", {value1:33, 
                                 [33, null, 5], value2:"Unknown"}], ... );

    Here, myFunction has to handle a number, then a String, an object, then an array, and finally an array containing numbers, strings and even an object that contains itself another array. Yuk!

    How are we going to handle this monster in the Java side? Well, up until now you had to write a method to receive the almost raw json (a JsonArray parameter), as generated by Gson, and process it on your own.

    My proposal is to write a Java method with this signature:

    public void myFunction( Object param ) {
      // ...

    Now, what will DJN pass to the poor myFunction method? Let’s dive into each case:

    • myFunction( 55, ...)

      Here param will be a Double set to 55.0.

      Not an Integer, mind you, because we need to honour the fact that json numbers can have fractional part. There is no separated integral numeric type in json.

    • myFunction( "hello", ... )

      Here param will be a String set to "hello".

    • myFunction( {value1:33, value2:"Unknown"}, ... )
      Here param will be a Map<String,Object> with two entries, a "value1" key with a Double value set to 33.0, and a "value2” key with a String value set to "unknown".

    • myFunction( [5, "bye"] )
      Here param will be an array of objects (Object[]), with two elements: a Double set to 5.0 and a String set to "bye".

      I think that arrays will be used most of the time to pass elements of the same type: always numbers, always strings, etc.

      This contrived example just illustrates the whole potential -that includes potential for mess, of course.

    • myFunction( [1, "anyway", {value1:33, [33, null, 5], value2:"Unknown"}], ... )

      You’ve got the idea by now. Here the method will receive an array of objects, the third one will be a Map<String,Object>, etc.

      I do not think this last scenario will be very popular, but it shows how far we can go if we need to.

    But this is *dirty* Java…!


    Yes, this function is not a very good Java-world citizen, what the hell does myFunction think it is doing? Since when is working with Object a good idea? Because an Object is just an alias for whatever, right?

    And, in fact, a very important goal for DirectJNgine was to provide and almost enforce a degree of type safety at the server side, and that’s why I have not implemented this kind of functionality up until now: if you write a server function that receives an Object, it will not work because DJN considers there is not much one can meaningfully do with whatever, so it almost forces you to devise a class that organizes your data.

    Even then, I provided the JSonArray backdoor to allow the server side to receive whatever, because sometimes you have very special needs.

    …so, why allow this level of exposure?

    Have I changed my mind? Is untyped data good nowadays?

    No, not at all. It just happens that my mind has expanded. Well, maybe I have changed my mind -but just a tiny bit 🙂

    Here is my reasoning.

    Firstly, having to handle the json itself is not too difficult, but neither is it very easy. For example, for moderately complex structures you will need a bit of recursion to process the JsonArray with the underlying json. I know people will like me better if I write that code for them.

    Secondly, a guy might tell me this: “ok, I understand you are making it difficult for me to mess with data in the whatever format. Limits can be good. But sometimes I inherit the mess. In fact, I’ve got that nice UI component from Joe: it allows end users to edit multiple items easily…but it will handle me data of whatever type. Sometimes the user will edit a string, sometimes a number, etc. And *I* don’t want to have to rearrange the data to make it fit a type-safe but uber-complex class I have to invent to make Java happy just once”.

    Well, that seems reasonable.

    Besides, one might think that, if there is a need to massage very complex data to make it amenable to complex processing, it might be better to massage it at the Java side, where you have all those Java utility libraries that have no Javascript equivalent. In that scenario, it might be better to pass raw data to the Java side and clean the mess there.

    That said, let me tell you that I still feel it will be bad style to allow highly unstructured data to get deep into the business core (unless it is just to be stored as-is and handled back the same way), and that most of the time you can be well served by defining a handful of helper data-only classes to structure the information.

    Yes, that’s me: I am a quality code bigot that enjoys Test Driven Development like there is no tomorrow.

    A pair of little details to take into account

    I expect two scenarios to be very common:

    1. Handling arrays, essentially acting as a collection of items of the same type, whatever that might be.
    2. Handling objects as bags of properties, probably of different types.

    To enforce those scenarios you will find it nice to be able to write your Java function so that it takes an Object[] (scenario 1) or Map<String,Object> (scenario 2), not a raw Object. That makes the intent clear and helps with type safety.

    Caveat emptor & more to come

    Of course, I’m just thinking aloud, though I would very much like to implement this given some spare time. Maybe in DJN 2.3.

    There are still other features that, if not important, would be nice to have. So a third entry about post 2.1 DJN future is guaranteed.