Monthly Archives: August 2014

Named parameters in Java

Creating a method that has many parameters is a major sin. Whenever there is need to create such a method, sniff in the air: it is code smell. Harden your unit tests and then refactor. No excuse, no buts. Refactor! Use builder pattern or even better use Fluent API. For the latter the annotation processor fluflu may be of great help.

Having all that said we may come to a point in our life when we face real life and not the idealistic pattern that we can follow in our hobby projects. There comes the legacy enterprise library monster that has the method of thousands parameters and you do not have the authority, time, courage or interest (bad for you) to modify … ops… refactor it. You could create a builder as a facade that hides the ugly API behind it if you had the time. Creating a builder is still code that you have to unit test even before you write (you know: TDD) and you just may not have the time. The code that calls the monstrous method is also there already, you just maintain it.

You can still do some little trick. It may not be perfect, but still something.

Assume that there is a method

public void monster(String contactName, String contactId, String street, String district,
                    ...
                    Long pT){
...
}

The first thing is to select your local variables at the location of the caller wisely. Pity the names are already chosen and you may not want to change it. There can be some reason for that, for example there is an application wide naming convention followed that may make sense even if not your style. So the call

monster(nm, "05300" + dI, getStrt(), d, ... , z+g % 3L );

is not exactly what I was talking about. That is what you have and you can live with it, or just insert new variables into the code:

String contactName = nm;
String contactId = "05300" + dI;
String street = getStrt();
Street district = d;
...
Long pT = z+g % 3L;
monster(contactName, contactId, street, district, ... ,pT );

or you can even write it in a way that is not usual in Java, though perfectly legal:

String contactName, contactId, street, district;
...
Long pT;
monster(contactName = nm, contactId = "05300" + dI, street = getStrt(), district = d, ... ,pT = z+g % 3L );

Tasty is it? Depends. I would not argue on taste. If you do not like that, there is an alternative way. You can define auxiliary and very simple static methods:

static <T> T contactName(T t){ return T;}
static <T> T contactId(T t){ return T;}
static <T> T street(T t){ return T;}
static <T> T district(T t){ return T;}
...
static <T> T pT(T t){ return T;}

