Monday, August 22, 2011

Tired of Getters and Setters? Lombok them!

I love Java. There is a lot of amazing stuff being build with it every minute and I really love being part of that community. But, to be honest, there is one single thing, that I hate. That is the JavaBeans™ architecture.
Not completely but the basic requirements to have a nullary constructor and property access using getter and setter methods. All this is stupid overhead, hard to maintain and change. But there is a little helper out there, that made my life more easier. It's project Lombok. Here is a very short overview about using Lombok with ManagedBeans.

Getting Started

Grep your favorite IDE (Eclipse/NetBeans) and start your new Maven based Java EE 6 web-project. Add the Lombok dependency to your pom.xml:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>0.10.0</version>
<scope>compile</scope>
</dependency>
And you are done. If you are not using Maven, get your copy of the lombok.jar from the project's website. That's all. Your done.

Coding the ManagedBean with Lombok

Create a new class named "Customer" and add some String fields: public class Customer {
private String name;
private String sure_name;
private String nickname;
}
But what happens if you try to use this one as @ApplicationScoped @ManagedBean? For sure your JSF runtime will complain about missing properties and constructors. But instead of adding all those boilerplate code you simply add @Data as an additional annotation to your class which should look like this now: @ManagedBean
@ApplicationScoped
@Data
public class Customer {
private String name;
private String surename;
private String nickname;
}
Now get a simple JSF frontend and add some: <h:inputText id="name" value="#{customer.name}" /> for every field in your bean to it and you are done. Everything works. And nobody is complaining about missing properties anymore!

What happened?
The offered Lombok annotation @Data simply tells your IDE to generate all the boilerplate code for you silently. And this is done during compile time, so you usually don't have to care about lombok being on your runtime path at all. There are some exceptions to this rule with other Lombok features but it's true for this simple example. @Data especially is a convenient shortcut annotation that bundles the features of @ToString, @EqualsAndHashCode, @Getter / @Setter and @RequiredArgsConstructor together: In other words, @Data generates all the boilerplate that is normally associated with simple POJOs (Plain Old Java Objects) and beans: getters for all fields, setters for all non-final fields, and appropriate toString, equals and hashCode implementations that involve the fields of the class, and a constructor that initializes all final fields, as well as all non-final fields with no initializer that have been marked with @NonNull or @NotNull, in order to ensure the field is never null. If you look at the generated source you see that the compiled file is there and contains all your well known boilerplate:
>javap Customer
Compiled from "Customer.java"
public class net.eisele.lombokdemo.Customer {
public java.lang.String process();
public net.eisele.lombok_jsf.Customer();
public java.lang.String getName();
public java.lang.String getSurename();
public java.lang.String getNickname();
public void setName(java.lang.String);
public void setSurename(java.lang.String);
public void setNickname(java.lang.String);
public boolean equals(java.lang.Object);
public boolean canEqual(java.lang.Object);
public int hashCode();
public java.lang.String toString();
}

That's all?
Not really :) There are some more features Lombok has to offer. e.g. a simple @Log which gives you access to a private static final java.util.logging.Logger log
field to simply log what's happening. You can also have a @Log4j, @CommonsLog or even a @Slf4j as alternatives. If you are looking for all the goddess, look at the project's feature overview page.

Risks?
One could argue that having all those fancy stuff done by a compiler could lead to unexpected results and probably introduces errors nobody likes. Right. But even if you don't like all those automated and transparent generation, you could simply Delombok your source files. This would simply replace all lombok annotations with the generated code and gives your access to a complete codebase. So it's a calculable risk using Lombok and I must admit: I love it.

Java Enterprise Edition 6: The Most Elegant Enterprise Java

Not everywhere is summer slump. The JBoss guys are hard at work (as always) and Andrew Lee Rubinder (@ALRubinger) published a new Java EE 6 DZone Refcard today. It's your quick and handy guide which provides a short intro about the Platform, Common Annotations For Java, Java Servelet 3.0, JavaServer Faces 2.0 and Enterprise JavaBeans 3.
You can get your copy directly from DZone. It's free to view online and you can download your personal PDF (2,51 MB) free of charge, if you have a DZone account.

DZone Refcards are free Cheat Sheets for Developers which save you time and guarantees that you stay well-informed. They are written by bestselling authors and leading experts and provide reliable information on major developer topics.Filled with useful tips and source code examples the downloadable PDFs look great on-screen or printed from your printer.

Andrew Lee Rubinger is an Open Source Software Engineer and Author. Most of you will know him for his book “Enterprise JavaBeans 3.1" from O’Reilly Media. But he is also a Member of the JBoss Application Server development team and technical lead of the ShrinkWrap project.

Thursday, August 18, 2011

Working with Money in Java

