Saturday, November 29, 2014

Manipulating JARs, WARs, and EARs on the Command Line

Although Java IDEs and numerous graphical tools make it easier than ever to view and manipulate the contents of Java archive (JAR, WAR, and EAR) files, there are times when I prefer to use the command-line jar command to accomplish these tasks. This is particularly true when I have to do something repeatedly or when I am doing it as part of a script. In this post, I look at use of the jar command to create, view, and manipulate Java archive files.

JAR files will be used primarily in this post, but the commands I demonstrate on .jar files work consistently with .war and .ear files. It's also worth keeping in mind that the JAR format is based on the ZIP format and so the numerous tools available for working with ZIP files can be applied to JAR, WAR, and EAR files. It's also worth keeping in mind that the jar options tend to mirror tar's options.

For my examples, I want to jar up and work with some .class files. The next screen snapshot demonstrates compiling some Java source code files (.java files) into .class files. The actual source of these files is insignificant to this discussion and is not shown here. I have shown compiling these without an IDE to be consistent with using command-line tools in this post.

Preparing the Files to Be Used in the jar Examples

The next screen snapshot shows my .class files have been compiled and are ready to be included in a JAR.

Creating a JAR File

The "c" option provided to the jar command instructs it to create an archive. I like to use the "v" (verbose) and "f" (filename) options with all jar commands that I run so that the output will be verbose (to help see that something is happening and that it's the correct thing that's happening) and so that the applicable JAR/WAR/EAR filename can be provided as part of the command rather than input or output depending on standard input and standard output. In the case of creating a JAR file, the options "cvf" will create JAR file (c) with specified name (f) and print out verbose output (v) regarding this creation.

The next screen snapshot demonstrates the simplest use of jar cvf. I have changed my current directory to the "classes" directory so that creating the JAR is as simple as running jar cvf * or jar cvf . and all files in the current directory and all subdirectories and files in subdirectories will be included in the created JAR file. This process is demonstrated in the next screen snapshot.

If I don't want to explicitly change my current directory to the most appropriate directory from which to build the JAR before running jar, I can use the -C option to instruct jar to implicitly do this as part of its creation process. This is demonstrated in the next screen snapshot.

Listing Archive's Contents

Listing (or viewing) the contents of a JAR, WAR, or EAR file is probably the function I perform most with the jar command. I typically use the options "t" (list contents of archive), "v" (verbose), and "f" (filename specified on command line) for this. The next screen snapshot demonstrates running jar tvf MyClasses.jar to view the contents of my generated JAR file.

Extracting Contents of Archive File

It is sometimes desirable to extract one or many of the files contained in an archive file to work on or view the contents of these individual files. This is done using jar "x" (for extract) option. The next screen snapshot demonstrates using jar xvf MyClasses.jar to extract all the contents of that JAR file. Note that the original JAR file is left intact, but its contents are all now available directly as well.

I often only need to view or work with one or two files of the archive file. Although I could definitely extract all of them as shown in the last example and only edit those I need to edit, I prefer to extract only the files I need if the number of them is small. This is easily done with the same jar xvf command. By specifying the fully qualified files to extract explicitly after the archive file's name in the command, I can instruct to only extract those specific files. This is advantageous because I don't fill my directory up with files I don't care about and I don't need to worry about cleaning up as much when I'm done. The next screen snapshot demonstrates running jar xvf MyClasses.jar dustin/examples/jar/GrandParent.class to extract only that single class definition for GrandParent rather than extracting all the files in that JAR.

Updating an Archive File

Previous examples have demonstrated providing the jar command with "c" to create an archive, "t" to list an archive's contents, and "x" to extract an archive's contents. Another commonly performed function is to update an existing archive's contents and this is accomplished with jar's "u" option. The next screen snapshot demonstrates creating a text file (in DOS with the copy con command) called tempfile.txt and then using jar uvf MyClasses.jar tempfile.txt to update the MyClasses.jar and add tempfile.txt to that JAR.

If I want to update a file in an existing archive, I can extract that file using jar xvf, modify the file as desired, and place t back in the original JAR with the jar uvf command. The new file will overwrite the pre-existing one of the same name. This is simulated in the next screen snapshot.

Deleting an Entry from Archive File

