Saturday, December 27, 2014

Three Common Methods Generated in Three Java IDEs

In this post, I look at the differences in three "common" methods [equals(Object), hashCode(), and toString()] as generated by NetBeans 8.0.2, IntelliJ IDEA 14.0.2, and Eclipse Luna 4.4.1. The objective is not to determine which is best, but to show different approaches one can use for implementing these common methods. Along the way, some interesting insights can be picked up regarding creating of these common methods based on what the IDEs assume and prompt the developer to set.

NetBeans 8.0.2

NetBeans 8.0.2 allows the Project Properties to be configured to support the JDK 8 platform and to expect JDK 8 source formatting as shown in the next two screen snapshots.

Code is generated in NetBeans 8.0.2 by clicking on Source | Insert Code (or keystrokes Alt+Insert).

When generating the methods equals(Object), hashCode(), and toString(), NetBeans 8.0.2 asks for the attributes to be used in each of these generated methods as depicted in the next two screen snapshots.

The NetBeans-generated methods take advantage of the JDK 7-introduced Objects class.

NetBeans-Generated hashCode() Method for Class NetBeans802GeneratedCommonMethods.java
@Override
public int hashCode()
{
   int hash = 5;
   hash = 29 * hash + Objects.hashCode(this.someString);
   hash = 29 * hash + Objects.hashCode(this.timeUnit);
   hash = 29 * hash + this.integer;
   hash = 29 * hash + Objects.hashCode(this.longValue);
   return hash;
}
NetBeans-Generated equals(Object) Method for Class NetBeans802GeneratedCommonMethods.java
@Override
public boolean equals(Object obj)
{
   if (obj == null)
   {
      return false;
   }
   if (getClass() != obj.getClass())
   {
      return false;
   }
   final NetBeans802GeneratedCommonMethods other = (NetBeans802GeneratedCommonMethods) obj;
   if (!Objects.equals(this.someString, other.someString))
   {
      return false;
   }
   if (this.timeUnit != other.timeUnit)
   {
      return false;
   }
   if (this.integer != other.integer)
   {
      return false;
   }
   if (!Objects.equals(this.longValue, other.longValue))
   {
      return false;
   }
   return true;
}
NetBeans-Generated toString() Method for Class NetBeans802GeneratedCommonMethods.java
@Override
public String toString()
{
   return "NetBeans802GeneratedCommonMethods{" + "someString=" + someString + ", timeUnit=" + timeUnit + ", integer=" + integer + ", longValue=" + longValue + '}';
}

Some observations can be made regarding the NetBeans-generated common methods:

  • All generated code is automatic and does not support customization with the exception of the fields used in the methods which the operator selects.
  • All of these common methods that extend counterparts in the Object class automatically have the @Override annotation provided.
  • No Javadoc documentation is included for generated methods.
  • The methods make use of the Objects class to make the generated code more concise with less need for null checks.
  • Only one format is supported for the String generated by toString() and that output format is a single comma-delimited line.
  • I did not show it in the above example, but NetBeans 8.0.2's methods generation does treat arrays differently than references, enums, and primitives in some cases:
    • The generated toString() method treats array attributes of the instance like it treats other instance attributes: it relies on the array's toString(), which leads to often undesirable and typically useless results (the array's system identity hash code). It'd generally be preferable to have the string contents of array attributes provided by Arrays.toString(Object[]) or equivalent overloaded version or Arrays.deepToString(Object[]).
    • The generated hashCode() method uses Arrays.deepHashCode(Object[]) for handling arrays' hash codes.
    • The generated equals(Object) method uses Arrays.deepEquals(Object[], Object[]) for handling arrays' equality checks.
    • It is worth highlighting here that NetBeans uses the "deep" versions of the Arrays methods for comparing arrays for equality and computing arrays' hash codes while IntelliJ IDEA and Eclipse use the regular (not deep) versions of Arrays methods for comparing arrays for equality and computing arrays' hash codes.

 

IntelliJ IDEA 14.0.2

For these examples, I'm using IntelliJ IDEA 14.0.2 Community Edition.

IntelliJ IDEA 14.0.2 provides the ability to configure the Project Structure to expect a "Language Level" of JDK 8.

To generate code in IntelliJ IDEA 14.0.2, one uses the Code | Generate options (or keystrokes Alt+Insert like NetBeans).

IntelliJ IDEA 14.0.2 prompts the operator for which attributes should be included in the generated methods. It also asks which fields are non-null, meaning which fields are assumed to never be null. In the snapshot shown here, they are checked, which would lead to methods not checking those attributes for null before trying to access them. In the code that I generate with IntelliJ IDEA for this post, however, I won't have those checked, meaning that IntelliJ IDEA will check for null before accessing them in the generated methods.

IntelliJ IDEA 14.0.2's toString() generation provides a lengthy list of formats (templates) for the generated toString() method.

IntelliJ IDEA 14.0.2 also allows the operator to select the attributes to be included in the generated toString() method (selected when highlighted background is blue).

IDEA-Generated equals(Object) Method for Class Idea1402GeneratedCommonMethods.java
public boolean equals(Object o)
{
   if (this == o) return true;
   if (o == null || getClass() != o.getClass()) return false;

   Idea1402GeneratedCommonMethods that = (Idea1402GeneratedCommonMethods) o;

   if (integer != that.integer) return false;
   if (longValue != null ? !longValue.equals(that.longValue) : that.longValue != null) return false;
   if (someString != null ? !someString.equals(that.someString) : that.someString != null) return false;
   if (timeUnit != that.timeUnit) return false;

   return true;
}
IDEA-Generated hashCode() Method for Class Idea1402GeneratedCommonMethods.java
@Override
public int hashCode()
{
   int result = someString != null ? someString.hashCode() : 0;
   result = 31 * result + (timeUnit != null ? timeUnit.hashCode() : 0);
   result = 31 * result + integer;
   result = 31 * result + (longValue != null ? longValue.hashCode() : 0);
   return result;
}
IDEA-Generated toString() Method for Class Idea1402GeneratedCommonMethods.java
@Override
public String toString()
{
   return "Idea1402GeneratedCommonMethods{" +
      "someString='" + someString + '\'' +
      ", timeUnit=" + timeUnit +
      ", integer=" + integer +
      ", longValue=" + longValue +
      '}';
}

