{ by david linsin }

March 27, 2009

JDK 7 Language Changes are Coined

Joe Darcy has posted a blog post on the status of project coin. According to Joe there are six proposals for small language changes, which are shortlisted by Sun. I put together an overview with some code samples.

1. Strings in switch by Joe Darcy
String s = ...
switch(s) {
case "foo":
processFoo(s);
break;
}

I really have no feelings about this change whatsoever! It's not a pain for me that it doesn't work right now and I think I won't need it if it's gonna be in JDK 7.

2. Improved Exception Handling for Java by Neal Gafter
try {
doWork(file);
} catch (final IOException|SQLException ex) {
logger.log(ex);
throw ex;
}

I wrote about how great it would be to have this feature as part of closures. As we all know, sadly, there won't be any closures in JDK 7, however I'm really glad that this part is considered to be in.

3. Automatic Resource Management by Josh Bloch
try (BufferedReader br = new BufferedReader(new FileReader(path)) {
return br.readLine();
}

As with catching multiple Exceptions at the same time, this is a language change that I would welcome with open arms! On the mailing-list of project coin this proposal caused the most vibrant discussions. Josh Bloch was very open about any type of feedback, even when someone suggested a modifier for cleaning up resources instead of the try statement. That made following the discussion very interesting.

4. Improved Type Inference for Generic Instance Creation by Jeremy Manson
Map<String, List<String>> anagrams = new HashMap<>();

I asked for this in a blog post almost a year ago and it seems as if I have been finally heard. The first thing you might ask when you see this, is why Jeremy Manson proposes new HashMap<>() instead of new HashMap(). In his very well worked out proposal, he indicates, it's a matter of backward compatibility. However, he also mentions it is not impossible to remove the arrow brackets in future versions.

5. Elvis and Other Null-Safe Operators written by Neal Gafter and submitted by Stephen Colebourne
String s = mayBeNull?.toString() ?: "null";
Integer ival = ...; // may be null
int i = ival ?: -1; // no NPE from unboxing

The operator ?: is called Elvis, because the question mark looks like the Elvis smiley, as I've learned from the Java Posse mailing-list yesterday. Jokes apart, I like this proposal the more I look at it. However, I've never had problems with adding null checks to my code and I'm not sure if the NPE problem would be solved better with annotations. JSR 303 - Bean Validation, provides a @NotNull annotation, which can be used to define your intend to prevent Null from being passed to your method. I tend to think the language level approach is not suitable here.

6. Simplified Varargs Method Invocation by Bob Lee

Before:
static <T> List<T> asList(T... elements) { ... }
static List<Callable<String>> stringFactories() {
Callable<String> a, b, c;
...
*// Warning: **"uses unchecked or unsafe operations"*
return asList(a, b, c);
}

After:
*// Warning: **"enables unsafe generic array creation"*
static <T> List<T> asList(T... elements) { ... }
static List<Callable<String>> stringFactories() {
Callable<String> a, b, c;
...
return asList(a, b, c);
}

This proposal simply moves the warnings from the invocation of the generified method to the declaration. I know this warning is annoying and it would reduce the number of warnings in your code base, but for me, this has never been a real pain so far.

The project coin mailing-list was flooded with proposals, so if you wonder why Sun chose the afore mentioned here's why:

Sun believes that the proposals are small enough, have favorable estimated reward to effort ratios, and advance the stated criteria of making things programmers do everyday easier or supporting platform changes in JDK 7.


You can really tell that Sun is on a schedule and that there is not a lot of time to gather more ideas. In fact Joe asks in his blog post to continue work on the before mentioned proposals, in the form of prototypes and refinements, instead of sending in new ones.

I've been on the project coin mailing-list since day one and I have to commend Joe on how he is "handling" the list. No offense, but some of the folks sending in proposals should really try to get some writing lessons. My English is not perfect and trying to communicate something subtle as a language change is really hard, but some folks are just not able to produce proper English sentences. Joe did a pretty good job in keeping people like that on a short leash.

The shortlisted proposals almost match with the winners of the poll I conducted a couple of months ago. I think in general they are gonna be very welcome by a broad range of developers. However, the implementation of those proposals is a whole different story. Next week we will know more.

March 23, 2009

JUG-Ka Stammtisch 3.0

Version 3.0 of the Java Users Group Karlsruhe Stammtisch is being release this coming Thursday 26th of March. This time we are going to meet directly in the pub Litfass, which is near Marktplatz, at 20:00 to get a good sip of Java. For further information check out the Google Group or drop me an email.

March 19, 2009

Final or Not Final?

I recently implemented an extension to Spring's HsqlSequenceMaxValueIncrementer. When I digged into the Spring source code of HsqlSequenceMaxValueIncrementer and its ancestors, I noticed something astonishing: almost all methods are public or at least protected and there is not one final class or field. Everything is extensible and somewhat accessible.

Let's take a look at AbstractSequenceMaxValueIncrementer, one of the parent classes of HsqlSequenceMaxValueIncrementer:


public abstract class AbstractDataFieldMaxValueIncrementer implements DataFieldMaxValueIncrementer, InitializingBean {
private DataSource dataSource;
private String incrementerName;

public AbstractDataFieldMaxValueIncrementer() {
}

public AbstractDataFieldMaxValueIncrementer(DataSource dataSource, String incrementerName) {
Assert.notNull(dataSource, "DataSource must not be null");
Assert.notNull(incrementerName, "Incrementer name must not be null");
this.dataSource = dataSource;
this.incrementerName = incrementerName;
}

public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}

public DataSource getDataSource() {
return this.dataSource;
}

public void setIncrementerName(String incrementerName) {
this.incrementerName = incrementerName;
}

public String getIncrementerName() {
return this.incrementerName;
}

public void afterPropertiesSet() {
if (this.dataSource == null) {
throw new IllegalArgumentException("Property 'dataSource' is required");
}
if (this.incrementerName == null) {
throw new IllegalArgumentException("Property 'incrementerName' is required");
}
}

public int nextIntValue() throws DataAccessException {
return (int) getNextKey();
}

public long nextLongValue() throws DataAccessException {
return getNextKey();
}

public String nextStringValue() throws DataAccessException {
// removed implementation for brevity
}

protected abstract long getNextKey();
}


