Friday, August 21, 2015

Book Review: Getting Started with Hazelcast - Second Edition

I recently purchased an electronic version of the Second Edition of Getting Started with Hazelcast as part of the recent Packt Publishing Skill Up Promotion. The book, written by Mat Johns, has the subtitle, "Get acquainted with the highly scalable data grid, Hazelcast, and learn how to bring its powerful in-memory features into your application." The book consists of eleven chapters and an appendix spanning approximately 120 pages.

Preface

The Preface of Getting Started with Hazelcast (Second Edition) provides brief descriptions of a sentence or two each summarizing the contents of the book's eleven chapters and its appendix. The Preface states that Getting Started with Hazelcast is intended for "Java developers, software architects, or DevOps looking to enable scalable and agile data within their applications." It recommends that readers have access to a JDK (at least JDK 6 but preferably JDK 8), a Java IDE, and Maven.

Chapter 1: What is Hazelcast?

The relatively short initial chapter of the Second Edition of Getting Started with Hazelcast introduces Hazelcast after first explaining the need for it with multiple simple graphics. The chapter describes Hazelcast as more than a cache and as an "in-memory data grid that supports a number of distributed collections, processors, and features."

Chapter 2: Getting off the Ground

The second chapter of Getting Started with Hazelcast explains and illustrates downloading Hazelcast from hazelcast.org/download/. The specific version downloaded and used for purposes of the Second Edition of Getting Started with Hazelcast is Hazelcast 3.5 (hazelcast-3.5.jar).

Chapter 2 demonstrates using ConsoleApp to use the command line to interact with simple Java applications using Hazelcast and to demonstrate Hazelcast's support for automatically supporting multiple clustered nodes. Code listings and associated explanatory text in this chapter introduce HazelcastInstance, working with an instance of distributed Map provided by HazelcastInstance.getMap(String), working with a distributed instance of Set provided by HazelcastInstance.getSet(String), working with a concurrent, distributed List instance provided by HazelcastInstance.getList(String), working with a concurrent, blocking, and distributed queue provided by HazelcastInstance.getQueue(String), and working with a distributed multimap instance (many values associated with a single key) provided by HazelcastInstance.getMultiMap(String).

Getting Started with Hazelcast's second chapter discusses "using predefined indexes" to search Hazelcast maps in a method similar to search capabilities provided by databases. This section provides an example of using SqlPredicate and lists the "limited subset of SQL" supported by SqlPredicate. The section also introduces other implementations of the Predicate interface (PredicateBuilder and PagingPredicate).

Another section of the second chapter covers using the hazelcast.xml file to configure Hazelcast for map eviction and covers the parameters named hazelcast.xml such as max-size, eviction-policy, and eviction-percentage.

Chapter 3: Going Concurrent

Chapter 3 of Getting Started with Hazelcast begins with more description on Hazelcast's IMap and IQueue, how they extend ConcurrentMap and BlockingQueue respectively, and the implications of those extensions. The chapter also introduces Hazelcast's distributed locking, its "cluster-wide unique identifier generator" (IdGenerator) and its JMS-inspired broadcast messaging system.

Chapter 4: Divide and Conquer

Getting Started with Hazelcast's fourth chapter begins with the assertion that Hazelcast's "distributed nature" of its "data persistence" enables applications to "achieve high levels of reliability, scalability, and performance." The chapter discusses partitions across clusters, partitions backing each other up, scaling up the cluster by adding more nodes, acquiring and using a ReplicatedMap to ensure data is available on every node, using partition groups, merge policies (PassThroughMergePolicy, PutIfAbsentMapMergePolicy, HigherHitsMapMergePolicy, and LatestUpdateMapMergePolicy), and Hazelcast 3.5 cluster quorums.

Chapter 5: Listening Out

The fifth chapter of Getting Started with Hazelcast discusses using Hazelcast's distributed events and listeners. The chapter introduces "collection listeners" (EntryListener, ItemListener, MessageListener, QuorumListener) and "cluster listeners" (DistributedObjectListener, MembershipListener, LifecycleListener, and MigrationListener). After the listing and briefy introductions to each of these listeners, the chapter delves more deeply into how they are configured (XML and in Java code) and can be used.

Chapter 6: Spreading the Load

Chapter 6 of Getting Started with Hazelcast discusses how Hazelcast provides the "ability to share the computational power in the form of a distributed executor" and how this is useful for "applications that require a lot of computational and data processing power." The chapter includes examples of applying IExecutorService, PartitionAware, HazelcastInstanceAware, and EntryProcessor.

Chapter 7: Gathering Results

Getting Started with Hazelcast's seventh chapter is its "big data" chapter. This chapter opens with an explanation of why "big data has proven to be a bit of a trendy buzzword of late." Brief history and background of MapReduce is provided. I like the simple explanation and graphic used in this introductory discussion regarding MapReduce.

Chapter 7 moves from general MapReduce theory to discussion of the Hazelcast's MapReduce implementation. It demonstrates via examples use of Reducer, JobCompleteableFuture, and working with Hazelcast aggregations with Java SE 6 and much more concise JDK 8 syntax.

Chapter 8: Typical Deployments

The eighth chapter of Getting Started with Hazelcast discusses determining the proper deployment strategy with Hazelcast for different types of applications. The chapter talks about "separat[ing] our application from the data cluster" and introduces Hazelcast's DataSerializable interface. The chapter concludes with coverage of "various architectural setups" that are described briefly, illustrated with simple graphics, and discussed in terms of trade-offs (advantages and disadvantages of each approach).

Chapter 9: From the Outside Looking In

Chapter 9 of Getting Started with Hazelcast covers two approaches for interacting with Hazelcast for non-Java/non-JVM clients. The chapter introduces the Hazelcast Memcache Client and provides simple demonstrations of using it with Python and PHP. The ninth chapter also introduces Hazelcast's support for REST APIs.

Chapter 10: Going Global