Some observations can be made regarding the IntelliJ IDEA-generated common methods:

  • Most generated code is automatic with minor available customization including the fields used in the methods which the operator selects, specification of which fields are expected to be non-null (so that null checks are not needed in generated code), and the ability to select one of eight built-in toString() formats.
  • All of these common methods that extend counterparts in the Object class automatically have the @Override annotation provided.
  • No Javadoc documentation is included for generated methods.
  • The generated methods do not make use of the Objects class and so require explicit checks for null for all references that could be null.
  • It's not shown in the above example, but IntelliJ IDEA 14.0.2 does treat arrays differently in the generation of these three common methods:

 

Eclipse Luna 4.4.1

Eclipse Luna 4.4.1 allows the Java Compiler in Project Properties to be set to JDK 8.

In Eclipse Luna, the developer uses the "Source" drop-down to select the specific type of source code generation to be performed.

Eclipse Luna allows the operator to select the attributes to be included in the common methods. It also allows the operator to specify a few characteristics of the generated methods. For example, the operator can choose to have the elements of an array printed individually in the generated toString() method rather than an often meaningless class name and system identity hash code presented.

Eclipse-Generated hashCode() Method for Class Eclipse441GeneratedCommonMethods.java
/* (non-Javadoc)
 * @see java.lang.Object#hashCode()
 */
@Override
public int hashCode()
{
   final int prime = 31;
   int result = 1;
   result = prime * result + this.integer;
   result = prime * result
         + ((this.longValue == null) ? 0 : this.longValue.hashCode());
   result = prime * result
         + ((this.someString == null) ? 0 : this.someString.hashCode());
   result = prime * result
         + ((this.timeUnit == null) ? 0 : this.timeUnit.hashCode());    return result;
}
Eclipse-Generated equals(Object) Method for Class Eclipse441GeneratedCommonMethods.java
/* (non-Javadoc)
 * @see java.lang.Object#equals(java.lang.Object)
 */
@Override
public boolean equals(Object obj)
{
   if (this == obj)
      return true;
   if (obj == null)
      return false;
   if (getClass() != obj.getClass())
      return false;
   Eclipse441GeneratedCommonMethods other = (Eclipse441GeneratedCommonMethods) obj;
   if (this.integer != other.integer)
      return false;
   if (this.longValue == null)
   {
      if (other.longValue != null)
         return false;
   } else if (!this.longValue.equals(other.longValue))
     return false;
   if (this.someString == null)
   {
      if (other.someString != null)
         return false;
   } else if (!this.someString.equals(other.someString))
      return false;
   if (this.timeUnit != other.timeUnit)
      return false;
   return true;
}
Eclipse-Generated toString() Method for Class Eclipse441GeneratedCommonMethods.java
/* (non-Javadoc)
 * @see java.lang.Object#toString()
 */
@Override
public String toString()
{
   return "Eclipse441GeneratedCommonMethods [someString=" + this.someString
         + ", timeUnit=" + this.timeUnit + ", integer=" + this.integer
         + ", longValue=" + this.longValue + "]";
}