Since I was extending the framework, the degree of flexibility was great for me. All I had to do was override a few methods to plug in my code and that's it.

If everything is accessible, the way it is in case of AbstractDataFieldMaxValueIncrementer, users can do almost everything they want with the classes you published. They can override all the methods and subclass each and every class. As shown above, that was obviously intended. The class wouldn't be abstract and have public/protected methods if it wasn't intended to be subclassed.

After reading the book Practical API Design, which preaches backward compatibility, I wonder how you would be able to evolve such a class? Let's say you wanted to extend the meaning of the field incrementerName. It should convey more information than simply the name of the sequence. Therefore you'd create a class IncrementerName, which replaced the String field. With this simple change, you'd break all the clients relying on the field incrementerName. I know this example might seem far-fetched, but I think you get the idea.

Another thing that caught my eye, when looking at AbstractDataFieldMaxValueIncrementer, is the field dataSource. It is basically a public field and I'm not quite sure why. Is it really necessary to replace the DataSource after you initialized the bean? Do you really want everyone to screw with the DataSource?

If it was for me, I would have answered those questions with a plain "No!". Why not implement AbstractDataFieldMaxValueIncrementer as follows:


public abstract class AbstractDataFieldMaxValueIncrementer implements DataFieldMaxValueIncrementer {
private final DataSource dataSource;
private final String incrementerName;

public AbstractDataFieldMaxValueIncrementer(DataSource dataSource, String incrementerName) {
Assert.notNull(dataSource, "DataSource must not be null");
Assert.notNull(incrementerName, "Incrementer name must not be null");
this.dataSource = dataSource;
this.incrementerName = incrementerName;
}

protected DataSource getDataSource() {
return this.dataSource;
}

public String getIncrementerName() {
return this.incrementerName;
}

public int nextIntValue() throws DataAccessException {
return (int) getNextKey();
}

public long nextLongValue() throws DataAccessException {
return getNextKey();
}

public String nextStringValue() throws DataAccessException {
// removed implementation for brevity
}

protected abstract long getNextKey();
}


I think this would not restrict the use of the class, except that you have to use constructor injection, but that's a different story. It would, however, restrict the use of the fields dataSource and incrementerName. I think those fields should be immutable anyways, since I cannot think of a reason why you would want to change them during the life-cycle of the object. I know dataSource isn't truly immutable, but the access is limited to subclasses, which should confine the wrong usage.