monster(contactName(nm), contactId("05300" + dI), street(getStrt()(, district(d), ... ,pT(z+g % 3L) );

The code is still ugly but a bit more readable at the place of the caller. You can even collect static methods into a utility class, or to an interface in case of Java 8 named like with, using, to and so on. You can statically import them to your code and have some method call as nice as

doSomething(using(someParameter), with(someOtherParameter), to(resultStore));

When all that is there you can feel honky dory if you answer the final question: what the blessed whatever* is parameter pT.

(* “whatever” you can replace with some other words, whichever you like)

Logical thinking…

“The fact that logical thinking is part of the job description of a programmer does not imply that others should not practice that.”

This was a very witty comment on a Hungarian newsletter focusing on Java. The actual issue was about how to handle a SOAP message that is 1.8GB and has to be handled once a day. The issue was around checking the correctness of the message against some predefined XSD and then parsing the content and do some functionality controlled by the content.

This is a nice task and though I had no practical experience with a SOAP message of that huge size I recommended to do some benchmark on a machine which fits more or less the size of the memory and CPU of the production machine no matter what software stack is selected. These days a machine with 16GB or more memory is not so rare and one may be able to handle the 1.8GB SOAP in memory even if the overhead of JVM and Java were huge. (Which I do not say is, but it could be. If you are interested: you can measure and publish an article about that, different story.)

Some of the commenters followed a different pattern. They, the cleverer ones, suggested that perhaps the developer has to ask the business analyst (BA) about the details. It may not necessarily be the best solution from the business point of view to transfer such huge beasts over SOAP. What was the business reason to use SOAP? What was the business reason to use XML? What is the business benefit? What are the business goals? Business goals are rarely related to SOAP or XML. They are tools one (several) level lower in the solution chain.

When the business analyst gets the requirements from the business people, she should not just blindly pass it on. We, developers expect them to think a bit of technology. They are the bridge between the business people and the developers. Some of the BAs are very experienced technically and are eager to learn. Probably they are the ones that are also eager to learn on the other side: how the business work. Some BAs are less technical but still do their job. A SOAP message of 1.8GB should ring the warning bell even for a BA? Or not?

Don not hit sysadmins with NPE!

My opinion is that having a null pointer exception and getting it into the log without catching, handling and re-throwing it in another exception is not inherently bad. If we can do nothing better then it should not be a problem. The thing is that in practice almost always there is a better way to handle the situation.

Recently I was pair programming and we debugged some web code. We could not get through the authentication filter on the development environment and the authentication was not really in scope for the debugging so we decided to switch that totally off for the time. The next thing was an NPE. We looked at the code and we saw at the line something like

principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

It was obvious: since the authentication was switched off the result of getAuthentication() was null, and therefore calling getPrincipal() on null caused the NPE. Should we modify the code to check if there is authentication information and throw a different exception? What would be the benefit to do that? The code runs slower, gets bigger (and bigger code is harder to maintain). And the NPE and the code source together are obvious. There is no need to change.

On second thought the NPE may not be that obvious for a support guy operating the code somewhere at the other side of this rotating ball. He may not have handy access to the source code and may not understand easily that the root cause for the NPE was the misconfiguration of the authentication layer. He/she has to start the server, it does not work and calls the support, raises a ticket. You as a responsible developer being at the farthest end of the support line may woke up during your finest sleep just to tell him/her that the authentication layer was misconfigured. Than you regret that you could have told it in the logs and in the exception.

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if( auth == null ){
  throw new BadConfigurationException("The authentication layer is not properly configured SecurityContextHolder.getContext().getAuthentication() returned null."
}
principal = auth.getPrincipal();

Not that big deal and pays back on the long run.

Moral: What seems to be obvious for the developer during development may not be that easy for the system administrator. Admins are not familiar with the code, may not have access to source code, have less experience in programming. On the other hand they have great experience setting up and running systems. It is a hard work, they deserve proper log messages and talkative exceptions.

What DSLs are not for

Domain specific languages are special programming languages. Each fits some special “domain” and makes the business code simpler. Using a DSL the business level problem can be implemented higher level and therefore the resulting code is simpler, it is created faster, presumably contains less errors. Some DSLs in some areas make it even possible to develop business functionality by the domain experts who have limited programming experience. There are many great books on DSLs Martin Fowler’s one being at least one of, if not the best of the topic.

Many times the decision to use DSL is to shorten release cycles. A mature software in a rapidly changing business domain may change frequently but many times the change is small. If it requires the change of the code then the whole release cycle is to be repeated. Code is modified, unit tested, release candidate is created, QA tests the new version and finally the release is ready after weeks the new business need arose. The obvious approach is to embed some DSL into the application and develop some business function that is likely to be changed in the future in this DSL. The “script” written in DSL may not be part of the real release and therefore the change can go through the system faster. Developers have less obvious coding, which developers usually do not like, business is happy getting the modified functions faster. Right?

WRONG!

But not so obviously at the first time, perhaps. The DSL functions fine, the new behavior is delivered faster and there is no problem. Some time later, however, there come a new feature that can not be implemented in the DSL and needs the change of the code application code. Why not extend the DSL and implement the new functionality in the new version of the DSL? This approach is very lucrative but it is very dangerous.

DSL are like alcohol. They can have a purpose and can serve good. A cup of quality wine after a nice summer evening supper should not harm. Too much of it regularly will ruin your life. A DSL that has too many features may be dangerous. Some may use it for the good, but there is a possibility for abuse. The release process was examined and engineered when the DSL was introduced but may not be reviewed as the DSL became more and more powerful and suddenly you may face a situation when new features are developed into the software out of the release cycle. At some point the release process and the most crucial part of it, quality assurance may be ruined.

DSL should be simple. Modification of the application scripting should also follow some release management. There may not be release management at all. I have heard of software projects where the software was released to public without any significant testing. If there was an error, the users complained about it and a new release came out an hour later. Fixing one bug, creating a new one. No problem if the business can stand that. The actual software was a facebook like application where new feature was more important for the users than uninterrupted use. Other applications in telecom, banking should be tested a bit more rigorous. Regulation may even demand all releases to be archived. In that case scripting out of the release cycle is out of question.

And there may be something in the middle. Some part, some features of the application may need strict release management, while other may not demand that. Some part can be scripted using some DSL, other core functions need strong QA and release management. Some features may mix the both: scripted and still part of the cycle.

The important message is:

Application scripting in DSL does not ease release management and/or QA. If the release management cycle can be releases for some part of the application feature, DSL may be a tool to aid that, but DSL is never the reason.