Dustin's Pages

Wednesday, December 31, 2014

One of my favorite posts to write each year is the year-ending summary of some of the developments in the world of software development that I have read about or observed during that year. As with any opinionated posts, these are significant developments from my perspective and may be more or less significant to others than they are to me. I'll undoubtedly completely miss some significant events in the world of software development during 2014 as well.

10. Docker (and Containers in General)

Docker, described as "an open platform for developers and sysadmins to build, ship, and run distributed applications," seems to be gaining significant attention in 2014 after being open sourced in 2013 and version 1.0 being released in 2014. Docker has several major partners now including IBM, VMware, OpenStack, and RedHat. Although Docker has been typically seen as a container for flavors of Linux, Microsoft announced in late 2014 that "developers and organizations that want to create container applications using Docker will be able to use either Windows Server or Linux with the same growing Docker ecosystem of users, applications and tools." Docker has been called the first true DevOps tool and Docker might be seen as the representative of the general class of containers that are becoming very popular.

9. DevOps

I had considered lumping Docker and other containers into this DevOps category, but decided that containers (and Docker in particular) were big enough news in 2014 to leave as a separate item. However, their success in 2014 definitely contributes to the growth of DevOps in 2014. I still find that DevOps means different things to different people, but there is no arguing that the term is frequently discussed in 2014. The sheer number of conferences associated with it attest to its popularity. These conferences include Mountain West DevOps 2014, DevOps track at Agile2014, DevOps Summit 2014, and DevOps Days.

The rise of tools that many consider "DevOps tools" has also been significant in 2014. Tools such as Docker, Chef, and Puppet are widely popular this year.

8. C++14

It was announced in late summer of 2014 that C++14 has been approved. Someone who only read the most popular software development blogs might wonder why a new C++ standard matters, but anyone with a broader view of the software development industry understands that C++ is one of the most widely used programming languages on the planet. A brief summary of the new features of C++14 is available in the post "C++14 is done -- here's what's new."

Java 8 brought arguably the most significant changes to Java since J2SE 5. Java 8 brought some of the most desirable features of trendier programming languages into one of the most commonly used programming languages.

Until 2014, most of us thought of Objective-C when we thought about native language development for Apple devices. Apple introduced Swift in 2014, which it has described as modern, safe, expressive, and high performing. Perhaps as important as any of these characteristics is that Swift can run alongside Objective-C on Cocoa and Cocoa Touch.

5. AngularJS

AngularJS made my "Honorable Mention" list in last year's version of this post and its popularity increased even more in 2014. It seems to be mentioned as often as jQuery in discussions on web development. It is jQuery that made (and still makes) JavaScript development bearable for many of us and it will be interesting to see if AngularJS has the same type of long-range effect on web development (moving more development to HTML built-in and extension tags and away from JavaScript). There seems to be a lot of potential for this already popular framework with the coming of AngularJS 2.0, Web Components, and ECMAScript 6 (ES6). Google is introducing AtScript with AngularJS 2.0 as a "new superset JavaScript runtime type system."

4. Cloud Computing

Barb Darrow opens Yup, 2014 was a big year in cloud with this statement: "2014 was the year in which both Microsoft and Google got serious about their public cloud options and taking on Amazon Web Services directly with their own Infrastructure as a Service and associated services." Office 365, other Microsoft offerings, and Google offerings are bringing the cloud to an ever increasing number of individuals, organizations, and businesses.

In the last year, competing public and private Cloud providers have tremendously upped the ante in terms of lowering their costs and also improving the feature sets of their services. ... In 2013, for the enterprise, the low hanging fruit for Cloud was all about tackling Development and Test workloads which could take advantage of Self-Service provisioning and also de-provisioning. In 2014 for CxOs it was all about investigating, piloting and actively moving production workloads into the Cloud.

2. Open Sourcing of .NET Core and Freely Available Visual Studio Community Edition

In the post .NET Core is Open Source, Immo Landwerth writes, ".NET Core will be open source, including the runtime as well as the framework libraries." He also explains that ".NET Core is a modular development stack that is the foundation of all future .NET platforms" and "the new .NET Core stack will be entirely open sourced on GitHub." Earlier in 2014, it was announced that the C# compiler was being open sourced.

