Archive

Posts Tagged ‘Java’

A dive into the Builder pattern

October 6th, 2013 10 comments

The Builder pattern has been described in the Gang of Four “Design Patterns” book:

The builder pattern is a design pattern that allows for the step-by-step creation of complex objects using the correct sequence of actions. The construction is controlled by a director object that only needs to know the type of object it is to create.


A common implementation of using the Builder pattern is to have a fluent interface, with the following caller code:

Person person = new PersonBuilder().withFirstName("John").withLastName("Doe").withTitle(Title.MR).build();

This code snippet can be enabled by the following builder:

public class PersonBuilder {

    private Person person = new Person();

    public PersonBuilder withFirstName(String firstName) {

        person.setFirstName(firstName);

        return this;
    }

    // Other methods along the same model
    // ...

    public Person build() {

        return person;
    }
}

The job of the Builder is achieved: the Person instance is well-encapsulated and only the build() method finally returns the built instance. This is usually where most articles stop, pretending to have covered the subject. Unfortunately, some cases may arise that need deeper work.

Let’s say we need some validation handling the final Person instance, e.g. the lastName attribute is to be mandatory. To provide this, we could easily check if the attribute is null in the build() method and throws an exception accordingly.

public Person build() {

    if (lastName == null) {

        throw new IllegalStateException("Last name cannot be null");
    }

    return person;
}

Sure, this resolves our problem. Unfortunately, this check happens at runtime, as developers calling our code will find (much to their chagrin). To go the way to true DSL, we have to update our design – a lot. We should enforce the following caller code:

Person person1 = new PersonBuilder().withFirstName("John").withLastName("Doe").withTitle(Title.MR).build(); // OK

Person person2 = new PersonBuilder().withFirstName("John").withTitle(Title.MR).build(); // Doesn't compile

We have to update our builder so that it may either return itself, or an invalid builder that lacks the build() method as in the following diagram. Note the first PersonBuilder class is kept as the entry-point for the calling code doesn’t have to cope with Valid-/InvaliPersonBuilder if it doesn’t want to.


This may translate into the following code:

public class PersonBuilder {

    private Person person = new Person();

    public InvalidPersonBuilder withFirstName(String firstName) {

        person.setFirstName(firstName);

        return new InvalidPersonBuilder(person);
    }

    public ValidPersonBuilder withLastName(String lastName) {

        person.setLastName(lastName);

        return new ValidPersonBuilder(person);
    }

    // Other methods, but NO build() methods
}

public class InvalidPersonBuilder {

    private Person person;

    public InvalidPersonBuilder(Person person) {

        this.person = person;
    }

    public InvalidPersonBuilder withFirstName(String firstName) {

        person.setFirstName(firstName);

        return this;
    }

    public ValidPersonBuilder withLastName(String lastName) {

        person.setLastName(lastName);

        return new ValidPersonBuilder(person);
    }

    // Other methods, but NO build() methods
}

public class ValidPersonBuilder {

    private Person person;

    public ValidPersonBuilder(Person person) {

        this.person = person;
    }

    public ValidPersonBuilder withFirstName(String firstName) {

        person.setFirstName(firstName);

        return this;
    }

    // Other methods

    // Look, ma! I can build
    public Person build() {

        return person;
    }
}

This is a huge improvement, as now developers can know at compile-time their built object is invalid.

The next step is to imagine more complex use-case:

  1. Builder methods have to be called in a certain order. For example, a house should have foundations, a frame and a roof. Building the frame requires having built foundations, as building the roof requires the frame.
  2. Even more complex, some steps are dependent on previous steps (e.g. having a flat roof is only possible with a concrete frame)

The exercise is left to interested readers. Links to proposed implementations welcome in comments.

There’s one flaw with our design: just calling the setLastName() method is enough to qualify our builder as valid, so passing null defeats our design purpose. Checking for null value at runtime wouldn’t be enough for our compile-time strategy. The Scala language features may leverage an enhancement to this design called the type-safe builder pattern.