It is perhaps a little surprising to see no option for deleting entries from a Java archive file when reading the jar man page, the Oracle tools description of jar, or the Java Tutorials coverage of jar. One way to accomplish this is to extract the contents of a JAR, remove the files that are no longer desired, and re-create the JAR from the directories with those files removed. However, a much easier approach is to simply take advantage of the Java archiving being based on ZIP and use ZIP-based tools' deletion capabilities.

The next screen snapshot demonstrates using 7-Zip (on Windows) to delete tempfile.txt from MyClasses.jar by running the command 7z d MyClasses.jar tempfile.txt. Note that the same thing can be accomplished in Linux with zip -d MyClasses.jar tempfile.txt. Other ZIP-supporting tools have their own options.

WAR and EAR Files

All of the examples in this post have been against JAR files, but these examples work with WAR and EAR files. As a very simplistic example of this, the next screen snapshot demonstrates using jar uvf to update a WAR file with a new web descriptor. The content of the actual files involved do not matter for purposes of this illustration. The important observation to make is that a WAR file can be manipulated in the exact same manner as a JAR file. This also applies to EAR files.

Other jar Operations and Options

In this post, I focused on the "CRUD" operations (Create/Read/Update/Delete) and extraction that can be performed from the command-line on Java archive files. I typically used the applicable "CRUD" operation command ("c", "t", "u") or extraction command ("x") used in conjunction with the common options "v" (verbose) and "f" (Java archive file name explicitly specified on command line). The jar command supports operations other than these such as "M" (controlling Manifest file creation) and "0" (controlling compression). I also did not demonstrate using "i" to generate index information for a Java archive.

Additional Resources on Working with Java Archives

I referenced these previously, but summarize them here for convenience.

Conclusion

The jar command is relatively easy to use and can be the quickest approach for creating, viewing, and modifying Java archive files contents in certain cases. Familiarity with this command-line tool can pay off from time to time for the Java developer, especially when working on a highly repetitive task or one that involves scripting. IDEs and tools (especially build tools) can help a lot with Java archive file manipulation, but sometimes the "overhead" of these is much greater than what is required when using jar from the command line.

Wednesday, November 26, 2014

Cannot Uninstall JavaFX SceneBuilder 1.0 with JDK 8

I was recently removing some of the software development applications, tools, and files I had used from an old Vista-based laptop because the people who are primarily using that laptop now have no interest in software development. As part of that effort, I tried to remove JavaFX Scene Builder 1.0, which I had installed a couple of years ago on that laptop. I hadn't used it recently (JavaFX Scene Builder 2.0 is available) but I had not removed the version from the laptop when I stopped using that old version.

My first attempt to remove JavaFX Scene Builder 1.0 was via the Windows Vista menu option Control Panel | Programs | Uninstall a program. The next screen snapshot shows this version of JavaFX Scene Builder 1.0 that I wanted to install along with the version of Java installed on that machine (JDK 8 and Java 8 JRE). No versions of Java (JDK or JRE) before Java 8 were on this machine.

The next screen snapshot demonstrates the normal requested confirmation of the removal of JavaFX Scene Builder 1.0.

Clicking the "Yes" button on the confirmation dialog just shown led to the removal process beginning.

Unfortunately, the removal of JavaFX Scene Builder 1.0 aborted and showed the error message: "No suitable 32-bit Java Runtime Environment (JRE) has been found. You should install Java 6 Update 29 (32-bit) or above OR Java 7 Update 2 (32-bit) or above."

I was a bit surprised that JavaFX Scene Builder could not be uninstalled with a Java 8 JRE installed on the machine. I tried to uninstall it more than once to make sure, but it was resistant to removal with only JRE 8 installed. I ended up simply removing the JavaFX Scene Builder 1.0 directory with Windows Explorer as shown in the next screen snapshot.

Because I could not use the uninstaller to remove JavaFX Scene Builder 1.0, I also needed to manually remove the shortcut as shown in the next screen snapshot.

It was not a big deal to remove the directory and shortcut when the installer was unable to remove JavaFX Scene Builder 1.0 from this machine. It also would not have been too difficult to download and install a Java SE 7 JRE to use in uninstalling JavaFX Scene Builder. However, I was a bit surprised that it was written so that an appropriate version of JRE 6 or JRE 7 was required. It explicitly prevents JRE 8 or any future JRE from being used to uninstall it.

