Thoughts On Java 8 Functional Programming (and also Clojure)

After working with Java 8 for the better part of a year, I have to say I find its new “Functional” features both useful and aggravating at the same time.  If you’ve used true functional programming languages (or you use them on your own personal projects while being forced to use Java at work), you’ll find yourself comparing each of Java 8’s new functional constructs with those in say Clojure, Scala, or Haskell, and you’ll inevitably be dissapointed.

Case in point: Java 8 includes an “Optional” container which wants you to treat it like a monad.  Now, I find it useful, but of course it’s nowhere near as nice as Scala’s “option” or Haskell’s “maybe”:

For example, at work I found myself having to refactor an older part of the code base.  Attempting to think “Functionally” I decomposed this block of fairly typical Java (simplified with class and variable names changed, of course)  :

arrivals = new HashMap<>();

for (Delivery delivery : route.getDeliveries()) {
    Truck deliveryTruck;
    try {
        deliveryTruck = delivery.getPackage().getTruck();
    } catch (NullPointerException ex) {
    //Log the error
    if (deliveryTruck == null || arrivals.containsKey(deliveryTruck)) {

    Location truckLoc;
    try {
        truckLoc = deliveryTruck.getLocation();
    } catch (NullPointerException ex) {
        //Log error
    arrivals.put(deliveryTruck, new TimeAndLocation(delivery.getDeliveryTime(), truckLoc));

Into this:

public Optional getArrival(Delivery delivery){
       return delivery.getPackageOpt()
            .map((t) -> new TimeAndLocation(delivery.getDeliveryTime(), t.getLocation()));

public List getArrivalsFoRoute(Route route){
        Map<Truck, TimeAndLocation> arrivals = new HashMap<>();
        for (Delivery delivery : route.getDeliveries()){
            Optional truck = delivery.getPackageOpt().flatMap(Package::getTruckOpt);
            truck.flatMap((t) -> getArrival(delivery)).ifPresent((a) -> arrivals.put(truck.get(), a));
        return new ArrayList<>(arrivals.values());

These two functions have the advantage of being easier to reason about and trivial to unit test individually.  Java 8’s Optional monad eliminates the possibility for NullPointerExceptions, so there is no longer an excuse for the evil “`return null;“` when you can just as easily do “`return Optional.empty();“` 😉

Now, the bad parts:  Optional inherits from Object.  That’s it.  It’s really just a Java container class.  Much nicer (and more useful) would have been a hierarchy of Monadic types (Either, an “Exception” monad, etc) all implementing a common Monad interface.  But alas, no.

That said, this code is fairly functional, if ugly.  True functional programming languages make things like this easier to express (and easier to express elegantly).

Off the top of my head, in clojure you could do something like this:

(defn arrival [delivery] {:datetime (get-dtime-M delivery) :location (get-truck-M delivery)}) 

(defn arrivals [route] (cat-maybes (map #(arrival %) (get-deliveries route))))

Which I think everyone would agree is easier to read.  Now, I’m making use of Monads here, which aren’t really “built-in” to the language, but Clojure is extensible enough (macros, etc.) that adding them is easy.  Personally, I rather like this library:   So, if we assume our get-dtime-M and get-truck-M functions return “maybe” monads (which contain either a ‘Just x’ or a ‘Nothing’), we get the same advantage as Java 8’s Optionals (no null checks littering our code).  We can also wait to evaluate the value of our Maybe monads till the end of our processing (The cat-maybes function does that, pulling only the ‘Just’ values from our array of Maybe monads generated by the map function).

In addition to Maybe, The cats library exposes many other useful monadic types (and you can create your own as well) which have no Java 8 counterpart.

Of course, If you really want to explore the full power of Monads, I’d suggest learning some Haskell — then come back to Clojure (or Scala, I suppose) when you need to write some real-world software 🙂

Spring, OSGi, and dropped services

My current job has had me working with a number of technologies with which I was completely unfamiliar when I started. The Spring Framework and OSGi are two such technologies that I believe I’ve become fairly comfortable with, yet still manage to throw something new and/or bizarre at me every once in a while.

My latest issue involved convincing Spring to register an OSGi service. Seems simple enough, Spring offers pretty good OSGi support, and one can usally register a service by doing something like this:

<bean id="theService" class=""/>
<osgi:service ref="theService" interface=""/>

Pretty straightforward.  It creates a bean called theService, then uses that bean to publish a service.  Spring automagically takes care of registering the new service in your container’s OSGi service registry (in my case, I’m running Virgo).  I’ve done something similar to this many times with no problem.  However, this time I needed to do something slightly more complex:

<osgi:reference id="someOtherService" 

<bean id="beanA" class="">
    <property name="otherService" ref="someOtherService"/>

<bean id="beanB" class="">
    <property name="beanA" ref="beanA"/>

<osgi:service ref="beanB" interface=""/>

Now for the problem… my “beanB” service was NOT being published.  I tried everything I could think of, switched my beans to constructor injection (no idea why that should work), verified that both my “beanA” and “beanB” beans were being created, etc., and everything looked fine… but the service wasn’t showing up!  Checking the logs… I found nothing.  No exceptions, no warnings, just the lack of the usual log message Spring generates when it publishes a new service.

So what was going on?  By using the good ‘ol “comment things out until it works, then reverse the process until it breaks” method of debugging, I identified the first line of my services.xml file, the osgi:reference tag, as the source of the problem.

The osgi:reference tag deontes a service that is consumed, rather than published.  BeanA uses that service, and this is where the problem comes in.  That otherService was something I had yet to implement.  It wasn’t strictly necessary for “beanA” to work, and beanA was being initialized just fine, but the lack of “someOtherService” in the OSGi service registry was triggering an obscure feature of Spring (or at least it was obscure to me, it’s entirely possible I’m the last Spring/OSGi user on Earth to learn about this).

I found a description of the problem, and its solution, in the spring documentation:

7.5. Relationship Between The Service Exporter And Service Importer
An exported service may depend, either directly or indirectly, on other services in order to perform its function. If one of these services is considered a mandatory dependency (has cardinality 1..x) and the dependency can no longer be satisfied (because the backing service has gone away and there is no suitable replacement available) then the exported service that depends on it will be automatically unregistered from the service registry – meaning that it is no longer available to clients. If the mandatory dependency becomes satisfied once more (by registration of a suitable service), then the exported service will be re-registered in the service registry.
In other words, it doesn’t matter that my beanB service didn’t depend directly on someOtherService, the fact that an unpublished service was somewhere in beanB’s chain of dependencies meant that Spring was simply going to refuse to publish beanB as an OSGI service.  It’s easy to imagine a rather hilarious cascade of dropping services depending on how you have beans and OSGi services wired together.
The solution lies in an option to the osgi:reference tag, namely “cardinality.”  From the Spring docs:
The cardinality attribute is used to specify whether or not a matching service is required at all times. A cardinality value of 1..1 (the default) indicates that a matching service must always be available. A cardinality value of 0..1 indicates that a matching service is not required at all times (see section for more details).

So, changing the first line in my xml to this:

<osgi:reference id="someOtherService" 
    interface="" cardinality="0..1"/>

fixed the issue.  In my opinion the default cardinality should be “0..1”, rather than “1..1”.  At the very least, if a mandatory service reference cannot be satisfied, some sort of conspicuous error log message ought to be generated.  But anyway, if you were having a similar problem and found your way here, hopefully I just saved you several hours of pain, anguish, and misery.