Microsoft is not one of the first companies one thinks of when one thinks "open source" and these announcements have even been called "shocker." Patrick Hynds's Microsoft developers are no longer isolated provides a thorough overview of the market forces that led to this announcement from Microsoft and an explanation of why this policy change could mean "another decade of that language (and maybe even that framework) remaining relevant."

Rick Delgado states, "These recent attacks beg the question as to whether the worst is behind us, or still ahead." His opinion is, "Unfortunately, it seems to be the later."

"Software Security" was already my #1 item for this list and everything in this #1 description above this sentence was already written when news of the Sony hack came to light. The rest of this section is on the Sony hack and only further cements "Software Security" as my #1 development in software development in 2014.

In one of the articles I cited earlier on cloud's huge 2014, that article's author pointed out that "data security concerns remain the biggest inhibitor to cloud adoption."

Honorable Mention

I've never been able to squeeze all the significant developments in software development in a given calendar year into ten items. This year is no different and this "Honorable Mention" section allows me to list items that I considered for the top ten, but ultimately, for me, did not bump any of the items in the top ten.

SQL Reminds Us of Its Dominance

Nearly eight years ago, Steve Yegge wrote in his post The Next Big Language that rule #1 for making sure a new programming language "stands a chance" is to create it with a "C-like syntax." A similar post on creating the next big database might say the same thing for a SQL-like syntax being rule #1. In my professional career, I've obviously worked with relational databases, but I have also worked with object-oriented and XML databases. In all cases (not just relational), SQL or a SQL-like syntax was introduced to the products I used in an attempt to gain marketshare that the relational databases enjoyed.

We're seeing the same thing with the NoSQL databases today, making the name "NoSQL" even more imprecise. One of the things that appealed to me about Cassandra when I first started using it was it's SQL-like Cassandra Query Language (CQL) (and cqlsh environment). CouchBase has announced N1QL (pronounced "nickel") as its "next generation query language" and the N1QL Language Reference describes it relative to SQL: "N1QL builds on the SQL language and includes many of SQL's features in addition to features associated with document-oriented databases."

Although relational databases in particular and database of all sorts in general have adopted SQL, the Structured Query Language has impacted software development outside of databases as well. XQuery brings SQL-like semantics to XML, JMS selectors are often described SQL-like, JMS expression syntax "is based on a subset of the SQL92 conditional expression syntax" (Java EE 6 Tutorial on JMS Message Selectors), and introductions to Java SE 8 streams and aggregate operations often use SQL as part of their explanations.

In a similar vein, manifestos have become popular in software development. The manifesto has been used outside of software development well before there was such a thing as software development. Karl Marx (who is unrelated to me as far as I know) is well-known for his contributions to the Communist Manifesto.

There are very mixed reactions to this news. Some focus on the positive aspects, including the argument that dropping NPAPI moves things towards being safer and "more mobile friendly." Others argue that they don't need Google being Big Brother and making it impossible to use plugins even at the consumer's own risk. Another argument is that the alternatives to NPAPI are not mature enough or sufficient to justify complete abandonment of NPAPI and that Google's Pepper Plugin API is insufficient for using popular plugins that are said to work with it. It does seem to make things more difficult for the web developer who needs characteristics that have made plugins more attractive than HTML5 if that developer needs to write his or her application differently for each browser because they cannot agree on their native client technology.

Internet of Things

The Internet of Things was on my list last year and remains a major concept in the software development community that has spread to the general populace as consumers have purchased connected devices.

HTML5

HTML5 continues to gain market share thanks to the ubiquity of the web and of mobile devices.

2014 was another year with many developments in software development. I have not had as much time as I like this year to put into this post, so I may add to it over the coming days. If I add any new items, I will note the added items in Feedback comments.

Saturday, December 27, 2014

In this post, I look at the differences in three "common" methods [equals(Object), hashCode(), and toString()] as generated by NetBeans8.0.2, IntelliJ IDEA14.0.2, and EclipseLuna4.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.

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.

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[]).

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 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.

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 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.

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

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).

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.

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.

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 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.

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:

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

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.

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.

Chapter 3 of Mastering JavaServer Faces 2.2 is all about scopes in JavaServer Faces. The chapter contrastsJSF 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.

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 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."

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 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.

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.

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):

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.