I saw this same type of situation recently with a different tool in a different environment. In that case, the version of SQLDeveloper being used would only work with a certain specified range of updates for Java SE 6 and not for any Java SE 6 updates outside of that range and not for any versions of JDK 7 or JDK 8.

Conclusion

There is a software development reminder (or lesson to be learned) from this. It is easy as humans to think only about the current timeframe and about the past, but we as software developers should put some thought into what the future holds. The prevailing version of software is not always going to be the prevailing version and when our software's documentation or the software itself advertises supporting certain versions "and above" or "and later," then we should probably not put an explicit check in our code that forces the software to have the one of the expected major revisions or that caps the supported versions.

Monday, November 24, 2014

Book Review: RESTful Java Patterns and Best Practices

Bhakti Mehta's RESTful Java Patterns and Best Practices was recently published by Packt Publishing. Consisting of six chapters and an appendix spanning approximately 125 substantive pages, its subtitle is, "Learn best practices to efficiently build scalable, reliable, and maintainable high performance RESTful services."

Preface

The Preface of RESTful Java Patterns and Best Practices begins with a description of why REST is important today. It includes several short summaries of each of the book's chapters. The Preface explains that Maven 3 and GlassFish 4 are required to build and run the book's examples and states that the book is designed as "a perfect reading source for application developers to get familiar with REST."

Chapter 1: REST – Where It Begins

RESTful Java Patterns and Best Practices's initial chapter provides a single paragraph on SOAP/WSDL-based web services before turning attention to REST-based web services. The basic characteristics of and increased "-ilities" provided by REST are described. The Richardson Maturity Model is also examined in some detail. I'm not sure that the Richardson Maturity Model clears things up or muddies them by encouraging interchangeable use of the terms HTTP and REST.

The first chapter includes brief descriptions of the characteristics of safe methods and of idempotent methods and describes which HTTP methods fit each category. The chapter then lists several "design principles for building RESTful services" before describing each in greater detail. This is section provides a brief and highly readable introduction to the basics of REST.

Chapter 1's introduction of the Java API for RESTful Web Services (JAX-RS) includes simple examples of turning POJOs into REST resources using JAX-RS annotations such as @GET, @POST, @Path, @Produces, @Consumes, and @ValidateOnExecution.

Chapter 1 provides a nice introduction to the Client API that is new to JAX-RS 2.0. It also briefly discusses some other approaches one can use to communicate and work with REST-based services: curl, Postman on Chrome, Advanced REST Client for Google Chrome, and JSONLint. Both curl and Postman get extra attention including a color screen snapshot of Postman in the electronic edition I reviewed.

The first chapter concludes with a bullet-format list of "best practices when designing resources," a list of related online resources, and a Summary. Overall, this first chapter is a nice high-level introduction to REST and to Java's approach to REST via JAX-RS. The code examples are simple and short and easy to understand. Just enough detail is provided to get a feel for REST and JAX-RS.

Chapter 2: Resource Design

Chapter 2 of RESTful Java Patterns and Best Practices delves more deeply into HTTP and REST concepts such as content negotiation (including contrasting use of HTTP headers versus URL patterns), alternative resource representation (MessageBodyReader and MessageBodyWriter, StreamingOutput, and ChunkedOutput), Jersey's JSON support (ObjectMapper, @XMLRootElement, JsonArray, and JsonObject), API versioning (comparing URI, request query parameter, and Accept header approaches), HTTP response codes, and the JAX-RS classes Response and ResponseBuilder.

The second chapter provides greater details regarding application of JAX-RS to REST-based application implementation. The examples are relatively short and clear and illustrate well the points being made.

Chapter 3: Security and Traceability

The third chapter opens up with two paragraphs explaining why security and traceability are important in today's REST-based applications. The specific security and traceability topics discussed in this chapter are logging in REST-based applications, exception handling in REST-based applications, validation patterns, and federated identity.

The section on logging from a REST-based application demonstrates writing of a servlet filter (annotated with @WebFilter and implementing Filter) that can log certain metadata about each request as each request occurs. This section also outlines some logging best practices that I'd say are general logging best practices rather than REST-specific logging best practices.