That leaves me with the question, why the authors of AbstractDataFieldMaxValueIncrementer didn't go that route? I think it's simply a design decision of Spring authors, to be as open and extensible as possible. They have InitializingBean and @Required to enforce necessary dependencies, which work quite well. I guess they push the responsibility of handling immutables with care to the developer, which is reasonable, but in my opinion rather risky. I think using final in such cases is an easy way to remove unnecessary sources of errors.

I'm not quite sure which approach is the best here. Does it all boil down to "it depends"? Or is all a matter of taste? I don't think so. In my day to day coding, I tend to consciously follow the advices of Effective Java, which favors immutability and limiting accessibility. However, looking at Spring's source code is a truly inspiring. They are doing a phenomenal job of keeping it stable, considering how open and extensible their classes are.

March 16, 2009

Manifesto for Software Craftmanship

manifesto_for_software_craftmanship.png


Go and sign up yourself! Support our craft and help to make better software!

March 09, 2009

Heiko W. Rupp @ JUG-Ka

Heiko W. Rupp of Red Hat (author of the first German JBoss book) is going to talk about "System management with RHQ and JBoss ON 2" at the Java Users Group Karlsruhe this coming Wednesday. The JBoss Operations Network (ON) management platform is a centralized system for managing the JBoss middleware.

The talk starts at 7:15pm and takes place at University of Karlsruhe. Get the latest updates of the JUG-Ka at our Google Group or sign up for XING.

March 02, 2009

Book Review: Practical API Design

Apress was kind enough to pass me a copy of this book, which I agreed to review in return.

Practical API Design: Confessions of a Java Framework Architect is the book I've always been waiting for. Jaroslav Tulach, the founder and architect of NetBeans, created a highly recommend read for everyone in charge of developing APIs.

But even if it's not your job to define interfaces, you are somewhat alway on the other side consuming them and it's good to know what drives evolution of the APIs you work with.

The book consists of 3 parts:

Part 1 is called "Theory and Justification". It defines the terminology and background which gives you the necessary foundation to explain and justify API design.

Let me give you and example: Have you ever had problems explaining your design to a colleague? You couldn't find the right words to reasonably highlight your decision, but you know it was right? The only justification was your intuition and the feeling that your design was the right choice. Does that sound familiar?

That's where Part 1 of this book comes in and tries to give you a tool to justify and even measure the quality of your design decisions: Selective Cluelessness. It's a principle which is based on the assumption that you can achieve more by knowing less:

"The more good APIs we have, the bigger the systems we'll be able to build without understanding all their details."


"Practical Design" is Part 2 and basically puts the theory highlighted in the first part to practice. Using Java, the author provides a set of what he calls API design patterns. They are design patterns in the traditional sense, but with a focus on evolution. Most of them accompanied by an examples the NetBeans APIs. It doesn't matter if you are not familiar with NetBeans. Due to the author's years of experience with NetBeans, he does a great job explaining the problems it was facing and how they came with a solution, which evolved into an API design pattern.

..., it's slightly more complicated to design a universe than building a house. As a result, we need an enhanced version of the design patters. We need patterns that help us building a "universe".


Part 3 of the book, "Daily Life", is a collection of advices on how to bugfix, evolve and maintain an API. The author points out how important versioning is and how NetBeans solves such a problem. He highlights the importance of compatibility and how to keep the promises to the users of your APIs.

The theory and initial design are just the tip of the iceberg. The rest is the real work.


I'm really glad I read this book, although it took me quite a while. The reason is not the 365 pages. It was all the moments I had during reading it. So many times I was reminded of mistakes I made in APIs I previously designed. I often pondered on whether a solution suggested in the book was better than the one I came up with. I think that's what makes a book interesting, if it makes you think and critically review your own solutions.

I enjoyed taking the journey through the API universe and learning how to design an API in a selective cluelessness way. As for the reasons why you should read this book:

... when you understand the API world, its needs and its laws of evolution, you can shape it into a form containing all that the creators of the oldest and most perfect science always searched for - beauty, truth and elegance. A properly API universe ain't a bad place to be.



com_channels

  • mail(dlinsin@gmail.com)
  • jabber(dlinsin@gmail.com)
  • skype(dlinsin)

recent_postings

loading...