The tenth chapter of Getting Started with Hazelcast looks at using Hazelcast in conjunction with cloud computing environments. The main focus of the chapter is on two alternate "mechanisms of cluster discovery" to IP multicast: manually controlled unicast configuration and discovery via Amazon AWS management APIs. These configurations are shown by example with changes to the hazelcast.xml XML file. The chapter also discusses how to "configure Hazelcast to push entries from our local cluster to a remote cluster by defining a Wide Area Network (WAN) replication policy."

Chapter 11: Playing Well with Others

The final chapter of Getting Started with Hazelcast discusses how "Hazelcast provides ... support to use and extend a few popularly used libraries" and how Hazelcast "provides implementations of standardized interfaces." The chapter demonstrates using Spring with Hazelcast (hazelcast-spring-3.5.jar) for dependency injection, using Hibernate with Hazelcast (hazelcasthibernate3-3.5.jar/hazelcasthibernate4-3.5.jar) for caching of "legacy applications," using Hazelcast as an implementation of the standard JCache API, using Hazelcast's Cluster Management Center (mancenter-3.5.war), and enabling Hazelcast JMX support.

Appendix: Configuration Summary

The appendix provides a single location reference of the various Hazelcast configuration examples presented in the book's chapters.

General Observations

  • The author of Second Edition of Getting Started with Hazelcast, Mat Johns, is one of two currently highlighted Hazelcast Heroes. His "Hazelcast Cred" states, "Literally wrote the book on Hazelcast, entitled 'Getting Started with Hazelcast'."
  • The title "Getting Started with Hazelcast" is appropriate for this book. It delivers on providing a good starting point for installing, configuring, and beginning to use Hazelcast.
    • A reader of this book will be well equipped in terms of concepts and vernacular to reference Mastering Hazelcast, the highly approachable Hazelcast documentation, and blogs and forums on Hazelcast with the background and context provided by this book.
    • Other than the Hazelcast Manual and Mastering Hazelcast (both of which are provided by Hazelcast), the only book I have found devoted to Hazelcast is Getting Started with Hazelcast.
    • I appreciate that Getting Started with Hazelcast covers using Hazelcast in different architectural setups and provides a narrative the shows how differente Hazelcast features or deployments can be used to address different needs. The book not only shows the semantics or mechanics of using Hazelcast, but it also discusses why one would choose to use Hazelcast in different ways in different situations.
  • It's typically a good sign regarding a technical book's reception when there is more than one edition of that book. A quick browse of book reviews of the first edition of Getting Started with Hazelcast shows that this book has been generally well received.
    • The first edition of Getting Started with Hazelcast provides instructions on downloading and uses Hazelcast 2.6 for its examples while the second edition references Hazelcast 3.5.
    • The first edition of Getting Started with Hazelcast was published in August 2013 and this second edition was published in July 2015.
    • The second edition is roughly 20 pages lengthier than the first edition.
    • The second edition of Getting Started with Hazelcast adds three new chapters on trendy topics related to Hazelcast: 7 ("Gathering Results" / Big Data), 10 ("Going Global" / Cloud), and 11 ("Playing Well with Others" / Spring/Hibernate/JCache/JMX).
  • Most of the graphics in Getting Started with Hazelcast are simple graphics with black font on white background, though there are a few graphics with color and a few color screen snapshots in the electronic version of the book.
  • Code listings are black text on white background with no syntax color highlighting and no line numbers.
    • This was a more noticeable disadvantage when I was moving between the Hazelcast Manual, Mastering Hazelcast, and Getting Started with Hazelcast at the same time and the former two electronic publications have color-coded syntax.
  • There were a few minor grammar errors and typos, but for the most part Getting Started with Hazelcast is written in a format that's easy to read and comprehend.
  • I was happy to see coverage of JCache (JSR 107) in the second edition of Getting Started with Hazelcastr and to see brief mention of enabling Hazelcast's JMX support for monitoring.
  • I would have liked to see a bit more discussion in Getting Started with Hazelcast regarding the differences between Hazelcast Enterprise and Hazelcast.

Conclusion

Overall, I can recommend the second edition of Getting Started with Hazelcast to prospective readers. My only reservation regarding recommendation of this book has nothing to do with any fault of the book, but rather is a result of the excellent Hazelcast documentation that is already available. The Hazelcast Documentation and Mastering Hazelcast are both excellent resources with the former more introductory and the latter more intermediate. It is worth noting that downloading Mastering Hazelcast does require providing one's name and an e-mail address. I personally found that Getting Started with Hazelcast provided a nice overview and background about Hazelcast and why it's important that enabled me to quickly use these additional resources as well.

Tuesday, August 18, 2015

Setting PostgreSQL psql Variable Based Upon Query Result

When using PostgreSQL's psql command-line tool to interact with a PostgreSQL database via operator interaction or script, it is not uncommon to want to set psql variables based on the results of a particular query. While PostgreSQL's procedural language PL/pgSQL supports approaches such as SELECT INTO and assignment (:=) to set PL/pgSQL variables based on a query result, these approaches are not supported for psql variable assignment.

The typical way to make a psql variable assignment is via use of \set. This allows for the setting of the psql variable to a literal value. However, there are situations in which it is desirable to set the psql variable based upon the result of a query. This is done with the \gset option in psql. Unlike the \set operation in psql which sets a variable with an explicitly specified name to an explicitly specified literal value, \gset implicitly names the psql variables after the names of the columns (or aliases if columns are aliased) returned by the query to which the \gset is associated. The \gset is specified after the query (no semicolon generally on the query) and there is no semicolon after the \gset statement (just as no semicolon should be placed after a \set statement).

It is easier to see how \gset works with a code sample. The next code listing shows a small psql file that takes advantage of \gset to set a psql variable named "name" whose value that was set by the query is displayed using psql's colon prefix notation to "echo" its value.

CREATE TABLE person
(
   name text
);

INSERT INTO person (name) VALUES ('Dustin');