Chapter 3's section on validating services states, "JAX-RS supports the Bean Validation to verify JAX-RS resource classes." The text and accompanying code samples demonstrate use of bean validation with standard annotations such as @ValidateOnExecution, @Valid, and @NotNull and a custom annotation @VerifyValue. This section also demonstrates with code and explanation how to create a custom exception mapper (implementation of ExceptionMapper that "catch[es] thrown application exceptions and write[s] specific HTTP responses.").

Part of Chapter 3 focuses on authentication and authorization. This section introduces Security Assertion Markup Language (SAML) and SAML Web Browser Profile for authentication and OAuth (open authorization) for authorization. This section has some nice graphics (with a bit of color in the PDF version) depicting how authentication with SAML and authorization with OAuth work at a high level.

Chapter 3's coverage or authorization includes more details on characteristics of OAuth 2.0. Access and refresh tokens are covered as is the level of support for OAuth 2.0 provided by Jersey (the Jersey implementation supports client side only and Authorization Code Grant Flow).

The third chapter includes a section titled "Best practices for OAuth [2.0] in the REST API." Although these seem to be generally applicable to use of OAuth whether REST is involved or not, I liked the table presenting different situations and when SAML or OAuth is preferable. There is a very brief section in Chapter 3 that introduces OpenID Connect, which the author describes as "a simple REST- and JSON-based interoperable protocol built on top of OAuth 2.0."

Before concluding with the summary and recommended reading sections typical of chapters in RESTful Java Patterns and Best Practices, the third chapter briefly outlines "REST architectural components" to be covered in more detail later. One "recommended reading" that I found particularly interesting is OAuth 2.0 and the Road to Hell.

Chapter 4: Designing for Performance

RESTful Java Patterns and Best Practices's fourth chapter advertises itself as covering "advanced design principles related to performance that every developer must know when building RESTful services." Discussion of strong and weak HTTP caching headers is preceded by an overview of general caching principles. A code listing and accompanying explanation demonstrate how to specify HTTP caching headers in JAX-RS responses. Similarly, this section also looks at the ETag response-header field and how to apply it to a JAX-RS response. The section of Chapter 4 on caching concludes with a brief description of RESTEasy's extension to JAX-RS caching.

"Asynchronous and long-running jobs in REST" is the second major topic of Chapter 4. This section uses code listings, textual explanations, and sequence diagrams to demonstrate use of JAX-RS 2.0 support for asynchronous processing with constructs such as AsyncResponse, @Suspended, CompletionCallback, ConnectionCallback, InvocationCallback, and Java SE Future interface.

The "Asynchronous resources best practices" section of Chapter 4 briefly describes "best practices when working with asynchronous RESTful resources." These tend to be best practices for working with HTTP asynchronously whether in REST or not.

There is a section in Chapter 4 that discusses dealing with partial updates in a REST application using PATCH, PUT, or POST. This section demonstrates creation of an annotation called @PATCH to annotate JAX-RS methods to be used for patch functionality.

The final section of Chapter 4 of RESTful Java Patterns and Best Practices before its summary and recommended reading section is on JSON Patch. This section provides a brief overview of JSON Patch and provides code listing and explanations of how to use JSON Patch.

Chapter 5: Advanced Design Principles

The promise of RESTful Java Patterns and Best Practices's fifth chapter is to cover "advanced design principles that every developer must know when designing RESTful services." The covered topics are rate-limiting patterns, response pagination, internationalization and localization, REST pluggability and extensibility, and some miscellaneous topics. The section on rate-limiting pagination is relatively lengthy and includes code snippets and discussion as well as an outline of some best practices for reducing and avoiding rate-limiting pagination.

"Response pagination" is covered in the fifth chapter, which looks at three types of response pagination: Offset-based pagination, Time-based pagination, and Cursor-based pagination. The chapter then provides an example of implementing offset-based pagination with JAX-RS.

Chapter 5's section on internationalization and localization describes the setting of localization parameters on HTTP headers, on query parameters, and as part of REST responses. Discussion in this section on runtime content negotiation covers HTTP headers Accept-Language and Content-Language and application of the JAX-RS Variant class.

