Feb 12, 2016

Dropwizard vs Spring Boot


In Java world there are 2 most wide spread solutions for JSON REST technology. In this post I’ll cover some aspects of them, that seems of most importance to me. 

Dependency Injection

With Spring, you are limited to Spring DI - quite complex and hard to debug. With Dropwizard, you can choose any DI you like. I was using Guice. But beware of using javax.inject annotations. Dropwizard v0.9.2. uses fresh release Jetty, that was build using HK2 DI library. So, using  general annotations with some other DI solution may result in strange behavior. For Guice-HK2 there are some bridge solutions, but using DI library specific annotations will save you from trouble.

Rest Api

I personally find JAX-RS specification not very convenient, maybe because I prefer single routes file and dislike annotating classes with @Path. Spring annotations for REST API are slightly better in this regard.

Configuration

Dropwizard offers once convenient way to configure everything - yml. With Spring you have as much flexibility as you can handle, and it makes server hard to maintain. I guess Dropwizard configuration is more in line with java values - there is single way to do it, simple, clear,maintainable. In case of issue you always know where to look.

Deployment

Dropwizard oriented on jar-deployment, standalone jetty. Spring can do both jar and war (for tomcat). It is arguable, but I consider multiple deployment options as a plus - it doesn’t complicate maintenance much, but can simplify support in case of running multiple applications.

Static Resources & Templates

Dropwizard offers quite simple way to mix pages and JSON API. If we will use angular on client side - it result in quite elegant solution with no tweaks. With Spring Boot I've struggled to configure my application to work with HTML and JSON, with support of some static ( e.g. css) resources.

SummaryTable

This is my marks for different aspects of platform. Max mark is 5. The bigger-the better.

CriteriaDropwizardSpring Boot
DI53
REST API34
Configuration53
Deployment45
Static Resources & Templates53
Total
2218





Summary
Dropwizard is better IMHO, and it plays nice with most Spring projects, like Spring Security and Spring JDBC. Spring Boot probably more performant, but I have no data on this topic, and all performance depends mostly from performance of your database. Solutions are quite similar, so winner detected.
There are lots of other articles on topic, that cover slightly different areas than this one.



Jan 15, 2016

OOP - we are fooling ourselves

Object Oriented Programming is a holy grail of modern code-writing methodologies. As everything so fundamental, it was criticised  quite heavily, with different degree of details. Some say, OOP is dead, some say it’s harmful. I think, we should reconsider our understanding of this paradigm.
If we talk about objects - we think about state (a lot) and behaviour (a little) . But in all domain models  we separate between «domain» and «business» logic. 

Example: A human buys bananas in a grocery store. Here set of objects Bananas change ownership and location. Object Store obtains money, frees some space in a shop, and loose some bananas. Object human looses money and gets a bananas. 
Question: What object should own this logic? If it’s 3 different objects, each with it’s own functions, then who should coordinate behaviour? Is it a shop who should take money from a human and change ownership of bananas? Or Human? Or Banana? Or some different different Object?
In practice, usually it’s different object, most probably StoreService. 

After that we have another question - about persistence. Somebody should store it to a database (persistent storage). Should it be domain objects? In practice, it’s usually DAO layer. 
And I will not dig into details - because human usually need to pack bananas in a bag and store should manage not to run out of bananas.
So, what do we have here - our objects are passive data objects, and all behaviour is in other objects, with some dependency on external resources (database).

Is it OOP ? Well, in practice, it’s what everybody calls OOP. Clearly, something is wrong.
Looking on a Store, we will not have an idea about all it’s abilities. StoreService will give us much more information. 

There is one solution I know to this problem - mix-ins. You will be able to mix some resource-dependent behaviour into domain objects, without altering domain objects much. Is it OOP ?
Nice articles on a subject:

Nov 11, 2013

Hazelcast trick 1

I was playing with hazelcast for a while. Great tool for java-based distributed systems - simple and elegant.
During our work I've run into some tricky situations. I understand that they can be solved in different ways, I've shosen to write some bits of code. I'll share these bits with explanations in upcoming posts.

Hazelcast Trick 1. Multicast vs TcpIpJoiner

Problem: 

In our network some clusters were in several subnets - and I've not figured out how to fix this yet, but hazelcast has tcp-ip joiner to the resque. There is one disadwantage though. Same config file for different machines makes it hard not to include localhost in config. And hazelcast was not working with hostnames correctly for me.

Solution:

So, I've decided to keep config file uniform, but add following code to my startup procedure:
       Config cfg = new FileSystemXmlConfig(configFile);
        cfg.setInstanceName(configName);
        if (tcpipjoin != null && tcpipjoin.isEnabled()) {
            cfg.getNetworkConfig().getJoin().getTcpIpConfig().clear();
            cfg.getNetworkConfig().getJoin().getTcpIpConfig().setEnabled(true);
            cfg.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
            for (String host : tcpipjoin.getHosts()) {
                String resolvedHost = resolveHostToIp(host);
                if (resolvedHost != null) {
                    cfg.getNetworkConfig().getJoin().getTcpIpConfig().addMember(resolvedHost);
                }
            }
        }