SELECT name FROM person \gset
\echo :name

DROP TABLE person;

In the previous code listing, lines 8-9 are the relevant lines for this discussion (the remainder of the lines are for setup and teardown of the demonstration). Line 8 contains the query (sans semicolon) followed by \gset. A psql variable of 'name' is set by that as evidenced by the echo-ing of its value in line 9. The output showing this works looks like this in a psql terminal window:

CREATE TABLE
INSERT 0 1
Dustin
DROP TABLE
Additional Considerations When Using psql's \gset
  • Placement of a semicolon between the query and the \gset affects the output.
    • Placing a semicolon after the query and before the \gset will execute the query and display the query results before setting the variable(s).
    • Leaving the semicolon out will execute the query to populate parameters with the names of the query's columns and aliases, but will not display the actual query results.
  • There should be no semicolon after the entire statement and placing a semicolon after the \gset will mess up the variable setting.
    • Error: invalid command \gset;
  • Query being used to set variable via \gset should return exactly one row.
    • ERROR: more than one row returned for \gset
  • When a column in the SELECT clause of a query associated with \gset is aliased, there are actually two psql variable names by which the returned value can be accessed. They are the column name and the alias name.
    • This allows a psql developer to alias a predefined column to any name he or she prefers for the variable set by \gset.

Conclusion