Some observations can be made regarding the Eclipse-generated common methods:

  • Eclipse provides the most points in the generation process in which the generated output can be configured. Here are some of the configurable options:
    • Location in class (before or after existing methods of class) can be explicitly specified.
    • All of these common methods that extend counterparts in the Object class automatically have the @Override annotation provided.
    • "Method comments" can be generated, but they are not Javadoc style comments (use /* instead of /** and explicitly state they are not Javadoc comments as part of the generated comment).
    • Option to "list contents of arrays instead of using native toString()" allows developer to have Arrays.toString(Array) be used (same as IntelliJ IDEA's approach and occurs if checked) or have the system identify hash code be used (same as NetBeans's approach and occurs if not checked).
    • Support for four toString() styles plus ability to specify custom style.
    • Ability to limit the number of entries of an array, collection, or map that is printed in toString().
    • Ability to use instance of in generated equals(Object) implementation.
  • All of these common methods that extend counterparts in the Object class automatically have the @Override annotation provided.
  • The generated methods do not make use of the Objects class and so require explicit checks for null for all references that could be null.
  • Eclipse Luna 4.4.1 does treat arrays differently when generating the three common methods highlighted in this post:
    • Generated toString() optionally uses Arrays.toString(Object[]) or overloaded version for accessing contents of array.
    • Generated equals(Object) uses Arrays.equals(Object[], Object[]) or overloaded version for comparing arrays for equality.
    • Generated hashCode() uses Arrays.hashCode(Object[]) or overloaded version for computing hash code of array.
Conclusion

All three IDEs covered in this post (NetBeans, IntelliJ IDEA, and Eclipse) generate sound implementations of the common methods equals(Object), hashCode(), and toString(), but there are differences between the customizability of these generated methods across the three IDEs. The different customizations that are available and the different implementations that are generated can provide lessons for developers new to Java to learn about and consider when implementing these methods. While the most obvious and significant advantage of these IDEs' ability to generate these methods is the time savings associated with this automatic generation, other advantages of IDE generation of these methods include the ability to learn about implementing these methods and the greater likelihood of successful implementations without typos or other errors.

Wednesday, December 24, 2014

Book Review: Puppet Essentials

This blog post is my review of Felix Frank's Puppet Essentials (Packt Publishing, 2014). The subtitle of this book is, "Get up and running quickly using the power of Puppet to manage your IT infrastructure," and it consists of 8 chapters spanning just over 200 substantive pages.

Preface

The Preface of a Packt book tends to be a good first place to look when trying to decide whether the books suits the potential reader. As with other Packt books I've reviewed, Puppet Essentials's Preface provides short summaries of its eight chapters and explains what's needed to run the examples ("two or more virtual machine instances" with the "virtualization guests [having] a connection to the Internet and with each other"). The first chapter also tells us that all examples in the book use "the 3.6.2 release from Puppet Labs' repository."

The "Who this book is for" section of Packt Prefaces us perhaps the most important to a potential reader. This one states:

This book assumes that you have no prior Puppet knowledge. You should have a sound technical background. Experience with the GNU/Linux command line is required. Existing programming skills are recommended. This book is also suitable for beginners or intermediate Puppet users who wish to expand their knowledge about the software.
Chapter 1: Writing Your First Manifests

The initial chapter of Puppet Essentials provides some brief historical facts about Puppet and then explains how to download and install Puppet. The chapter then explains that Puppet manifests are "the equivalent of scripts or programs" and are "written in Puppet's domain-specific language (DSL)."

Chapter 1 differentiates parameters and properties in Puppet and then explains and demonstrates use of the -e option (pass in-lined manifest via shell command) and use of the --noop option ("dry run" what command would do without actually causing that effect or change).

This first chapter provides an introduction to Puppet syntax including conditional statements (if/elsif/else, case, and selectors [ternary]), using variables (which are immutable) and variable types (strings, arrays, and hashes). The first chapter also has a nice explanation of how Puppet manifests are declarative rather than imperative (or procedural). The author writes that "manifests should always describe what you expect to be the end result. The specifics of what actions need to be taken to get there are decided by Puppet."

Because Puppet manifest files are declarative, it is important to explicitly specify order of the results prescribed in the manifest file. The first chapter demonstrates use of -> syntax (order chaining arrow) to establish these explicit dependencies. It also explains and demonstrates application of the before and require metaparameters for explicitly specifying dependencies.

I liked that, in the section on avoiding circular dependencies, the author shows the error that will be printed to the console indicating a circular dependency error and discusses how to see the cyclic path using the --graph option. Use of -graph generates .dot files that can be viewed as graphics with OmniGraffle, Graphwiz, or dotty.

Chapter 1's introduction to Puppet also covers communication between resources via events/signals. I like how the use of notify and subscribe are shown to be analogous to use of before and require. This section also introduces the notification chaining arrow (~>).

The first chapter wraps up with a discussion on "examining the most notable resource types" and specifically looks at the file, package, service, user, group, exec (with a warning to beware abusing this), cron, and mount. The chapter's summary provides some useful reminders including that Puppet manifests "resemble scripts," but "they should not be considered as such" because "they consist of resources instead of commands" and these "resources are generally not evaluated in the order in which they have been written."

Chapter 2: The Master and Its Agents

The second chapter of Puppet Essentials moves the focus from simple Puppet manifests used on single hosts to master/agent use. This chapter introduces puppet-master and explains how to specify agent-specific configuration in node designations in the site manifest on the master.

I liked that Chapter 2 mentions use of --configprint to print out configuration settings Puppet is using. The chapter also covers setting up the agents and getting them to communicate properly with certificates. The discussion covers creating a certificate, revoking a certificate, and renewing a certificate. Another part of the chapter discusses using cron to manage agent lifecycle.

Chapter 2 includes a warning about not using Puppet's built-in WEBrick in a production environment. It then describes in detail how to configure Ruby-based Phusion Passenger with Apache server and with Nginx.

The second chapter discusses tuning Puppet by monitoring and configuring the Passenger Pool Size when using Phusion Passenger instead of WEBrick. There is also a section in this chapter on troubleshooting SSL issues.

Chapter 3: A Peek Under the Hood – Facts, Types, and Providers

Puppet Essentials's third chapter begins with an explanation for why Facter is a valuable "secondary system" in Puppet. The author describes Facter as being "a layer of abstraction over the characteristics of both hardware and software." This feature especially intrigued me as Facter supplies "facts" about each agent that are essentially characteristics of each particular host identified by well-known names. Some of the built-in "facts" that are referenced include processorcount, ipaddress, operatingsystem, operatingsystemrelease, osfamily, and macaddress. The chapter then moves onto developing custom facts with Ruby code and discusses approaches for specifying when facts only apply to certain operating systems or hardware. I also appreciate the author addressing external facts that can be written without Ruby as static (YAML or JSON format) files or even scripts.

Chapter 3 also provides more in-depth discussion of types and providers in Puppet.

Chapter 4: Modularizing Manifests with Classes and Defined Types

Chapter 4 of Puppet Essentials introduces Puppet classes and Puppet defined types and then compares and contrasts them and describes the situations in which each is preferred. Nesting classes is also explained and demonstrated as an approach for composite classes.

Sections in Chapter 4 explain how to use defined types as resource wrappers, as resource multiplexers, as macros, and to process array values. This very detailed chapter also discusses limitations of Puppet classes and some work-arounds for those limitations.

Chapter 5: Extending Your Puppet Infrastructure with Modules

Chapter 5 of Puppet Essentials is about Puppet modules, which the PuppetForge website describes as "reusable, sharable units of Puppet code." The chapter describes the types of things that can be part of a module and explains that modules are in root directories with names matching the module's name. Manifests are stored under that module-named root directory in the manifests subdirectory. The author explains that manifests/init.pp "can be thought of as a default manifest location, because it is looked up for any definition from the module in question." The author also uses text explanation and indented text hierarchical representation of the module's directory/file structure to illustrate structuring of a module in the file system. This chapter also explains how to configure various environments for Puppet.

Another section of Chapter 5 covers downloading and installing modules created by others. This section references PuppetForge as one source of modules and introduces the command puppet module install to download and install a Puppet module. The author recommends that "the stdlib module should be considered mandatory" because "it adds a large number of useful functions to the Puppet language."

The "Modules' Best Practices" section of Chapter 5 "provides details on how to organize your manifests" and "advises some design practices and strategies in order to test changes to modules." Along the way, the author references Puppet taking advantage of an infrastructure as code paradigm. This chapter also explains how to create one's own module without publishing it to PuppetForge. An interesting example working with Cacti illustrates various points being made, including that there are times when it's best to write a wrapper script when a series of complex commands needs to be run and call that wrapper script from Puppet.

A relatively lengthy section of the fifth chapter discusses "enhancing the agent through plugins" such as custom facts, parser functions, types, and providers. The portion of custom facts states that "native Ruby facts ... are more portable than external facts." The chapter concludes with a brief overview of how to find modules matching one's needs on PuppetForge.

Chapter 6: Leveraging the Full Toolset of the Language

Puppet Essentials's sixth chapter covers "some techniques that you are not going to need every day" that "can make difficult scenarios much easier." In the section on templating configuration files, the author points out that Puppet uses ERB as its template language and that this is similar to PHP or JSP, but with Ruby code inside the tags. This section on templating introduces basic ERB syntax, describes how to apply templates, and describes how to mitigate performance issues with templates.

The section of Chapter 6 on creating virtual resources with the @ prefix provides concrete discussion on how these virtual resources make it much easier to use common resources across Puppet modules. This section uses text and code listings to explain realizing virtual resources with the realize function and with a collector.

Chapter 6 also introduces exported resources and demonstrates use of @@ prefix to declare these. It also provides an example of collecting exported resources.

The brief "Exporting SSH host keys" section of Chapter 6 introduces Puppet's sshkey service. The chapter also includes two other brief sections on "managing hosts files locally" and "automating custom configuration items." There are much more detailed sections on overriding resource parameters, Puppet class inheritance, and using resource defaults. Chapter 6 concludes with warnings about using the defined function or stdlib's ensure_resource and a discussion about why these should be avoided.

Chapter 7: Separating Data from Code Using Hiera

Chapter 7 of Puppet Essentials talks about the maintenance issues associated with Puppet manifests that mix data and logic and introduces use of Hiera to support an "external database that holds all individual and shared values." The chapter describes Hiera built into Puppet and demonstrates how to configure Hiera via the hiera.yaml file. The chapter briefly compares and contrasts the three back-ends for Hiera (YAML, JSON, and Puppet Manifest Files), mentions that custom Ruby back-ends can be written, and then focuses on YAML files. It provides detailed explanations and examples of using Hiera and briefly discusses considerations when "choosing between manifest and Hiera designs."

A particularly useful section of Chapter 7 is the section "Debugging Hiera lookups" which introduces the command-line tool hiera that can be used to help "determine where the respective [data] values are retrieved from for any given agent node."

Chapter 8: Configuring Your Cloud Application with Puppet

The final chapter of Puppet Essentials talks about using Puppet in the cloud. Before discussing Puppet and the cloud, however, the chapter first looks at some of Puppet's most common deployment environments (Debian and Red Hat Linux and with Vagrant). This eighth chapter also describes Craig Dunn's Roles and Profiles pattern.

The discussion on "Taking Puppet to the cloud" approaches this subject based on the "Infrastructure as a Service (IaaS) paradigm," but later provides an explanation of how to implement a Platform as a Service (PaaS) implementation on top of the IaaS implementation. Sections in this chapter cover "initializing agents in the cloud," "using Puppet's cloud-provisioner module," "building Manifests for the cloud," "composing arbitrary configuration files," and "handling instance deletions."

A major section in this final chapter is on "preparing for autoscaling" so commonly associated with deployments to the cloud. Several items are discussed in this section, including the need to test manifests regularly.

The final chapter's Summary summarizes the chapter and includes a couple of paragraphs that provide an overall book conclusion.

General Observations
  • Puppet Essentials serves as both an introductory text on use of Puppet and as a reference on more intermediate and advanced uses of Puppet.
  • I like that Puppet Essentials talks about things that have changed in Puppet or are likely to change in the future. It's difficult for a technical book to avoid being overcome by events or becoming obsolete, but these references to changes help.
  • Puppet Essentials is written as though expecting an audience familiar with Ruby or Perl for most of their scripting tasks. This assumption is manifest (no pun intended) by many references to those languages when introducing Puppet concepts and syntax.
  • Puppet Essentials references things that are outside the scope of the book such as Puppet 4, Stages, scaling a master with load balancing, using "openssl command-line tool ... for analyzing the certificates and related files", generating HTML documentation with puppet-doc (which apparently has been used to create much of the impressive Puppet online documentation), writing Ruby back-ends for Hiera, publishing modules, and "exploiting PuppetDB."
  • The "Summary" sections of each chapter did a nice job of thoroughly and relatively concisely reviewing the highlights covered earlier in each chapter.
  • The numerous code listings in this book are black font on white background with no color syntax and no line numbers. There are some instances where portions of code most relevant to the discussion are highlighted in bold.
  • Although the text of Puppet Essentials is generally highly readable, there are some typos. For example, there are at least a couple references to "boxen" instead of "boxes."
  • Other reviews of Puppet Essentials might help provide a more complete picture of the book:
Conclusion

I recommend Puppet Essentials for developers or operations personnel (or "DevOps" personnel) who want a good introductory text on Puppet that also provides enough in-depth information and observations to be useful as a reference. As the author states in the book, the online Puppet documentation seems well maintained and highly approachable, but it's nice to have a book to tie it altogether and to provide some in-depth asides.

Monday, December 22, 2014

Book Review: Mastering JavaServer Faces 2.2

Anghel Leonard's Mastering JavaServer Faces 2.2 (Packt Publishing, 2014) has the subtitle, "Master the art of implementing user interfaces with JSF 2.2." The book features twelve chapters and a short appendix spanning approximately 530 substantive pages. This blog post is my review of the PDF version of the book.

Preface

The Preface of Mastering JavaServer Faces 2.2 provides 2 to 3 sentences summarizing each of the book's chapters. It also recommends NetBeans 8+, GlassFish 4, and Mojarra JavaServer Faces 2.2.6 for running the book's sample applications. The "Who this book is for" section of the Preface clearly articulates that Mastering JavaServer Faces 2.2 is intended for readers who are already familiar with JavaServer Faces. This section states:

This book is a perfect symbiosis between JSF 2.0 and 2.2. It is dedicated to JSF developers who have previous experience and want to upgrade their knowledge to the new JSF 2.2. By fortifying your knowledge on JSF 2.0 and adding the power of JSF 2.2, you will soon become a JSF expert.

I re-emphasize this point here: Mastering JavaServer Faces 2.2 assumes JavaServer Faces experience. The book dives right into newer (JSF 2.2) JavaServer Features without the traditional background and introductory text one would expect from a book that introduces a language or framework. In other words, this book would be best suited for a developer with JSF experience who wants to learn about JSF 2 and JSF 2.2 new features or who has an older book on earlier versions of JSF and wants to use this book as a companion to that older book.

Chapter 1: Dynamic Access to JSF Application Data through Expression Language (EL 3.0)

The initial chapter of Mastering JavaServer Faces 2.2 begins fast with an introduction to Expression Language (EL). The chapter looks at EL 3.0 (JSR 341) syntax (operators, reserved words, immediate evaluation with ${}, deferred evaluation with #{}, referencing both CDI managed beans and JSF managed beans, referencing managed beans' properties and nested properties and methods, referencing Java enumerated types, accessing collections from JSF, and implicit objects).

I liked the Chapter 1 section on "writing a custom EL resolver" because I was not previously aware that one could write one's own custom implicit variables in JSF expression language. This section introduces EL Resolvers, demonstrates how to writ a custom EL Resolver, and describes how to differentiate between a VariableResolver and a PropertyResolver.

The "EL 3.0 overview" section of the first chapter introduces EL 3.0 (part of Java EE 7), lists some of its features, and describes how to use it with JSF. One of the more interesting portions of this section for me was the coverage of EL lambda expressions and streams.

Chapter 2: Communication in JSF

The second chapter of Mastering JavaServer Faces 2.2 opens with the statement, "Communication is the core of a JSF application, and is one of the main aspects that dictate the architecture of such an application." It adds, "JSF provides many solutions for ensuring a powerful and flexible communication layer between JSF components and also between JSF and XHTML pages, the JavaScript code, and other third-party components." With this introduction, the chapter moves onto covering a lengthy list of miscellaneous approaches to communicating between components of a JSF application.

The topics covered in Chapter 2 include context parameters, <f:param ...> tag and >c:set<, view parameters (UIViewParameter/<f:viewParam>), GET request view actions (<f:viewAction>), <f:attribute> tag (demonstrated with an example that modifies supported behavior of a PrimeFaces component), action listeners (<f:setPropertyActionListener>), JSF Flash scope, cookies, hidden fields (<h:inputHidden>), accepting passwords (<h:inputSecret>), accessing JSF user interface components from JSF Java code, EL method expressions, JSF data binding, injecting one managed bean into another managed bean (@ManagedProperty), and communication between managed beans.

Chapter 3: JSF Scopes – Lifespan and Use in Managed Beans Communication

Chapter 3 of Mastering JavaServer Faces 2.2 is all about scopes in JavaServer Faces. The chapter contrasts JSF managed beans and CDI beans and recommends "[using] CDI beans whenever possible," but does discuss situations in which JSF managed beans are preferable. This section includes a useful figure that makes it easy to see the JSF core scope annotations (javax.faces.bean) alongside the CDI scope annotations (javax.enterprise.context). The section describes each level of scope in a JSF application (request, session, view, application, conversation, flow, dependent pseudo-scope, none, custom) and whether JSF managed beans and/or CDI beans support each scope. This coverage of scopes includes code listings for each type of bean to which that scope applies. The sections on flow scope and custom scopoe are longer than the others and particularly useful in understanding these relatively more complicated scopes.

The third chapter concludes with brief sections on easy and lazy managed bean instantiation, allowable scopes for injected and injecting managed beans, and when to use @ManagedProperty versus @Inject. There are several useful figures in this chapter that use shapes and colors to illustrate points being made.

Chapter 4: JSF Configurations Using XML Files and Annotations – Part 1

Mastering JavaServer Faces 2.2's fourth chapter looks at how JSF 2.2 allows annotations to be used to configure many characteristics of a JSF application that formerly had to be configured in a faces-config.xml file. A table that is present early in this chapter maps old ("Before JSF 2.2") namespaces to new ("JSF 2.2") namespaces. The chapter also looks at specifying certain JSF characteristics both with XML and programmatically. The chapter has sections explaining how to use and order multiple configuration files and how to support internationalization by configuring locales and resource bundles.

Chapter 4 has a lengthy section on "configuring validators and converters." I like the author's discussion in this section regarding the state of injecting dependencies into validators and whether it's supported in JSF 2.2 or 2.3. Configuring JSF application navigation in another large topic in the fourth chapter that covers implicit navigation, conditional navigation, preemptive navigation (AKA predetermined navigation), and programmatic navigation.

Chapter 4's focus on configuration moves onto configuring action listeners, system event listeners, phase listeners, @ListenerFor and @ListenersFor.

Chapter 5: JSF Configurations Using XML Files and Annotations – Part 2

The fifth chapter of Mastering JavaServer Faces 2.2 continues the general theme of JSF configuration that the preceding chapter also addressed. The chapter begins with a relatively in-depth look at various approaches for configuring resource handlers (default configuration via placement in JSF 2.0 conventional locations, custom resource handler, and javax.faces.WEBAPP_RESOURCES_DIRECTORY JSF 2.0 context parameter in web.xml file). The section in Chapter 5 on configuring view handlers discusses and demonstrates writing custom view handlers to "convert absolute URLs into relative URLs" and to handle encountered ViewExpiredExceptions.

Chapter 5's section on overriding JSF renderers uses code listings and explanations to demonstrate overriding the HTML output by JSF components when rendered. I particularly liked the "little bit tricky" example of extending ResponseWriterWrapper to change the behavior of writeText to write escaped strings and making some other changes to support that PrimeFaces-like functionality in standard JSF. Another section in the chapter looks at extending ClientBehaviorBase and the other steps necessary to "define specific client-side behavior to a component in a reusable approach."

A considerable portion of Chapter 5 is devoted to JSF factories. Examples include configuring the global exception handler by extending ExceptionHandlerFactory and ExceptionHandlerWrapper, configuring the RenderKitFactory, configuring PartialViewContext, configuring VisitContext, configuring ExternalContext, and configuring Flash by extending FlashFactory and FlashWrapper. Each of these is explained by spelling out the steps needed to perform the configuration and then demonstrating those steps implemented with code listings.

Chapter 5 concludes with coverage of enabling and disabling the ClientWindow API, configuring the JSF lifecycle by extending LifecycleFactory and LifecycleWrapper, configuring an application by extending ApplicationFactory and ApplicationWrapper, and configuring View Declaration Language (VDL), and using more than one configured factory in conjunction with each other to write "a Java Servlet capable of converting a non-JSF request into a JSF view."

Chapter 6: Working with Tabular Data

Chapter 6 is devoted to coverage of applying <h:dataTable> to represent tabular data in JSF. Specific examples covered include rendering of tabular data from JSF-hosted POJOs, displaying a collection of objects with CollectionDataModel, presenting sorted data, an introduction to DataModel, deleting a row from a table, modifying a row in a table, adding a new row, supporting selection of a single row and multiple rows, nesting tables, paginating tables, filtering tables, and styling tables.

The sixth chapter also demonstrates how to generate a JSF table programatically with JSF API classes such as HtmlDataTable, HtmlColumn, and HtmlOutputText.

Chapter 7: JSF and AJAX

The seventh chapter of Mastering JavaServer Faces 2.2 covers use of JavaServer Faces with Ajax. The chapter introduces <f:ajax> and the JSF/Ajax lifecycle. It then provides detailed explanations of the main attributes of <f:ajax>: execute, render, listener, event, onevent, onerror.

Mastering JavaServer Faces 2.2's Chapter 7 covers more examples of using JSF with Ajax such as grouping multiple components within a single <f:ajax> tag, "updating input fields with Ajax after validation error" using resetValues, implementing Cancel and Clear buttons, mixing Ajax and Flow scope, determining if a request is an Ajax request (PartialViewContext.isAjaxRequest or headers Faces-Request and X-Requested-With), using <f:param> with <f:ajax>, controlling client-side Ajax queuing with <f:ajax>'s delay attribute, explicitly loading and customizing the JavaScript file that contains JSF's Ajax support (jsf.js).

Chapter 8: JSF 2.2 – HTML5 and Upload

Chapter 8 is introduced as being primarily composed of two sections: "The first part will present the JSF 2.2 support for HTML5, while the second part discusses the new upload component of JSF 2.2." The chapter's section on using HTML5 with JSF 2.2 discusses pass-through attributes and pass-through elements (TagDecorator). It also discusses application of Bean Validation 1.1 with HTML5 and JSF 2.2.

The section of Chapter 8 on JSF Upload introduces <h:inputFile> and some of its "most important" attributes before discussing use of multiple upload tags, identify characteristics of a file to be uploaded, writing uploaded data to disk, building a file upload validator, using upload with Ajax, uploading multiple files, upload with both indeterminate and determinate progress bars, and an especially lengthy discussion on providing previews of images to be uploaded.

Chapter 9: JSF State Management

The ninth chapter of Mastering JavaServer Faces 2.2 states early in the chapter that "JSF saves and restores the view state between requests using the ViewHandler/StateManager API. ... JSF uses this technique because it needs to preserve the views state over the HTTP protocol, which is a stateless protocol." The chapter goes on to explain how JSF 2.0 and 2.2 have improved JSF application performance with changes in how JSF state is managed. It provides a very detailed example of persisting state in JSF Mojarra to a MongoDB database.

One of the more interesting discussions in the ninth chapter for me was the discussion on JSF 2.2 support for stateless views via the transient attribute on the <f:view> element. Another interesting discussion covers security in JSF (CSRF, XSS, and SQL injection).

Chapter 10: JSF Custom Components

The opening statement of Chapter 10 is, "JSF is a component-based framework, and JSF custom components are the major proof that sustain JSF flexibility and extensibility." The chapter differentiates between custom components and composite components. I like the author's recommendation to look for already existing components as the first step when deciding to implement and then implement a custom component. This idea and a few other ideas are presented as possibly more appropriate approaches than implementing a custom component in many situations.

Chapter 10 explains and demonstrates "building noncomposite custom components" in JSF 2.2 with a single Java class annotated with @FacesComponent. The explanation and demonstration of writing noncomposite custom components dives into deeper details about implementing more complex custom components with Java classes and tag handlers.

Chapter 10's coverage of "building composite components" describes JSF 2 custom components as "practically custom components written in XHTML pages using markup tags" and is a longer and more detailed section than the section on noncomposite custom components. The author makes a good point here that use of XHTML "means that JSF page authors can start writing their components without having the same level of knowledge and skills as dedicated JSF component authors." This section demonstrates implementation of an example of a composite component that makes it easy to compare to the same example application implemented earlier in the chapter with a noncomposite custom component. Chapter 10 also provides explanations and illustrations of transforming the jQuery UI range slider component into a JSF composite component and transforming the HTML5 DatePicker into a JSF composite component.

There are several aspects of developing composite components in JSF covered in Chapter 10. These include working with composite facets, validating and converting input information within a composite component, distributing a composite component as a JAR, and instantiating composite components programatically.

Chapter 11: JSF 2.2 Resource Library Contracts – Themes

The second-to-last chapter of Mastering JavaServer Faces 2.2 starts with the sentence, "Starting with version 2.0, JSF developers exploit Facelets as the default View Declaration Language (VDL)." The early part of this chapter also describes a Facelet template as "a mix of XHTML and other resources such as CSS, JS, and images" that "acts as a base (or a model) for the application pages," providing "reusable code that serves as a consistent and standard look and feel." The chapter begins coverage of Resource Library Contracts by discussing the contracts folder. The chapter explains and illustrates applying style to tables and JSF components with contracts. The chapter also covers writing of contracts for composite components, writing custom themes, using XML to configure contracts, and packaging contracts in JARs under META-INF/contracts.

Chapter 12: Facelets Templating

Mastering JavaServer Faces 2.2 introduced and referenced Facelets in earlier chapters, but this final chapter focuses on Facelets (specifically templating with Facelets). After a brief history of how Facelets supplanted JavaServer Pages as the default View Definition Language for JavaServer Faces, the chapter provides a bullet list of Facelet tags with brief descriptions of each tag in each bullet.

After listing major Facelets tags with brief descriptions, Chapter 12 provides more in-depth discussion and examples of applying Facelets tags such as <ui:param>, <ui:decorate>, <ui:fragment>, <ui:repeat>, <ui:include>, <ui:debug>, and <ui:remove>.

Until reading Mastering JavaServer Faces 2.2, I was not aware of jsfc, but that is covered in the final chapter. The chapter also discusses "Facelets programmatic aspects" such as FaceletFactory, FaceletCache, ResourceHandler, including Facelets programatically, implementing a TagHandler class and implementing Facelets taglib functions.

The section of Chapter 12 titled "Facelets pitfalls" opens with something I've definitely observed: "It is a well-known fact that JSF pitfalls are not easy to understand and fix." This section then focuses on "three common Facelets pitfalls." Chapter 12's Summary is for that chapter only; there is no overall book summary.

Appendix: The JSF Life Cycle

This appendix is barely more than a single page, but has valuable information on the JSF lifecycle depicted in a flow diagram.

General Observations
  • There are numerous code listings in Mastering JavaServer Faces 2.2. These are black text on white background with no line numbers or syntax highlighting. Code is also available online, which is probably preferable because it can be presented in the reader's favorite IDE or text editor with color syntax highlighting and line numbers.
  • Mastering JavaServer Faces 2.2 provides graphics and figures to illustrate points being made. Many of these are in color in the PDF version I reviewed.
  • In multiple cases, the author mentioned a feature that was supposed to be part of JSF 2.x, but that was not working for him at time of writing of the book. I appreciated this being called out as it appears that some of these features may still not be supported in a standard way.
  • The author differentiates between standard JSF features and functionality and features and functionality provided by alternative JSF implementations.
  • NetBeans is referenced a few times in Mastering JavaServer Faces 2.2. In all of these cases, even a person who has not used NetBeans would likely understand the principle being stated.
  • Mastering JavaServer Faces 2.2 is not intended for the developer who is completely new to JavaServer Faces (the author stated this in the Preface: "It is dedicated to JSF developers who have previous experience and want to upgrade their knowledge to the new JSF 2.2."). Rather, this book is focused on providing in-depth details of new features of JSF 2.0 and 2.2 for developers who already have some basic familiarity with JSF. Alternative resources to consider for those entirely new to JSF in preparation for reading Mastering JavaServer Faces 2.2 include the following (some of which I've linked to earlier in this post):
Conclusion

Mastering JavaServer Faces 2.2 provides wide coverage of JavaServer Faces 2.0 and 2.2 additions that have made the framework more powerful and easier to apply. Mastering JavaServer Faces 2.2 assumes that the reader has previous JavaServer Faces experience and does not spend time bringing the reader up to speed on JSF basics before diving into the relatively detailed coverage of features new to JSF with 2.0 and 2.2. The book is best suited for developers who have mostly developed with JSF 1.x and want to start taking advantage of JSF 2 and JSF 2.2 features. This book is not appropriate for someone brand-new to JSF with no previous JSF experience.

Thursday, December 18, 2014

Packt Publishing's Christmas 2014 $5 Ebook and Video Bonanza Sale

Packt Publishing is once again offering any of their e-books or videos for $5 (USD) as part of their $5 eBook Bonanza holiday promotion. This $5 price on any e-book or video is available until 6 January 2015. Their main promotion page features their 20 best-selling titles, but any book is covered by this deal.

I have reviewed numerous Packt Publishing titles on this blog and provide links to those reviews below. I am currently reading Mastering JavaServer Faces 2.2 and hope to post a review of it before this promotion ends. I've read about half of the book so far and have found it to be a useful reference on JSF 2.0 and JSF 2.2.

My Reviews of Packt Publishing Titles

These are some of my prior reviews of Packt Publishing e-books and videos:

E-books Videos Pre-Orders Included

Packt Publishing is also including pre-orders in the Christmas 2014 $5 Bonanza deal. This means books that are "coming soon" are included. These titles can be found by searching all ebooks on their site and selecting "Coming soon" as the "Release date" filter. Titles in this category include Node.js Design Patterns (expected December 2014), IntelliJ IDEA Essentials (expected December 2014), Puppet Cookbook: Third Edition (expected February 2015), Scala Object-Oriented Programming (expected February 2015), Learning Chef (expected February 2015), and SoapUI Cookbook (expected March 2015).

Conclusion

There is always some risk when purchasing a book or video of that title not meeting one's needs or not providing enough value for a particular reader/viewer to justify the cost. The beauty of Packt Publishing's $5 per ebook or video Christmas Bonanza sale is that the risk is greatly reduced. Also, at $5 per title, books on completely new subjects unrelated to my current work appear more attractive to me.

Wednesday, December 17, 2014

Goodbye, Dr. Dobb's

Andrew Binstock's 16 December 2014 column Farewell, Dr. Dobb's announces that the Dr. Dobb's parent company is planning to "sunset" the Dr. Dobb's website. The column is an interesting read because Binstock analyzes why the website will add no new content despite consistently increasing traffic at the site. This analysis provides an overview of how the market for communicating technical information is changing.

I remember reading Dr. Dobb's when it was in "hard copy" and even saved a few that had articles that were particularly interesting to me. As with most technical journals and magazines, Dr. Dobb's shifted to online only once access to high-speed internet was typical for most of its readers. Binstock points out in his column that advertisers seem to be realizing that inline advertisements may not lead to as many sales as they once did or were once thought to do and he makes the point that he has never purchased anything from one of these advertisements. In a similar vein, I have to admit that though I've read a Dr. Dobb's article from time-to-time as a Google search or social media reference pointed it out to me, I have not made a regular habit of perusing Dr. Dobb's headlines in recent years. Part of this is the plethora of online resources vying for my attention and part of this is my increasing specializing in in a few programming languages while the software development world continues to broaden in terms of opportunities and possibilities. Binstock addresses this when he writes that the "software market today is so highly segmented" and observes that "the advent of the Web, which offered a vast array of new information sources, meant that Dr. Dobb's was no longer the central access point."

Although I have not read Dr. Dobb's with the regularity and thoroughness that I used to, I still will miss the great new in-depth content it provides. As software developers, we are fortunate to have many sources of information, but some are more accurate and in-depth than others and Dr. Dobb's was generally in the category of more accurate and more in-depth. There is some good news in the announcement. At least in the near term, existing content on DrDobbs.com will remain in place despite no new content being added. This means that links to Dr. Dobb's articles from blog posts and other articles should continue to work and readers will not need to resort to using the Wayback Machine or similar mechanisms to find these articles.

Perhaps the most significant benefits of Dr. Dobb's were its coverage of general software development without focus on a specific programming language or environment, its detailed articles, and its content being edited. Blogs and software development social media sites have brought many advantages to us as more people writing means more opinions and experiences to consider and more narrow topics being covered thoroughly. However, the age of blogs and software development social media also brings online resources of much greater variability in terms of accuracy, thoroughness, and even general spelling and grammar. Having ready access to these numerous individually authored posts and articles has led to the increase of information available on narrow topics and individual programming languages, but it has also made it more difficult for many of us to keep up with all the information available on our platform and language of choice and still have time to read about and consider completely unrelated languages and platforms.

A natural question might be, "What is the best replacement or substitute now for Dr. Dobb's?" Binstock is addresses that, but is not really able to provide an alternative:

This should not suggest that there is no role anymore for Dr. Dobb's. As our page views show, the need for an independent site with in-depth articles, code, algorithms, and reliable product reviews is still very much present. And I will dearly miss that content. I wish I could point you to another site that does similar work, but alas, I know of none.

Goodbye, Dr. Dobb's. Thanks for helping me learn about new programming languages, frameworks, platforms, and idioms.

Friday, December 12, 2014

Recent (November/December 2014) Java/JDK 9 Posts of Interest

I have come across a few Java-related posts in recent weeks that I reference and summarize here.

An Update on Java Modularity

Mark Reinhold's Project Jigsaw: Modular run-time images reports on the status of Project Jigsaw. This post includes coverage of consequences of Project Jigsaw that make its effects more concrete in my mind. Here are some of the interesting consequences of Project Jigsaw that Reinhold pointed out:

  • "The JDK image [will] simply [be] a run-time image [the JRE] that happens to contain the full set of development tools and other items historically found in the JDK."
  • "The endorsed-standards override mechanism has been removed" and will be replaced with "upgradeable modules."
  • "The extension mechanism has been removed."
  • "The internal files rt.jar, tools.jar, and dt.jar have been removed" and "class and resource files previously in tools.jar and dt.jar are now always visible via the bootstrap or application class loaders in a JDK image."

More Java 9 Features

In his post Oracle Confirms New Java 9 Features, Benjamin Ball summarizes and references the latest six JDK Enhancement Proposals (JEPs) associated with JDK 9 (JEP 158, JEP 165, JEP 213, JEP 214, JEP 219, and JEP 224).

Another JDK Versioning Scheme

Bienvenido David describes JDK Enhancement Proposal (JEP) 223 in his post New Java Version - it's not JDK 1.9. He explains that, under this proposed versioning scheme, JDK 1.7.0_65-b20 (7u65) would be JDK 7.6.15+20 (7.6.15).

Recompiling the Java Runtime Library with Debug Symbols

Attila-Mihaly Balazs's post Recompiling the Java Runtime Library with Debug Symbols possesses three characteristics of my favorite blog posts in that it's (1) relatively thorough given its (2) conciseness and it (3) references other related posts ("Credits for inspiration"). The post demonstrates using Ant to build a debug version of rt.jar. Compiling rt.jar (which won't be around in JDK 9 according to the previously mentioned Reinhold post) isn't something one needs to do often, but it's nice to keep a post like it in mind in case this is needed in the future.

It's worth pointing out here that the post "Recompiling the Java Runtime Library with Debug Symbols" is associated with the 2014 Java Advent Calendar ("interesting technical article from various authors related to Java daily between the 1st and 24th of December, each year") and is hosted on the voxxed.com site ("knowledge sharing platform with the same DNA as the Devoxx conferences and a productive relation with Parleys.com").

JVM Essential Guide

Alexey Zhebel's post Java Virtual Machine: the Essential Guide provides a concise (about five printed pages really does mean it focuses on "essentials") overview of the Java Virtual Machine. Topics that are (briefly) covered include architecture, execution, memory, threads, performance optimization, and performance monitoring.

Ascii Art in Javadoc Comments

As one who has used "ASCII art" in Javadoc and other comments before and has seen others use this approach effectively, I found Fabian Kessler's post Graphical Visualizations in JavaDoc interesting. Kessler points out some advantages of "ASCII art" over linking graphics in Javadoc and references the useful online tool asciidraw.

Effective Javadoc that doesn't simply restate what the code already demonstrates can be very helpful and the use of ASCII art is another tactic that can be used to write effective Javadoc that adds to the understanding of what the code is supposed to do.