This solved 2 issues:

  1. Resolve hostname to IP (oddly, hazelcast was not doing well with hostnames, dont know why yet)
  2. Exclude localhost from list - in this final configuration was simple and effective. Without attempting to call itself and rezolve hostname.
Helper methos is not as straitforward, here it goes:

    static String resolveHostToIp(String host) throws UnknownHostException {
        String[] parts = host.split(":");
        if (parts.length > 2) throw new UnknownHostException("Illegal host format: " + host);
        String ip = InetAddress.getByName(parts[0].trim()).getHostAddress();
        if(isLocal(ip)) {
            logger.info("Host " + host + "filtered out as local");
            return null;
        }
        String resolved = parts.length == 1 ? ip : (ip + ":" + parts[1].trim());
        logger.debug("host " + host + " resolved to " + resolved);
        return resolved;
    }

    private volatile static List localhostIpSynonyms;

    private static boolean isLocal(String ip) {
        if (localhostIpSynonyms != null) {
            return localhostIpSynonyms.contains(ip);
        }
        else {
            try {
                List synonims = new ArrayList<>();
                for (Enumeration ifcs = NetworkInterface.getNetworkInterfaces(); ifcs.hasMoreElements(); ) {
                    NetworkInterface ifc = ifcs.nextElement();
                    if (ifc.isUp()) {
                        for (Enumeration ias = ifc.getInetAddresses(); ias.hasMoreElements(); ) {
                            synonims.add(ias.nextElement().getHostAddress());
                        }
                    }
                }
                localhostIpSynonyms = synonims;
                logger.info("Local IP's resolved to:" + localhostIpSynonyms);
                return localhostIpSynonyms.contains(ip);
            } catch (Exception e) {
                logger.error("Can not resolve list of local ip adress", e);
            }
        }
        return false;
    }

Trick is not only to rezolve hostname to ip with port set, but to lookup all local interfaces in order to drop local ones.

Oct 23, 2013

Trunk Based Development vs Successful-git-branching-model

At work I've faced 2 generic approaches to branching:

  1. "Modern", where we have branch-per-feature policy:
    http://nvie.com/posts/a-successful-git-branching-model/
  2. "Classic", where everybody commit to the trunk and branches are made only for releases:
    http://paulhammant.com/2013/04/05/what-is-trunk-based-development/
Both approaches are very interesting, but my personal favorite is "Classic" one. Because:
  1. CI  (Continious integration)- you merge often, and you have ci server testing your code. In first approach, you'll need job-per-branch, and there are a lot of them! In second, one job will notify you then your commit is breaking something
  2. If your changes are not compiling\not all test pass? Well, in this case solution is to commit but don't push.
  3. Second approach forces some sporadic code review, when 2 developers change some linked source - and this triggers communication and is a good way to common vision.

Sep 23, 2013

Java Puzzle #1

Inspired by Java Puzzlers conference, spotted interesting behaviour of following code:
public class LongNull {
    Long longi = null;

    public long getLongi() {
        return longi;
    }

    public static void main(String[] args) {
        System.out.println(new LongNull().getLongi());
    }
}
What it produces:
  1. NullPointerException
  2. Prints 0
  3. Prints null

Jan 21, 2013

The Role of the Development Manager

I've came across great article about development manager role, and want to share it with you:
http://www.infoq.com/articles/development-manager-role

Oct 23, 2012

Agile practice: Time frame

One of the most interesting aspects in agile is time-frame. It's idea of defining start time and duration for every activity.  There are not a lot of links google are providing on it, so I decided to create one.

Time frame for an individual

Understand, what do you want to achieve. For example, I want to finish my small practice catalogue "best practices in 10 minutes" (working URL is theme.alwaysdata.net).
How it will be in S.M.A.R.T. way ? Break you task into small, testable, relevant parts, if possible.   I need to do 10 practices in same format.
Time-bound it. Estimate - how much time you're expecting to spent on every part. Or how much time you will spent on it every day/week. Best option is to have something delivered - new feature per day, new page for your book
I spend 0.5 hour every day creating practice description for my catalogue. It took me a week to get to the "almost  done" point. I've struggled for a month before applying time-frame, thinking "I still have time to do it later". 
So, I just start my pomodoro and focus on task, forgetting about everything else for 25 minutes.
After some time-units (for me it's pomodoro) You will be able to see what needs to be done and how much time will it take me to finish task, because you will know your velocity.

If there is no ability to create SMART tasks, I will reveal a secret. Smart tasks aren't needed to time frame, it's just useful to have ones. Just limit your time and at the end of each iteration think about what was done and what needs to be done. Important thing here is to mark previous task as done and create new task, putting there all the remaining work. If size of task changes (it may increase, if task is more complex than you thought) or scope becomes more clear - it means you've done right thing and you'll be more productive next iteration.

Time frame  for teams and iterations.

Limit your time for tasks, for iteration, for meetings. It will be painfull to end meetings in the middle of conversation or understand what task breakdown is needed in the end of iteration, but it will mean that next meeting will be more focused and next iteration planning will be more detailed.

Conclusion

Time is our most precious resource. Learning to respect it is a key for happy and productive work. Time framing is great-to-have practice, it will enhance your estimation ability greatly. Most important in time-framing - that at the end of each iteration you feel that you're one step closer to your goal.