Summary

  1. In real-life software, the builder pattern is not so easy to implement as quick examples found here and there
  2. Less is more: create an easy-to-use DSL is (very) hard
  3. Scala makes it easier for complex builder implementation’s designers than Java
Send to Kindle
Categories: Development Tags: , ,

On the merits of verbosity and the flaws of expressiveness

September 8th, 2013 2 comments

Java is too verbose! Who didn’t stumble on such a rant on the Internet previously? And the guy bragging about [Insert expressive language there], that which soon replace Java because it is much more concise: it can replace those 10 lines of Java code with a one-liner. Ah, the power!

Unfortunately, in order to correlate conciseness with power (and verbosity with lack of power), those people take many shortcuts that once put into perspective make no sense at all. This article aims to surgically deconstruct such shortcuts to expose their weaknesses. And because I like a factual debate – and because there are not only trolls on the Internet, this post will be linked to Andy Petrella’s different point of view.

Verbose is not bad

Having more data than necessary prevents messages corruption by indirect communication. Here are two simple but accurate examples:

  • In network engineering, there’s a concept of DBIt or Delivery Confirmation Bit. It is just a summary of all 0 or 1 of the current sequence and guarantees the delivered packet has been transmitted correctly, despite not-so-adequate network quality.
  • In real-life, bank accounts have a 2-digits control key (at least in most European countries I know of). Likewise, it is to avoid wiring funds to a erroneous account.

It’s exactly the same for “verbose” languages; it decreases probability of understanding mistakes.

More concise is not (necessarily) better

Telling that one-liner are better than 10 lines implies that shorter is better: this is sadly not the case.

Let us take a code structure commonly found in Java:

public List<Product> getValidProducts(List<Product> products) {

    List<Product> validProducts = new ArrayList<Product>();

    for (Product product : products) {

        if (product.isValid()) {

            validProducts.add(product);
        }
    }

    return validProducts;
}

In this case, we have a list of Product and want to filter out invalid ones.

An easy way to reduce verbosity is to set everything on the same line:

public List<Product> getValidProducts(List<Product> products) { List<Product> validProducts = new ArrayList<Product>(); for (Product product : products) { if (product.isValid()) { validProducts.add(product); } } return validProducts;}

Not concise enough? Let’s rename our variables and method obfuscated-style:

public List<Product> g(List<Product> s) { List<Product> v = new ArrayList<Product>(); for (Product p : s) { if (p.isValid()) { v.add(p); } } return v;}

We drastically reduced our code verbosity – and we coded everything in a single line! Who said Java was too verbose?

Expressiveness implies implicitness

I already wrote previously on the dangers of implicitness: those same arguments could be used for programming.

Let us rewrite our previous snippet à la Java 8:

public List<Product> getValidProducts(List<Product> products) {

    return products.stream().filter(p -> p.isValid()).collect(Collectors.toList());

}

Much more concise and expressive. But it requires, you, me and everybody (sorry, I couldn’t resist) to have a good knowledge of the API. The same goes for Scala operators and so on. And here comes my old friend, the context:

  • The + operator is known to practically everyone on the planet
  • The ++ operator is known to practically every software developer
  • The Elvis operator is probably known to Groovy developers, but can be inferred and remembered quite easily by most programmers
  • While the :/ operator (aka foldLeft()) requires Scala and FP knowledge

So from top to bottom, the operator requires more and more knowledge thus reducing more and more the number of people being able to read your code. As you write code to be read, readibility becomes the prime factor in code quality.

Thus, the larger the audience you want to address, the more verbose your code should be. And yes, since you will not use advanced features nor perfect expressiveness, seasoned developers will probably think this is just average code, and you will not be praised for your skills… But ego is not the reason why you code, do you?

Summary

In this article, I tried to prove that “Less is more” does not apply to programming with these points:

  • Verbosity prevents communication mistakes
  • Spaces and tabs, though not needed by the compiler/interpreter, do improve readibility
  • Expressiveness requires you and your readers share some common and implicit understanding