I've a new favorite blog. Peter Lawrey is running a blog called "Vanilla Java". It's all about "Understanding how Core Java really works". Peter is a DZone MVB and pushing some posts about speed and size of different objects and technologies in Java. One particular post recently caught my attention and made me think.
Picture: Images_of_Money (CC BY 2.0)
It is "Double your money again" in which Peter talks about rounding problems while using java.lang.Double and it's primitive type double. This is a field I know a little about and have seen a lot. And I thought I share a bit about my experiences here.

If you are using double you run into trouble
Mainly because of the fact, that double (Wrapper: Double) is a double-precision 64-bit IEEE 754 floating point. It's not meant for keeping exact decimal values.

double result = 0.1 + 0.2 - 0.3;
System.out.println("0.1 + 0.2 - 0.3=" + result);
=&gt; 0.1 + 0.2 - 0.3=5.551115123125783E-17

The .toString() representation follows some (not so simple) rules:
If m is greater than or equal to 10-3 but less than 107, then it is represented as the integer part of m, in decimal form with no leading zeroes, followed by '.' ('\u002E'), followed by one or more decimal digits representing the fractional part of m.
If m is less than 10-3 or greater than or equal to 107, then it is represented in so-called "computerized scientific notation." Let n be the unique integer such that 10n ≤ m &lt; 10n+1; then let a be the mathematically exact quotient of m and 10n so that 1 ≤ a &lt; 10. The magnitude is then represented as the integer part of a, as a single decimal digit, followed by '.' ('\u002E'), followed by decimal digits representing the fractional part of a, followed by the letter 'E' ('\u0045'), followed by a representation of n as a decimal integer, as produced by the method Integer.toString(int).
(Source: java.lang.Double)
Following this: you run into trouble with presentation and calculations which you have to handle.

Rounding Tie-breaking
Back to Peter's initial post. He is proposing to use a rounding algorithm when working with doubles to prevent undetermined effects. The little methods he shows are nice: But Java already knows about rounding and further on, it already knows about more than one rounding algorithm. Now it's up to you to choose the best one. We have a couple of them at hand (compare wikipedia article). Let's go:

ROUND_CEILING
Rounding mode to round towards positive infinity.
ROUND_DOWN 
Rounding mode to round towards zero.
ROUND_FLOOR 
Rounding mode to round towards negative infinity.
ROUND_HALF_DOWN 
Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round down.
ROUND_HALF_EVEN 
Rounding mode to round towards the "nearest neighbor" unless both neighbors are equidistant, in which case, round towards the even neighbor.
ROUND_HALF_UP 
Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round up.
ROUND_UP 
Rounding mode to round away from zero.

To get the results processed with the so-called Gaussian- , or bankers' rounding all you have to do is to set a scale on your BigDecimal.

double result = 0.1 + 0.2 - 0.3;
BigDecimal resultRounded = new BigDecimal(result)
                           .setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("0.1 + 0.2 - 0.3=" + resultRounded);
 =&gt; 0.1 + 0.2 - 0.3=0.00


There is some conversion involved here. As you can see, I'm converting the double to a BigDecimal. That means, you cannot use it for further calculations. if you need a double you probably can do the following:

double result = new BigDecimal(value).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();


But as Peter states in the comments on his post this is probably not performing very well.

BigDecimal != Amount
Even if you now know how to get rid of the rounding problem you still have a simple number at hand and not an amount. Which means, you have to fix the presentation. What should be simple, isn't. As always you have a couple of approaches to evaluate.

DecimalFormat
The preferred way is to use the DecimalFormat class to format decimal numbers into locale-specific strings. This class allows you to control the display of leading and trailing zeros, prefixes and suffixes, grouping (thousands) separators, and the decimal separator. You can grep an instance by using the NumberFormat.getCurrencyInstance(locale):

double result = 0.1 + 0.2 - 0.3;
BigDecimal result2 = new BigDecimal(result).setScale(2, BigDecimal.ROUND_HALF_UP);
NumberFormat form = NumberFormat.getCurrencyInstance(new Locale("de", "DE"));
System.out.println("Amount: " + form.format(result2));
 =&gt; Amount: 0,00 €

Currency
If you need more control than you already have with the preferred way, you could think about using the Currency class. Look at java.util.Currency as it represents a currency identified by it's ISO 4217 currency code. Another alternative is to get it with a locale.
Currency curr = Currency.getInstance("EUR");
Currency currLoc = Currency.getInstance(new Locale("de", "DE"));
System.out.println("currency EUR in en_US: "+curr.getSymbol(new Locale("de", "DE")));
System.out.println("currency in de_DE for en_US: "+currLoc.getSymbol(new Locale("en", "US")));
 =&gt;currency EUR in en_US: €
 =&gt;currency in de_DE for en_US: EUR


Bottom line
If you have a chance to, go ahead with the build in functionality. Both the rounding issues as the i18n stuff can be addressed with the set of utilities and classes available. If you tend to have your own Amount class using the custom currency mechanisms be aware of the fact, that you have to place the currency symbol in front or afterwards depending on the locale you are in. So: There is not much magic inside and if you use it the right way, you don't have to fear working with money in Java at all.