The "Miscellaneous topics" section of Chapter 5 discusses Hypermedia as the Engine of Application State (HATEOAS), which I believe is one of the most commonly misunderstood and under-appreciated features of REST for those new to REST. This chapter's introduction, which includes examples, is a relatively straightforward and concise introduction to the topic. After introducing HATEOAS, the chapter uses an example of PayPal's REST API support for HATEOAS to illustrate real-world application of HATEOAS.

Another Chapter 5 "Miscellaneous Topic" addresses REST extensibility. This is only covered very briefly (single paragraph) and makes assertions about REST being more maintainable and readable (presumably than SOAP-based web services) with lightly offered justification for these claims. Given how little concrete evidence (and no practical examples) is provided, this section is not very compelling.

Chapter 5 concludes with a brief discussions of topics related to documenting and testing REST-based applications. The most appealing part of this coverage for me was the reference to tools that can be used for testing and documenting REST-based applications. This section introduces REST Assured, which it describes as "the Java DSL for easy testing of RESTful services," and provides a simple illustrative example of this in action. The coverage of Swagger does not illustrate its use, but does describe it as "a language-agnostic framework implementation for describing, producing, consuming, and visualizing RESTful web services."

Chapter 6: Emerging Standards and the Future of REST

Although the Fielding dissertation that codified the REST concept was published in 2000, it continuing rising popularity has meant new developments in understanding and applying of the REST architectural style and in the available related tooling. This chapter begins by describing real-time APIs and describing polling and the disadvantages of polling.

Chapter 6 provides brief explanations of how PubSubHubbub and streaming can each be used to address the limitations of polling. Both of these approaches are explained with text and simple graphics. The section on streaming discusses server-sent events (SSE) and their nonstandard support in Jersey.

RESTful Java Patterns and Best Practices's final chapter also introduces WebHooks, which it defines as "a form of user-defined custom HTTP callbacks." This section uses text description, simple graphics, and coverage of implementing case studies to explain this topic. The WebSockets protocol is also covered in the sixth chapter and is described as "a protocol that provides full-duplex communication channels over a single TCP connection." WebSockets is explained with text descriptions, simple graphics, a table, and a code listing. A couple paragraphs each are also dedicated to introducing (at a conceptual level) XMPP and BOSH over XMPP.

Chapter 6 includes a section with text and a table that compares and constrasts WebHooks, WebSockets, and Server-Sent Events. Chapter 6's section "REST and Micro Services" briefly describes "different advantages of Micro Services as compared to monolithic services."

As is the case with the previous five chapters, Chapter 6 ends with a "Recommended Reading" section and a "Summary." The "Summary" is mostly a summary of the chapter rather than the book, though there is a reference to another book co-authored by this book's author: Developing RESTful Services with JAX-RS 2.0, WebSockets, and JSON. The summary for the overall book is left to the Appendix, which is really just another chapter and which I review later in this post.

The sixth and final chapter of RESTful Java Patterns and Best Practices is a high-level overview of trending considerations for REST-based applications. This chapter has very little Java-specific (or JAX-RS-specific) content.

Appendix

Although RESTful Java Patterns and Best Practices's table of contents lists six chapters and an appendix, the Appendix feels just like the six chapters. It not only has "Recommended Reading" and "Summary" sections like its preceding chapters, but it even includes text that refers to "this chapter." The chapter/appendix introduces three REST APIs: REST API from GitHub, Open Graph API from Facebook, and REST API from Twitter. For me, the most interesting aspect of these introductions was how the author illustrated some of the patterns covered previously in the book from each covered API's perspective. This provides reinforcement with concrete APIs of some of the previously discussed concepts and patterns.

The Appendix's "Summary" summarizes the appendix and the entire book.