I will be satisfied if this post made you consider perhaps verbosity is not so bad after all.

Now is the time to read Andy’s post if you didn’t already and make your own mind.

Send to Kindle
Categories: Development Tags: , ,

Java, Scala, complexity and aardvarks

December 4th, 2011 2 comments

This week saw another flame war from some of the Scala crowd. This time, it was toward Stephen Colebourne, the man behind Joda time.

The article in question can be found here, and Stephen’s answer here.

To be frank, I tend to agree to Stephen’s predicat but for very different reasons. Now, if you’re a Scala user, there are basically 2 options:

  • either you react like some did before, telling me I’m too stupid or too lazy to really learn the language and stop reading at this point. In this case, I’m afraid there’s nothing I can say apart from ‘Please, don’t harm me’ because it has a feeling of religion war coming from supposedly scientific-minded people.
  • Or you can read on and we’ll debate like educated people.

Truth is, I’m interested in Scala. I try to program in Scala for personal projects. So far, I’ve gotten the hold on traits (what I would do to have them in Java) and closures and I’ve understood some of the generics concepts (so long as it’s not too complex). I plan on diving in the Collections API to better use closures next.

I think that Scala, like EJB2, was designed by smart, even brilliant people, but with a different experience than mine.

In real life, projects are full of developpers of heterogeneous levels: good developers, average developers and bad developers. And please don’t blame it on the HR department, the CEO or the global strategy of the company: it’s just Gaussian distribution, just like in any population.

In effect, that makes Scala a no-go in most contexts. Take Java as an example. What did it make it so successful, even with all its lackings? The compile-once, run-everywhere motto? Perhaps, but IMHO, the first and foremost reason behind Java success is the change of responsibility in memory management, from developers (like in C/C++) to system administrators. Before, the worse the developer, the higher the probability of a bug in memory management but Java changed all this: it’s not perfect, but much simpler.

Like Freddy Mallet, I’m sure a technology has to be simple to become mainstream and Scala has not taken this road. As a consequence, it’s fated to stay in a niche market… Stating this should raise no reactions from anybody, it’s just a fact.

Note: aardvarks will be a point for a future blog post.

Send to Kindle
Categories: Java Tags: ,

Thoughts on Java logging and SLF4J

November 21st, 2009 15 comments

In this post, I will ramble on logging in Java, how it was done in the old days and what can a library like SLF4J can bring.

Logging is a basic need when you create software. Logging use-cases are:

  • debugging the software during development,
  • help diagnose bugs during production
  • trace access for security purposes
  • create data for statistical use
  • etc.

Whatever the use, logs should be detailed, configurable and reliable.

History

Historically, Java logs where done with System.out.println(), System.err.println() or e.printStackTrace() statements. Debug logs where put in System.out and error logs in System.err. In production, both were redirected: the former on the null output, the latter to the desired error log file. So they were useful enough but they suffered from a big drawback: they were not very configurable. It was an all or nothing switch, either log or don’t. You could not focus detailed logs on a particular layer or package.

Log4J came to the rescue. It was everything one could ever want from a logging framework. It invented many concepts still used in today’s logging frameworks (it was the first framework I used so please bear with me if a concept was not invented by it):

  • the concept of Logger so that each logger can be configured independently
  • the concept of Appender so that each appender can log wherever it wants (file, database, message, etc.)
  • the concept of Level so that one can configure the logging (or not) of each message separately

After that, Sun felt the need for a logging feature inside the JDK but, instead of using log4j directly, it created an API inspired by it. However, it was not not so well finished as Log4J. If you want to use JDK 1.4 logging, chances are you’ll have to write your own Appenders – called Handlers – since the only handlers available are Console and File out-of-the-box.