I'm speaking at DOAG 2011 Conference and Exhibition, 15th-17th November 2011

It's holiday season and likewise quite is my blog. Things to prepare, thoughts to test, ideas to have. A simple and quick reminder for all my German readers: I'm speaking at DOAG 2011 Conference and Exhibition, 15th-17th November 2011. (see on lanyrd.com)
In more than 400 speakers slots the DOAG 2011 Conference, which takes place November 15th-17th, 2011 in Nuremberg, provides current information on the successful use of the Oracle products as well as practical tips and tricks and exchange of experience. The varity of the presentations is addressing and covering all important fields of the Oracle products - ranging from database to middleware and business applications. This is the optimal opportunity to enlarge your network and to profit from the experiences and know-how of all users.

Find the complete schedule online (German only). My two sessions are on day two:
16.11.2011, Stream: Java
High Performance JPA mit Coherence 
10:00 - 10:45
Room: Hongkong

16.11.2011, Stream: Oracle Middleware
Introduction to Java EE 7 
12:00 - 12:45
Room: Prag

Beside this I will contribute one part to the Oracle ACE Director live demo about SOA and BPM.
17.11.2011, Stream: SOA/BPM
"Where the rubber meets the road" - 8000 seconds of practice.
12:00 - 14:45
Room: Oslo

If you haven't, there is still time to register (German website) ! Looking forward seeing you there!

Monday, August 1, 2011

Java Champions at JavaOne vs. ACEs at OpenWorld 2011 - 15:45

Have you seen the otn post from end of July? 163 Oracle ACE Sessions at Oracle OpenWorld 2011.
That's a huge number. Compared to the 358 ACEs and ACE Directors out there, this makes a
total of 45% of the overall ACEs speaking at "their" number one conference.
But what the OpenWorld is to the ACEs that should JavaOne be for the Java Champions, right? Consider this another conference analysis, like I did a few times before.

The Java Champions are an exclusive group of passionate Java technology and community leaders who are community-nominated and selected under a project sponsored by Oracle. Java Champions get the opportunity to provide feedback, ideas, and direction that will help Oracle grow the Java Platform. This interchange may be in the form of technical discussions and/or community-building activities with Oracle's Java Development and Developer Program teams. According to their bio page, there are 126 active JCs.

If you take this information and match it against the speaker page of the most recently published JavaOne 2011 content catalog you get the amazing number of: 15%. That's the percentage of actively talking JCs at JavaOne this year. Compared with the Oracle ACEs this is .. let's call it: A little less.

Of course there are many reasons for that. Fist is that Google is obviously still boycotting JavaOne. Another might be, that there are many researchers listed which simply doesn't fit into the content catalog. Any other ideas? Let me know!

Here is a list of sessions by Java Champions

Andres Almiray
17581 - Painless Desktop Application Development: The Griffon Experience

Adam Bien
21622 - Rethinking Best Practices with Java EE 6
21641 - Java EE 6: The Cool Parts
23423 - The Road to Java EE 7: Is It All About the Cloud?

Stephen Chin
17960 - JavaFX 2.0 with Alternative Languages
22021 - JFXtras 2.0: Open Source Extensions for JavaFX
22122 - Moving to the Client: JavaFX and HTML5
22125 - XML-Free Programming: Java Server and Client Development Without <>

Bert Ertman
24423 - Best Practices for Migrating Spring Applications to Java EE 6

Jeff Genender
26521 - Using Apache Camel and Java EE in an OSGi World

Michael Hüttermann
18180 - Agile Application Lifecycle Management (ALM)

Heinz Kabutz
24466 - Are Your Garbage Collection Logs Speaking to You?

Josh Marinacci
25088 - Building Java Apps for Non-Java Mobile Platforms with GWT and PhoneGap

Kevin Nilson
22122 - Moving to the Client: JavaFX and HTML5

Kirk Pepperdine
24466 - Are Your Garbage Collection Logs Speaking to You?

Paul Perrone
24721 - LincVolt: A Robotic Electric 1959 Lincoln
24741 - LaserTag: Fusing Laser and RFID for Perimeter Security

Peter Pilgrim
24085 - Progressive JavaFX 2.0 Custom Components

Michael Santos
25184 - The Massive Challenge: Java Technologies for Modern Enterprise Applications

Howard Lewis Ship
25680 - Have Your Cake and Eat It Too: Metaprogramming Techniques for Java

Bruce Snyder
22585 - Simplify Your JMS Code with Spring

Bruno Souza
25242 - Instant Cloud: Just Add Java
33960 - General Session: Java User Groups Sunday

Regina ten Bruggencate
24243 - Women in Java: An Unconference

Dick Wall
22060 - Script Bowl 2011: A Scripting Languages Shootout

James Weaver
22523 - The Return of Rich-Client Java
23283 - Visualization of Geomaps and Topic Maps with JavaFX 2.0