General Observations

  • The code listings in RESTful Java Patterns and Best Practices are black text on white background with no color syntax (even in the PDF version) and no line numbers. Most of the code listings are short enough that color syntax and line numbers are not as important as they otherwise might be.
  • I liked the approach taken in RESTful Java Patterns and Best Practices of presenting small snippets of code to illustrate points being made and referencing the code available for download for additional and context code.
  • There are several illustrative graphics in RESTful Java Patterns and Best Practices, a few of of them with multiple colors in the PDF edition and some of them in grayscale, and many of them black font on white background, even in the PDF edition.
  • There are some typos in RESTful Java Patterns and Best Practices. They're generally minor and I provide some examples here to demonstrate their nature:
    • One sentence states, "JAX-RS 2.0 had newer Client APIs for accessing RESTful resources."
    • The section introducing JAX-RS annotations discusses @PATH when it really should be @Path.
    • The section on JSON and Jersey references JSONArray and JSONObject when JsonArray and JsonObject are intended.
    • The acronym PPI when spelled out only has an opening parenthesis and not a closing parenthesis.
  • I liked how each chapter included a "Recommended Reading" section with several freely available online resources, most of which had been referenced earlier in the chapter.
  • I liked the Appendix's use of three popular REST APIs to illustrate some of the concepts and patterns introduced in the book's six chapters.
  • In some cases, I would have liked to see more Java/JAX-RS implementation details for certain patterns, especially in the sixth chapter.
  • Other reviews of RESTful Java Patterns and Best Practices are available and worth checking out for a more complete overall picture of the book based upon multiple perspectives:

Conclusion

RESTful Java Patterns and Best Practices introduces basic REST concepts, patterns, and practices and how to apply many of those patterns and concepts with JAX-RS. This book is probably best suited for those looking for introductory information on a broad set of considerations pertinent to REST applications and implementing those considerations with Java and JAX-RS. For those seeking more detailed coverage of REST principles and JAX-RS application of those principles, RESTful Java with JAX-RS 2.0 might be more appropriate.

Saturday, November 15, 2014

Book Review: JavaScript Promises Essentials

Because JavaScript Promises are a trendy web development topic that I know very little about, I accepted Packt Publishing's offer to review the electronic (PDF) edition of Rami Sarieddine's JavaScript Promises Essentials. Sarieddine introduces this book on his blog post JavaScript Promises Essentials. The subtitle of the book is, "Build fully functional web applications using promises, the new standard in JavaScript." JavaScript Promises Essentials is a short book with six chapters and a preface covering approximately 70 pages of substantive content.

Preface

The "Preface" of JavaScript Promises Essentials states that the book is "a practical guide to the new concept of promises" that "presents a single resource replacing all the scattered information out there about the topic" (I added the links). The Preface introduces the concept of promises and why they are useful.

JavaScript Promises Essentials's Preface provides very brief summaries of each of its chapters before covering what readers of the book need when reading it. The author states that readers "just need an HTML and JavaScript editor" and recommends three candidates: Microsoft Visual Studio Express 2013 for Web, Microsoft's WebMatrix, or jsFiddle. The Preface also suggests that JavaScript Promises Essentials is designed for "all developers who are involved in JavaScript programming" with special appeal for those "interested in learning about asynchronous programming in JavaScript and the new standard that will make that experience much better."

Chapter 1: JavaScript Promises – Why Should I Care?

The initial chapter of JavaScript Promises Essentials provides a brief summary of JavaScript and how it became a popular programming language, especially in web browsers. The chapter talks about how web development and user experience has progressed. The chapter provides a basic overview and examples of applying JavaScript event handlers and callback functions.

Chapter 1 also includes a section "Why should I care about promises?" that starts with a definition of promise quoted from the Promises/A+ web page: "A promise represents the eventual result of an asynchronous operation." After presenting this simple introductory definition, the chapter then moves onto further elaboration on the nature of promises (incuding having state and being immutable). This section provides a nice overview of what JavaScript promises are and the syntax for them.

Part of Chapter 1 demonstrates how complicated chained callbacks can become and how much easier they are to read when presented as promises instead. The chapter concludes with an interesting summary: "Promises are a pattern that allows for a standardized approach in asynchronous programming" and enables "developers to write asynchronous code that is more readable and maintainable."

Chapter 2: The Promise API and Its Compatibility

JavaScript Promises Essentials's second chapter covers "current browser support for the promises standard" and "JavaScript libraries out there that implement promises and promise-like features." Coverage of the Promises API begins by contrasting the Promises/A+ specification with the Promises/A specification and focusing on additions, removals ("omissions"), and clarifications. This discussion gets fairly deep into the descriptions of the rules to be supported by Promises/A+ implementations.

The second chapter's discussion rises back to a higher level of discussion on "browser support and compatibility" for promises. This includes a reproduction (in color in electronic edition) of the Promises portion of the "ECMAScript 6 compatibility table" provided by kangax. The author introduces Remy Sharp's concept of a polyfill ("piece of code (or plugin) that provides the technology that you, the developer, expect the browser to provide natively") and then references a particular polyfill for web browsers that don't support promises natively.