With both frameworks available, you needed to configure both of them since whatever framework you used, there was surely at least one dependency of your project that used the other. Apache Commons Logging is an API bridge that connects itself to supported logging frameworks. Libraries should use commons-logging so that the real framework used is the choice of the project, and is not imposed by the dependencies. This is not always the case, so Commons Logging does not solve the double configuration problem. Morevoer, Commons Logging suffer from some class-loading problems, leading to NoClassDefFoundError errors.

Finally, the lead programer from Log4J quit the project for reasons I will not detail here. He created another logging framework, namely SLF4J, that should have been Log4J v2.

Some strange facts

The following facts are things that bother me with the previous frameworks. They are not drawbacks per se but are worth mentioning:

  • Log4J has Maven dependencies on JMS, Mail and JMX that are not optional, meaning they will appear on your classpath if you do not bother to exclude them
  • Likewise, Commons Logging has Maven dependencies on Avalon (another logging framework), Log4J, LogKit and Servlet API (!) that are not optional
  • A Swing log viewer is included in Log4J jar, even if you it is used in an headless environment, such as a batch or an application server
  • Log4J v1.3 main page redirects to v1.2 while Log4 v2.0 is experimental

Which framework to use ?

Log4J would be the framework of choice (and is for most) but it is no longer developed. Version 1.2 is the reference, version 1.3 is abandoned and version 2.0 is still in its early stage.

Commons Logging is a good choice for a library (as opposed to an application) but I suffered once classloaders issues, and once is enough to veto it (finally, i threw Commons Logging out and used Log4J directly).

JDK 1.4 Logging is a standard and does not raise concurrent versions problems. But it lacks so many features, it cannot be used without redeveloping some such as a database adapter and such. Too bad… but it does not answers the question: which framework to use?

Recently, architects of my company decided for SLF4J. Why such a choice?

SLF4J

SLF4J is not as widespread as Log4J because most architects (and developers alike) know Log4J well and either don’t know about SLF4J, or don’t care and stick to Log4J anyway. Moreover, for most projects Log4J fulfills all logging’s needs. Yet, interestingly enough, Hibernate uses SLF4J. It has some nice features that are not present in Log4J.

Simple syntax

Take the following Log4J example:

LOGGER.debug("Hello " + name);

Since String concatenation is frowned upon, many companies enforce the following syntax, so that the concatenation only does take place when in DEBUG level:

if (logger.isDebugEnabled()) {

  LOGGER.debug("Hello " + name);
}

It avoids String concatenation but it’s a bit heavy, isn’t it? In contrast, SLF4J offers the following simple syntax:

LOGGER.debug("Hello {}", name);

It’s like the first syntax but without the concatenation cost nor the heavy syntax burden.

SLF4J API and implementation

Moreover, SLF4 nicely decouples API from implementation so that you can use the API that works best with your development with the back-end that suits best your production team. For example, you could enforce the use of the SL4J API while letting the production still reuse the old log4j.properties they’ve known for ages. SLF4J’s logging implementation is known as LogKit.

SLF4J bridging

SLF4J has a bridging feature sor you can remove all log4j and commons-logging dependencies from your project’s dependencies and use only SLF4J.

SLF4J offers a JAR for each logging framework: they mimic its API but reroute the calls to the SLF4J API (which in turn uses the real framework). A word of warning: you could run into a cycle so beware to not have the bridging library along the implementation library in your classpath. For example, if you use the Log4J bridge, each Log4J API call will be rerouted to SLF4J. But if the SLF4J Log4J implementation is present, it will be routed back to Log4J then again, and again.

SLF4J API with Log4J implementation

Taking all these facts into account, my advice is to use SLF4J API and Log4J implementation. This way, you still configure logging the old Log4J way but you have access to SLF4J’s simpler API. In order to do so, you’ll have to:

Action Location Description
Add to classpath slf4j-api.jar* Main API without which you cannot use SLF4J
slf4j-log4j.jar* SLF4J Log4J implementation
jul-to-slf4j.jar* Enables rerouting JDK 1.4 logging calls to SLF4J
jcl-over-slf4j.jar* Reroutes commons-logging calls to SLF4J
Remove from classpath commons-logging.jar* Would conflict with commons-logging API in jcl-over-slf4j.jar
SLF4JBridgeHandler.install()** Main application Redirect JDK 1.4 logging calls to SLF4J
* Jar name will likely includes version
** 20% overhead advertised so do only if you need the single entry point and if there are a few calls

In you run inside an application server, you’ll probably have to change its libraries and / or its configuration to reach this situation.

To go further:

Send to Kindle

JNA meets JNI

May 23rd, 2009 7 comments

I reccently stumbled upon a nice framework you’ll love if you ever have to work with native code. Before this framework, if you needed to call native code, you would use JNI. JNI uses a proved but complex and error-prone process.

First thing first, you write your Java classes like always. But for methods you want to delegate to native code, you use the native keyword and do not provide an implementation. Then, you call a JDK-provided executable named javah. This generates your C header file (*.h) and an empty stub implementation: you have to fill the voids. Finally, you compile both Java and C files.

At runtime, do not forget to load the library with System.loadLibrary("mylib"). Notice you do not provide the extension, the JVM does it automatically for you, depending on you platform (.dll on Windows, .so on Linux). Then call you Java class and it will magically delegate to your native code.

This whole process always frustrated me (and so, I can imagine, lots of developers) because of the following reasons:

  • since I’m a Java developer and not a C developer, I could never write good C code. It hurts my head to even consider memory allocations or to bring myself to think about function pointers ;-)
  • if I need to change the native Java method signature, I have to run the whole process again or change both header and C files without errors, and then compile everything again. In this case, I can’t stress out the importance of having a very automated build process or the adequate IDE (I tend toward the former)
  • last, but not least, what if I do not have access to the source C file? JNI can’t help you call Windows dll… or you have to write a proxy-like C file to do so

Rejoice people. Java.net brought you the solution. The answer to your problems is Java Native Access or JNA. Now calling a NTLM authentication or showing the running services inside your application will be a breeze. Let’s try to get informations about your computer running under Windows – sorry ‘Nix users.

The first thing is to know which function will get you there: such is the goal of the MSDN library. Now, create an interface, preferably name after the DLL you will use and make it inherit from com.sun.jna.Libray. Its methods will have to map exactly the name and the arguments of the DLL. For example, let’s say you want to display your computer’s name. Under Windows, there’s a method named GetComputerNameW() that is provided by kernel32.dll. So, you interface will have a method adequately named GetComputerNameW(). The Devil being in the details, you’ll have to map each parameter documented in MSDN on a parameter in your interface’s method’s signature. GetComputerNameW() takes 2 parameters: a LPTSTR (pointer to a char buffer) and a LPDWORD (pointer to a integer). Running to JNA documentation, the mapping in Java becomes a char[] and a com.sun.jna.ptr.IntByReference.

Your interface now looks like this:

public interface Kernel32 extends StdCallLibrary {

    int GetComputerNameW(char[] name, IntByReference number);

    // Other method mappings
    ...
}

Now, in order to access a Kernel32 reference, just use the following codeline. Under the table, it will bind our interface to the underlying implementation through a proxy:

Kernel32 kernel32 = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);

This done, each subsequent call to kernel32′s GetComputerName() method will fill the char buffer with our computer’s name.

JNA still suffers from some drawbacks:

  • JNA usually performs 10x slower than JNI. It has some techniques to speed up execution, so if you are in a performance-aware environment, you’ll probably want to use them
  • it won’t make you a pro C programmer so very complex method signatures will throw you into frenzy: the harder part of the job will be mapping the datatypes from C to Java. This will probably frustrate you to no end since you will be seeing java.lang.UnsatisfiedLinkError: Error looking up function XXX: La procédure spécifiée est introuvable more often than not. In this case, call a C programmer for help!

The sources of this small project are provided Maven-style. Have fun with Java and Windows!

To go further:

Send to Kindle
Categories: Java Tags: , , , , , , ,