When using psql, use \set variable_name variable_value to explicitly set a psql variable with the name provided by the first argument and an associated value provided by the second argument. To set a psql variable based on query results, append \gset after the query (without semicolon generally) and access returned values by column names (or by columns' aliased names).

Monday, August 17, 2015

Procedure-Like Functions in PostgreSQL PL/pgSQL

PostgreSQL does not support stored procedures in the sense that a database such as Oracle does, but it does support stored functions. In this post, I look at a few tactics that can make the use of a stored function in PostgreSQL (stored function and its calling code both written in PL/pgSQL) feel like using a stored procedure. These simple approaches allow developers to use PostgreSQL stored functions in a manner that is more consistent with use of stored procedures.

Stored procedures and stored functions are very similar and, in fact, I've often heard the term "stored procedure" used interchangeably for stored procedures and for stored functions. For purposes of this post, the essential differences between the two can be summarized as:

  1. Functions are created with the FUNCTION keyword and procedures are created with the PROCEDURE keyword.
  2. Stored procedures do not return a value, but stored functions return a single value.
    • The stored function's return value can be used in SELECT statements.

Because PostgreSQL PL/pgSQL only supports stored functions, the defined functions need to declare a return type. Fortunately, in the case of our emulated "stored procedure," we can declare void as the return type. This is demonstrated in the code listing below for a "Hello World" implementation written in PL/pgSQL.

CREATE OR REPLACE FUNCTION helloWorld(name text) RETURNS void AS $helloWorld$
DECLARE
BEGIN
    RAISE LOG 'Hello, %', name;
END;
$helloWorld$ LANGUAGE plpgsql;

With a PostgreSQL stored function with void return type written, we now can invoke it from a client. In this case, I will look at three approaches for calling the stored function from other PL/pgSQL code.

PL/pgSQL: Invoke Function Via SELECT Statement

One approach for calling the stored function in PL/pgSQL code is to use SELECT INTO. The most obvious disadvantage is that, in the case of a procedure-like function returning void, nothing useful being selected and so the variable being selected into must be ignored anyway. The next code listing demonstrates using SELECT INTO to invoke the procedure-like function. The variable in this example, called "dumped", will not have anything useful selected into it, but this statement successfully invoke the stored function. Besides the line shown here, I also need a line in the DECLARE section to declare the "dumped" variable.

SELECT INTO dumped helloWorld('Dustin');

PL/pgSQL: Invoke Function Via Variable Assignment

The PL/pgSQL assignment operator provides another way to invoke the procedure-like stored function. As with the previous example, this approach requires a variable ("ignored") be declared in the DECLARE section and then that variable is assigned the result of the function that returns void, making it effectively a throw-away variable as well.

ignored := helloWorld('Dustin');

PL/pgSQL: Use PERFORM to Explicitly Ignore Returned Value

The PL/pgSQL command PERFORM provides some syntactical advantages when invoking procedure-like stored functions. This command does not require a PL/pgSQL variable to be declared. This saves the line to declare the variable and avoids the pretense of setting a variable that is never really set. It's really just a shortcut for SELECT, but it's syntactically sweeter and makes for more readable code because code maintainers don't have to figure out that a statement that appears to make an assignment actually does not do so.

PERFORM helloWorld('Dustin');

Conclusion

Although PostgreSQL only supports stored "functions" (and not stored "procedures"), it provides syntax that allows for functions to take on procedure-like qualities. BY allowing stored functions to return void and be to called from PL/pgSQL code via PERFORM that expects no result value, PostgreSQL allows client code to appear as if it is invoking a stored procedure rather than a stored function.

Monday, August 10, 2015

JavaScript Survival Tools for the Java Developer

Although I've worked with JavaScript a bit here and there over the years, I have not used it as regularly or consistently as I've used Java. I have also not used it for anything nearly as complex as for what I've used Java. Therefore, it is not very surprising that moving from commonly used Java to seldom used JavaScript offers some pain points. This post looks at some tools and techniques Java developers (and developers familiar with other class-based and statically typed languages) might find helpful in transitioning to JavaScript development.

Be Aware / Beware the JavaScript Gotchas: Helpful Online Resources

Every programming language has its share of gotchas, sharp edges, traps, quirks, and corners, but it is difficult for me to think of a programming language (other than perhaps Perl) that has more of these in its fundamental design than JavaScript. The developer who is aware of these is likely still going to run into these occasionally, but awareness will help the developer reduce the number of times he or she falls into the traps.

Given the importance of understanding these JavaScript nuances, the first category of tools is online resources that provide warnings about these nuances and their effects. A good resource providing an overview of JavaScript Gotchas is Seven JavaScript Quirks I Wish I’d Known About. Other resources useful in getting familiar with nuances of JavaScript include Short Guide to JavaScript Gotchas, A Beginner's List of JavaScript Gotchas, and What are the top JavaScript pitfalls?

I have not read the book JavaScript: The Good Parts, but many Java developers who have written about their experiences with JavaScript have mentioned that this book has helped them to better understand how to properly use JavaScript. The recent blog post JavaScript Debugging Tips and Tricks is also very useful in learning about debugging JavaScript.

For me, the biggest (in terms of time spent) issues using JavaScript while using Java is the different handling of scope (and related issues such as hoisting and different meanings of this keyword that take 40 minutes to explain and differ depending on which mode is being used). JavaScript's scope rules are a bit complex (see this StackOverflow thread for a taste of how complex), but boil down for me to essentially "use var often," "embrace functions for controlling scope," and "braces don't mean anything in specifying scope."

See Where You're At with console.log

The ability to log an application's state and a description of an application's behavior is useful in programming and debugging in any programming language. Because JavaScript is a weakly and dynamically typed language, this ability to see what's happening at runtime is even more significant in JavaScript where a compiler is not going to help find "obvious" typos and mismatched interfaces. In the old days, one was typically stuck with invoking alert() to see these types of logging details. This approach lacked subtlety and placed a popup on the screen that the user clicked "OK" on to close. The advent of console.log() is a welcome addition to the JavaScript developer's tool set.

The biggest downside of console.log may be that it's not part of the DOM or JavaScript standards. However, modern major browsers all seem to support it. For those worried about a target environment browser not supporting it, a fall-back to alert can be used. The obvious advantage of console.log is that modern browsers support special windows or areas in the browser in which messages are logged rather than rendering a pop-up that requires user acknowledgement to close. For Java developers familiar with logging using Log4j or java.util.logging, console.log is much closer to what they're used to than alert.

It's also worth mentioning here that non-standard console.dir can be very handy, with its advantages being more obvious in certain browsers than others.

See Where You've Come From with console.trace

The non-standard console.trace is similar to console.log in that it's non-standard but supported by modern web browsers. What makes console.trace different than console.log is that console.trace logs the stack trace of the JavaScript execution at time of the logging invocation. This is similar to logging a thread's current stack trace in Java.

Feel at Home with Constructor Functions

Java developers are comfortable working with objects. Although JavaScript's object-orientation is prototype-based rather than class-based, the use of constructor functions makes JavaScript objects feel more like Java objects. I have discussed the use of constructor functions in greater depth in the post JavaScript Objects from a Java Developer Perspective. The book Object-Oriented JavaScript provides a thorough introduction to using JavaScript objects and I have reviewed this book in an earlier post.

Override JavaScript Objects' toString() Implementations

JavaScript, like Java, provides an implementation of toString() at its highest Object level. All JavaScript objects automatically inherit that toString() implementation via Object.prototype.toString(). Like Java's, the JavaScript Object.toString() provides only minor informative value. The same advantages that come from overriding Java class's toString() implementations apply when overriding JavaScript objects' toString() implementations. Overridden and customized JavaScript objects' toString() methods are especially helpful when used in conjunction with the just-discussed console.log.

I have written about how to override JavaScript objects' toString() methods in the posts JavaScript Objects from a Java Developer Perspective and A Java Developer's Perspective on the Power and Danger of JavaScript's Object Prototype.

Enjoy Java's Write-Once, Run Anywhere Paradigm in JavaScript

Although modern web browsers more consistently implement JavaScript features these days than they used to, there are seemingly countless frameworks available that abstract specifics of browsers' DOMs and other implementation specifics away from the developer. Arguably the most famous and most used of the JavaScript frameworks is jQuery. Most of the Java developers I know who speak positively of JavaScript are developers who use a framework such as jQuery to abstract away their need to worry about DOM and other browser implementation nuances and idiosyncrasies. As I have revisited JavaScript development off and on over the years, I've been impressed with how much the frameworks have improved in recent years compared to the quality and dearth of them several years ago. jQuery was one of the first to really make a difference in JavaScript and several introduced since then have had similarly significant impacts. Java developers understand well the value of being able to write the same code once and have it work on multiple targeted environments.

Another framework that has been popular of late, including among Java developers, is AngularJS.

IDE Familiarity Might Reduce Homesickness

A good IDE can be a valuable tool for anyone wanting to learn the basics of a new programming language. The many "holy wars" over which IDEs and text editors are best provide evidence that many developers prefer IDEs and text editors that they are used to using. Fortunately for Java developments, the dominant Java IDEs (NetBeans, IntelliJ IDEA, Eclipse) provide JavaScript development support.

Play with JavaScript Using Java's Implementation

The Oracle HotSpot JVM provides a JavaScript implementation: Rhino before Java 8 and Nashorn since Java 8.

Play with JavaScript with jsFiddle

If you read many StackOverflow answers tagged as JavaScript, you're likely to see people posting there mentioning that they had tested suggested implementations on jsFiddle. This handy online tool allows developers to "try out" JavaScript to see how it performs without need to set up a browser or other environment.

Check JavaScript with JSLint

For Java developers used to the Java compiler catching all types of minor syntactic issues, JavaScript can sometimes seem too forgiving as it quietly doesn't do what the developer is expecting because of some bad syntax. The online JSLint (The JavaScript Code Quality Tool) is very helpful in identifying JavaScript syntax issues. jslint4java is a Java wrapper for JSLint.

Debugging is Even More Helpful in JavaScript

The ability to debug code is important in any programming language, but it feels even more important in dynamically typed languages such as JavaScript where more errors are pushed to the runtime instead of being encountered earlier during compile time. There are several tools available for helping debug JavaScript applications. These include tools mentioned here such as jsFiddle, but also include browser-specific tools such as the famous and frequently used Firebug and the browers' debugger implementations (Firefox Debugger, Internet Explorer F12 debugger, and Chrome's JavaScript Debugger.

Use a Java-like Abstraction of JavaScript

For the developer who prefers static typing and some of the other advantages of Java and other languages, an approach to more comfortably "writing JavaScript" is to use a superset or abstraction of JavaScript with static characteristics. The idea of compiling from a more statically typed language into JavaScript is not new to Java developers as Google Web Toolkit (GWT) has done this for a long time. A newer implementation of this concept is provided as DukeScript, which is described as a "new technology for creating cross-platform mobile, desktop and web applications" that "are plain Java applications that internally use HTML5 technologies and JavaScript for rendering."

Another option for those wishing to generate JavaScript while using constructs they are familiar with in Java is use of TypeScript, "a typed superset of JavaScript that compiles to plain JavaScript." TypeScript provides stronger typing, classes, interfaces, and other concepts that Java and C# developers are familiar and comfortable with. Many of us who use Java, C++, C#, and languages such as these have learned to love the advantages of strongly typed programming languages and TypeScript presents many of those advantages to us in JavaScript.

Conclusion

JavaScript has become a widely popular and ubiquitous programming language. In several ways, it is quite different from other popular programming languages such as Java and C#. Although experience in any one programming language is generally beneficial in learning a different programming language, there have actually been times that my "thinking in Java" has almost been a detriment when writing JavaScript due to some of the subtle (from a syntax perspective) but drastic (from a behavior perspective) differences in the two languages. This post has outlined some of the tools that I've found helpful for being more effective when developing JavaScript from a primarily Java background.

Monday, July 27, 2015

Java Numeric Formatting: DecimalFormat

In the post Java Numeric Formatting, I described and demonstrated some of the useful instances provided by NumberFormat static methods such as NumberFormat.getNumberInstance(Locale), NumberFormat.getPercentInstance(Locale), NumberFormat.getCurrencyInstance(Locale), and NumberFormat.getIntegerInstance(Locale). It turns out that all of these instances of abstract NumberFormat are actually instances of DecimalFormat, which extends NumberFormat.

The next code listing and the associated output demonstrate that all instances returned by NumberFormat's "getInstance" methods are actually DecimalFormat instances. What differentiates these instances of the same DecimalFormat class is the settings of their attributes such as minimum and maximum integer digits (digits to the left of the decimal point) and minimum and maximum number of fraction digits (digits to the right of the decimal point). They all share the same rounding mode and currency settings.

Instances Provided by NumberFormat.getInstance() Are DecimalFormat Instances
/**
 * Write characteristics of provided Currency object to
 * standard output.
 *
 * @param currency Instance of Currency whose attributes
 *    are to be written to standard output.
 */
public void printCurrencyCharacteristics(final Currency currency)
{
   out.print("\tCurrency: " + currency.getCurrencyCode() 
      + "(ISO 4217 Code: " + currency.getNumericCode() + "), ");
   out.println(currency.getSymbol() + ", (" + currency.getDisplayName() + ")");
}

/**
 * Writes characteristics of provided NumberFormat instance
 * to standard output under a heading that includes the provided
 * description.
 *
 * @param numberFormat Instance of NumberFormat whose key
 *    characteristics are to be written to standard output.
 * @param description Description to be included in standard
 *    output.
 */
public void printNumberFormatCharacteristics(
   final NumberFormat numberFormat, final String description)
{
   out.println(description + ": " + numberFormat.getClass().getCanonicalName());
   out.println("\tRounding Mode:           " + numberFormat.getRoundingMode());
   out.println("\tMinimum Fraction Digits: " + numberFormat.getMinimumFractionDigits());
   out.println("\tMaximum Fraction Digits: " + numberFormat.getMaximumFractionDigits());
   out.println("\tMinimum Integer Digits:  " + numberFormat.getMinimumIntegerDigits());
   out.println("\tMaximum Integer Digits:  " + numberFormat.getMaximumIntegerDigits());
   printCurrencyCharacteristics(numberFormat.getCurrency());
   if (numberFormat instanceof DecimalFormat)
   {
      final DecimalFormat decimalFormat = (DecimalFormat) numberFormat;
      out.println("\tPattern: " + decimalFormat.toPattern());
   }
}

/**
 * Display key characteristics of the "standard"
 * NumberFormat/DecimalFormat instances returned by the static
 * NumberFormat methods getIntegerInstance(), getCurrencyInstance(),
 * getPercentInstance(), and getNumberInstance().
 */
public void demonstrateDecimalFormatInstancesFromStaticNumberFormatMethods()
{
   final NumberFormat integerInstance = NumberFormat.getIntegerInstance();
   printNumberFormatCharacteristics(integerInstance, "IntegerInstance");
   final NumberFormat currencyInstance = NumberFormat.getCurrencyInstance();
   printNumberFormatCharacteristics(currencyInstance, "CurrencyInstance");
   final NumberFormat percentInstance = NumberFormat.getPercentInstance();
   printNumberFormatCharacteristics(percentInstance, "PercentInstance");
   final NumberFormat numberInstance = NumberFormat.getNumberInstance();
   printNumberFormatCharacteristics(numberInstance, "NumberInstance");
}

Although my previous post and this post so far have demonstrated obtaining instances of DecimalFormat via static NumberFormat access methods, DecimalFormat also has three overloaded constructors DecimalFormat(), DecimalFormat(String), and DecimalFormat(String, DecimalFormatSymbols). Note, however, that there is a warning in DecimalFormat's Javadoc documentation stating, "In general, do not call the DecimalFormat constructors directly, since the NumberFormat factory methods may return subclasses other than DecimalFormat." My next few examples do instantiate DecimalFormat instances with their direct constructors despite that Javadoc warning because there is no harm in this case of doing so.

Instances of DecimalFormat support a great degree of control over the presentation formatting of decimal numbers. The following code runs the standard set of numbers used in the earlier example against a variety of different custom patterns. The screen snapshot after the code listing shows how these numbers are rendered when these patterns are applied.

/**
 * Apply provided pattern to DecimalFormat instance and write
 * output of application of that DecimalFormat instance to
 * standard output along with the provided description.
 *
 * @param pattern Pattern to be applied to DecimalFormat instance.
 * @param description Description of pattern being applied.
 */
private void applyPatternToStandardSample(
   final String pattern, final String description)
{
   final DecimalFormat decimalFormat = new DecimalFormat(pattern);
   printHeader(description + " - Applying Pattern '" + pattern + "'");
   for (final double theDouble : ourStandardSample)
   {
      out.println(
         theDouble + ": " + decimalFormat.format(theDouble));
   }
}

/**
 * Demonstrate various String-based patters applied to
 * instances of DecimalFormat.
 */
public void demonstrateDecimalFormatPatternStringConstructor()
{
   final String sixFixedDigitsPattern = "000000";
   applyPatternToStandardSample(sixFixedDigitsPattern, "Six Fixed Digits");
   final String sixDigitsPattern = "###000";
   applyPatternToStandardSample(sixDigitsPattern, "Six Digits Leading Zeros Not Displayed");
   final String percentagePattern = "";
   applyPatternToStandardSample(percentagePattern, "Percentage");
   final String millePattern = "\u203000";
   applyPatternToStandardSample(millePattern, "Mille");
   final String currencyPattern = "\u00A4";
   applyPatternToStandardSample(currencyPattern, "Currency");
   final String internationalCurrencyPattern = "\u00A4";
   applyPatternToStandardSample(internationalCurrencyPattern, "Double Currency");
   final String scientificNotationPattern = "0.###E0";
   applyPatternToStandardSample(scientificNotationPattern, "Scientific Notation");
}
==================================================================
= Six Fixed Digits - Applying Pattern '000000'
==================================================================
NaN: �
0.25: 000000
0.4: 000000
0.567: 000001
1.0: 000001
10.0: 000010
100.0: 000100
1000.0: 001000
10000.0: 010000
100000.0: 100000
1000000.0: 1000000
1.0E7: 10000000
Infinity: ∞
==================================================================
= Six Digits Leading Zeros Not Displayed - Applying Pattern '###000'
==================================================================
NaN: �
0.25: 000
0.4: 000
0.567: 001
1.0: 001
10.0: 010
100.0: 100
1000.0: 1000
10000.0: 10000
100000.0: 100000
1000000.0: 1000000
1.0E7: 10000000
Infinity: ∞
==================================================================
= Percentage - Applying Pattern ''
==================================================================
NaN: �
0.25: %25
0.4: %40
0.567: %57
1.0: %100
10.0: %1000
100.0: %10000
1000.0: %100000
10000.0: %1000000
100000.0: %10000000
1000000.0: %100000000
1.0E7: %1000000000
Infinity: %∞
==================================================================
= Mille - Applying Pattern '‰00'
==================================================================
NaN: �
0.25: ‰250
0.4: ‰400
0.567: ‰567
1.0: ‰1000
10.0: ‰10000
100.0: ‰100000
1000.0: ‰1000000
10000.0: ‰10000000
100000.0: ‰100000000
1000000.0: ‰1000000000
1.0E7: ‰10000000000
Infinity: ‰∞
==================================================================
= Currency - Applying Pattern '¤'
==================================================================
NaN: �
0.25: $0
0.4: $0
0.567: $1
1.0: $1
10.0: $10
100.0: $100
1000.0: $1000
10000.0: $10000
100000.0: $100000
1000000.0: $1000000
1.0E7: $10000000
Infinity: $∞
==================================================================
= Double Currency - Applying Pattern '¤'
==================================================================
NaN: �
0.25: $0
0.4: $0
0.567: $1
1.0: $1
10.0: $10
100.0: $100
1000.0: $1000
10000.0: $10000
100000.0: $100000
1000000.0: $1000000
1.0E7: $10000000
Infinity: $∞
==================================================================
= Scientific Notation - Applying Pattern '0.###E0'
==================================================================
NaN: �
0.25: 2.5E-1
0.4: 4E-1
0.567: 5.67E-1
1.0: 1E0
10.0: 1E1
100.0: 1E2
1000.0: 1E3
10000.0: 1E4
100000.0: 1E5
1000000.0: 1E6
1.0E7: 1E7
Infinity: ∞

For my last two examples of applying DecimalFormat, I will acquire the instance of DecimalFormat via the preferred approach of using NumberFormat.getInstance(Locale). The first code listing demonstrates different locales applied to the same double and then the output format from each.

/**
 * Provides an instance of DecimalFormat based on the provided instance
 * of Locale.
 *
 * @param locale Locale to be associated with provided instance of
 *    DecimalFormat.
 * @return Instance of DecimalFormat associated with provided Locale.
 * @throws ClassCastException Thrown if the object provided to me
 *    by NumberFormat.getCurrencyInstance(Locale) is NOT an instance
 *    of class {@link java.text.DecimalFormat}.
 */
private DecimalFormat getDecimalFormatWithSpecifiedLocale(final Locale locale)
{
   final NumberFormat numberFormat = NumberFormat.getCurrencyInstance(locale);
   if (!(numberFormat instanceof DecimalFormat))
   {
      throw new ClassCastException(
         "NumberFormat.getCurrencyInstance(Locale) returned an object of type "
            + numberFormat.getClass().getCanonicalName() + " instead of DecimalFormat.");
   }
   return (DecimalFormat) numberFormat;
}

/**
 * Demonstrate formatting of double with various Locales.
 */
public void demonstrateDifferentLocalesCurrencies()
{
   final double monetaryAmount = 14.99;
   out.println("Locale-specific currency representations of " + monetaryAmount + ":");
   out.println("\tLocale.US:            "
      + getDecimalFormatWithSpecifiedLocale(Locale.US).format(monetaryAmount));
   out.println("\tLocale.UK:            "
      + getDecimalFormatWithSpecifiedLocale(Locale.UK).format(monetaryAmount));
   out.println("\tLocale.ENGLISH:       "
      + getDecimalFormatWithSpecifiedLocale(Locale.ENGLISH).format(monetaryAmount));
   out.println("\tLocale.JAPAN:         "
      + getDecimalFormatWithSpecifiedLocale(Locale.JAPAN).format(monetaryAmount));
   out.println("\tLocale.GERMANY:       "
      + getDecimalFormatWithSpecifiedLocale(Locale.GERMANY).format(monetaryAmount));
   out.println("\tLocale.CANADA:        "
      + getDecimalFormatWithSpecifiedLocale(Locale.CANADA).format(monetaryAmount));
   out.println("\tLocale.CANADA_FRENCH: "
      + getDecimalFormatWithSpecifiedLocale(Locale.CANADA_FRENCH).format(monetaryAmount));
   out.println("\tLocale.ITALY:         "
      + getDecimalFormatWithSpecifiedLocale(Locale.ITALY).format(monetaryAmount));
}
Locale-specific currency representations of 14.99:
 Locale.US:            $14.99
 Locale.UK:            £14.99
 Locale.ENGLISH:       ¤14.99
 Locale.JAPAN:         ¥15
 Locale.GERMANY:       14,99 €
 Locale.CANADA:        $14.99
 Locale.CANADA_FRENCH: 14,99 $
 Locale.ITALY:         € 14,99

My DecimalFormat examples so far have focused on formatting numbers for presentation. This final example goes the other direction and parses a value from the string representation.

/**
 * Demonstrate parsing.
 */
public void demonstrateParsing()
{
   final NumberFormat numberFormat = NumberFormat.getCurrencyInstance(Locale.US);
   final double value = 23.23;
   final String currencyRepresentation = numberFormat.format(value);
   out.println("Currency representation of " + value + " is " + currencyRepresentation);
   try
   {
      final Number parsedValue = numberFormat.parse(currencyRepresentation);
      out.println("Parsed value of currency representation " + currencyRepresentation + " is " + parsedValue);
   }
   catch (ParseException parseException)
   {
      out.println("Exception parsing " + currencyRepresentation + parseException);
   }
}
Currency representation of 23.23 is $23.23
Parsed value of currency representation $23.23 is 23.23

The last example shown did not actually need to access the concrete DecimalNumber methods and was able to solely use the NumberFormat-advertised methods. The example formats a currency representation with NumberFormat.format(double) and then parses that provided currency representation to return to the original value with NumberFormat.parse(String).

NumberFormat, and more specifically DoubleFormat, "format and parse numbers for any locale."

Monday, July 20, 2015

Using Hibernate Bean Validator in Java SE

The main Bean Validation page states that "Bean Validation is a Java specification which ... runs in Java SE but is integrated in Java EE (6 and 7)." This post demonstrates using Java Bean Validation reference implementation (Hibernate Validator) outside of a Java EE container. The examples in this post are based on Hibernate Validator 5.1.3 Final, which can be downloaded at http://hibernate.org/validator/downloads.

"Getting Started with Hibernate Validator" states that Hibernate Validator requires implementations of Unified Expression Language (JSR 341) and Contexts and Dependency Injection (CDI/JSR 346). Implementations of these specifications are available in modern Java EE compliant containers (application servers), but use of Hibernate Validator in Java SE environments requires procurement and use of separate implementations.

The "Getting Started with Hibernate Validator" page provides the Maven XML one can use to identify dependencies on the Expression Language API (I'm using Expression Language 3.0 API), Expression Language Implementation (I'm using Expression Language Implementation 2.2.6), and Hibernate Validator CDI portable extension (I'm using Hibernate Validator Portable Extension 5.1.3 Final). I am also using Bean Validation API 1.1.0 Final, JBoss Logging 3.3.0 Final, and ClassMate 1.2.0 to build and run my examples.

There are three Java classes defined for the examples of bean validation demonstrated in this post. One class, Car.java is adapted from the example provided on the "Getting started with Hibernate Validator" page and its code listing is shown next.

Car.java
package dustin.examples;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

/**
 * Example adapted from "Getting Started with Hibernate Validator"
 * (http://hibernate.org/validator/documentation/getting-started/).
 */
public class Car
{
   @NotNull
   private String manufacturer;

   @NotNull
   @Size(min = 2, max = 14)
   private String licensePlate;

   @Min(2)
   private int seatCount;

   public Car(final String manufacturer, final String licencePlate, final int seatCount)
   {
      this.manufacturer = manufacturer;
      this.licensePlate = licencePlate;
      this.seatCount = seatCount;
   }

   public String getManufacturer()
   {
      return manufacturer;
   }

   public String getLicensePlate()
   {
      return licensePlate;
   }

   public int getSeatCount()
   {
      return seatCount;
   }

   @Override
   public String toString()
   {
      return "Car{" +
         "manufacturer='" + manufacturer + '\'' +
         ", licensePlate='" + licensePlate + '\'' +
         ", seatCount=" + seatCount +
         '}';
   }
}

Another class used in this post's examples is defined in Garage.java and is mostly a wrapper of multiple instances of Car. Its primary purpose is to help illustrate recursive validation supported by Hibernate Bean Validator.

Garage.java
package dustin.examples;

import javax.validation.Valid;
import javax.validation.constraints.Size;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
 * Holds cars.
 */
public class Garage
{
   @Size(min = 1)
   @Valid
   private final Set<Car> cars = new HashSet<>();

   public Garage() {}

   public void addCar(final Car newCar)
   {
      cars.add(newCar);
   }

   public Set<Car> getCars()
   {
      return Collections.unmodifiableSet(this.cars);
   }
}

The Garage code listing above uses the @Valid annotation to indicate that the Car instances held by the class should also be validated ("validation cascading").

The final Java class used in this post's examples is the class that will actually perform the validation of the two bean validation annotated classes Car and Garage. This class's listing is shown next.

HibernateValidatorDemonstration.java
package dustin.examples;

import static java.lang.System.out;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;
import javax.validation.Validator;
import java.util.Set;

/**
 * Demonstrate use of Hibernate Validator.
 */
public class HibernateValidatorDemonstration
{
   private final Validator validator;

   public HibernateValidatorDemonstration()
   {
      final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
      validator = factory.getValidator();
   }

   public void demonstrateValidator()
   {
      final Car nullManufacturerCar = new Car(null, "ABC123", 4);
      final Set<ConstraintViolation<Car>> nullMfgViolations = validator.validate(nullManufacturerCar);
      printConstraintViolationsToStandardOutput("Null Manufacturer Example", nullMfgViolations);

      final Car nullLicenseCar = new Car("Honda", null, 3);
      final Set<ConstraintViolation<Car>> nullLicenseViolations = validator.validate(nullLicenseCar);
      printConstraintViolationsToStandardOutput("Null License Example", nullLicenseViolations);

      final Car oneSeatCar = new Car("Toyota", "123ABC", 1);
      final Set<ConstraintViolation<Car>> tooFewSeatsViolations = validator.validate(oneSeatCar);
      printConstraintViolationsToStandardOutput("Too Few Seats Example", tooFewSeatsViolations);

      final Car oneDigitLicenseCar = new Car("General Motors", "I", 2);
      final Set<ConstraintViolation<Car>> tooFewLicenseDigitsViolation = validator.validate(oneDigitLicenseCar);
      printConstraintViolationsToStandardOutput("Too Few License Digits Example", tooFewLicenseDigitsViolation);

      final Car nullManufacturerNullLicenseCar = new Car(null, null, 4);
      final Set<ConstraintViolation<Car>> nullMfgLicenseViolation = validator.validate(nullManufacturerNullLicenseCar);
      printConstraintViolationsToStandardOutput("Null Manufacturer and Null License Example", nullMfgLicenseViolation);

      final Garage garage = new Garage();
      final Set<ConstraintViolation<Garage>> noCarsInGarage = validator.validate(garage);
      printConstraintViolationsToStandardOutput("No Cars in Garage", noCarsInGarage);

      garage.addCar(oneDigitLicenseCar);
      garage.addCar(oneSeatCar);
      garage.addCar(nullManufacturerNullLicenseCar);
      final Set<ConstraintViolation<Garage>> messedUpCarsInGarage = validator.validate(garage);
      printConstraintViolationsToStandardOutput("Messed Up Cars in Garage", messedUpCarsInGarage);
   }

   private <T> void printConstraintViolationsToStandardOutput(
      final String title,
      final Set<ConstraintViolation<T>> violations)
   {
      out.println(title);
      for (final ConstraintViolation<T> violation : violations)
      {
         out.println("\t" + violation.getPropertyPath() + " " + violation.getMessage());
      }
   }

   public static void main(final String[] arguments)
   {
      final HibernateValidatorDemonstration instance = new HibernateValidatorDemonstration();
      instance.demonstrateValidator();
   }
}

The above code features several calls to javax.validation.Validator.validate(T, Class<?>) that demonstrate the effectiveness of the annotations on the classes whose instances are being validated. Several examples validate an object's single validation violation, an example validates an object's multiple validation violations, and a final example demonstrates successful cascading violation detection.

The class HibernateValidatorDemonstration has a main(String[]) function that can be executed in a Java SE environment (assuming the necessary JARs are on the runtime classpath). The output of running the above demonstration class is shown next:

Jul 19, 2015 9:30:05 PM org.hibernate.validator.internal.util.Version 
INFO: HV000001: Hibernate Validator 5.1.3.Final
Null Manufacturer Example
 manufacturer may not be null
Null License Example
 licensePlate may not be null
Too Few Seats Example
 seatCount must be greater than or equal to 2
Too Few License Digits Example
 licensePlate size must be between 2 and 14
Null Manufacturer and Null License Example
 manufacturer may not be null
 licensePlate may not be null
No Cars in Garage
 cars size must be between 1 and 2147483647
Messed Up Cars in Garage
 cars[].licensePlate size must be between 2 and 14
 cars[].manufacturer may not be null
 cars[].licensePlate may not be null
 cars[].seatCount must be greater than or equal to 2

Conclusion

This post has demonstrated that the Hibernate Bean Validator, the reference implementation of the Bean Validation specification, can be executed in a Java SE environment. As part of this demonstration, some basic concepts associated with the Bean Validation specification and the Hibernate Bean Validator implementation were also discussed and demonstrated.

Additional Resources

Friday, July 17, 2015

Packt Publishing's Skill Up Promotion

Packt Publishing is currently running a "Skill Up" promotion with the tagline, "Learn More to Earn More." There are three separate special offers associated with the Skill Up promotion. One option is to purchase any e-book or video for $10 (USD). Another option is to select a "bundle" of five e-books for a total of $25 (USD) for that bundle ($5 per book). The third option is one year's access to PacktLib for $80 (USD).

The "bundle" offer (five e-books for $25 USD) appears to apply to any five e-books or videos in Packt Publishing's large catalog. However, there are several pre-selected bundles ("tech playlists") available for developers wishing to purchase these books in one category. For example, here are some of the available pre-selected bundles:

These are several more pre-selected bundles available than those shown above, but I created and purchased my own "tech playlist" with a PostgreSQL database theme:

The "list" prices for the above five PostgreSQL books would have totaled over $140. It was nice to pay only $25 for all five of them.

As part of the "Skill Up" promotion, reports on developers' salaries are available. The purpose of these appears to be for developers to determine the salary ranges associated with certain types of skills and then, in theory, a developer could purchase e-books and videos on those topics of interest (and associated with promising salaries) to learn those skills.

The "Skill Up" promotion appears to have just started, but I don't know when the "Skill Up" promotion ends.