Chapter 2 moves onto coverage of "libraries with promise-like features" and provides descriptions of libraries that implement "the promises concept" (though not necessarily ECMAScript 6 or Promises/A+ compliant). The briefly described libraries are kriskowal/q, tildeio/rsvp.js, cujojs/when.js, the then collection, and jQuery.Deferred().

Chapter 3: Chaining of Promises

The third chapter of JavaScript Promises Essentials revisits the discussion from the first chapter about the disadvantages of using chained callbacks in JavaScript and how promises address those callbacks. The author states that promises provide a "straightforward, standard mechanism to chain asynchronous operations." This short chapter provides fairly detailed introductory examples of chaining promises.

Chapter 4: Error Handling

The fourth chapter of JavaScript Promises Essentials begins with a brief explanation of the challenges of dealing with asynchronous error handling in JavaScript before looking at how promises address these challenges. Discussion and examples illustrate use of then, catch, onFulfilled, and onRejected.

Chapter 5: Promises in WinJS

The focus of Chapter 5 of JavaScript Promises Essentials is on WinJS, an implementation of Promises. The chapter briefly introduces WinJS and advantages of using WinJS. This discussion includes mention of the increasing number of environments supporting WinJS and the open sourcing of WinJS. The WinJS namespace is introduced with an introduction to its basic features including xhr and Promise.

Unsurprisingly, the fifth chapter emphasizes the WinJS.Promise object. The three main components of a WinJS.Promise object (Constructors, single Event, and Methods) are discussed. The discussion on WinJS.Promise's methods contrasts the then and done methods. This section also explains that WinJS is compliant with Promises/A, but not tested for compliance with Promises/A+ and explains practical ramifications of this.

JavaScript Promises Essentials's fifth chapter includes an example (including color screen snapshot) of using Visual Studio to apply a WinJS promise. The example includes use of WinJS.Utilities.ready and WinJS.xhr. I like that the author recommends http://try.buildwinjs.com/ for those interested in trying out WinJS. For those who are not using WinJS, this chapter could probably be skipped, though there are some general ideas of promises that come out in the chapter even as it discusses WinJS specifically.

Chapter 6: Putting It All Together – Promises in Action

Chapter 6 of JavaScript Promises Essentials begins by explaining and demonstrating creation of "a minimal JavaScript library that implements promises." I found this final chapter of JavaScript Promises Essentials to be one of the more interesting as the explanations of building a promise implementation in JavaScript definitely provided concreteness that helped solidify my understand of JavaScript promises.

Once the simple promises implementation is built, the chapter moves onto using that implementation in examples. The chapter's summary also serves as a summary of the entire book.

General Observations

  • JavaScript Promises Essentials provides a general overview of JavaScript promises fit for general development. However, it is is particularly relevant for Windows developers with a chapter focused on a Windows-specific implementation of Promises.
  • Some of the text in the book is a bit choppy and some of it I'm not even sure conveys what was originally intended. Here is an example: "Callbacks are lightweight since we need to add extra libraries."
  • There are a few illustrations in JavaScript Promises Essentials. Some of them are in color and some are in grayscale even in the PDF. In one case, a flow chart in chapter 4, the text references green and red colors but the illustration is grayscale.
  • The code listings are black font on white background with proper indenting but without line numbers or color syntax highlighting.
  • Because book reviews are opinionated by nature, it can be useful to read several different reviews for different opinions. Other reviews can be found (or likely soon will be found) at the following sources:

Conclusion

JavaScript Promises Essentials covers one of the trendiest concepts (promises) in one of today's most popular languages (JavaScript). The book is no longer than it needs to be and provides a nice overview of implementing and using promises in JavaScript. It is especially well suited for Windows developers with one of its six chapters entirely focused on WinJS, but the other five chapters are of benefit to anyone who wants to know more about applying promises in JavaScript.

The information in JavaScript Promises Essentials is generally conveyed well, though there are some awkward (and sometimes too lengthy) sentences. Some of the book's strengths include coverage of the Promises/A and Promises/A+ standards, coverage of the current state of promises in JavaScript, and description of current JavaScript Promises implementations and libraries.