Wednesday, June 25, 2014

Book Review: Penetration Testing with the Bash Shell

This post is my review of the Packt Publishing book Penetration Testing with the Bash shell by Keith Makan. I think it's important to emphasize its subtitle: "Make the most of the Bash shell and Kali Linux's command-line-based security assessment tools." As the main title and sub-title suggest, this book is about penetration testing with Bash using the Kali Linux. The book has approximately 125 pages covering 5 chapters.

The Preface of Penetration Testing with the Bash shell begins with an articulation of why it is important for penetration testers to be familiar with command-line tools. The Preface also provides brief summaries of each of the five chapters in the book and some of the command-line tools covered in each chapter.

Under the "What you need for this book" section of Penetration Testing with the Bash shell's Preface, Makan writes, "The only software requirement for this book is the Kali Linux operating system, which you can download in the ISO format from http://www.kali.org." You don't necessarily need to use Kali Linux as many of the bash examples and described command-line tools are also available with or for other Linux distributions. The "Who this book is for" section of the Preface states, "Command line hacking is a book for anyone interested in learning how to wield their Kali Linux command lines to perform effective penetration testing."

Chapter 1: Getting to Know Bash

The initial chapter explains that "throughout the book, the bash environment or the host operating system that will be discussed will be Kali Linux" and that "Kali Linux is a distribution adapted from Debian." The chapter then goes onto explain with text and examples Bash concepts such as man pages and bash commands such cd, ls, pwd, and find. The chapter also describes using Linux redirection (output and input) and pipes before concluding with a discussion of grep and regular expressions. As the author suggests, this chapter could be generally be skipped by developers familiar with Linux, but would be must-read information for those new to Linux. Although Kali Linux is used for the examples, I didn't see anything in this initial chapter that seemed specific to Kali Linux.

Chapter 2: Customizing Your Shell

The second chapter of Penetration Testing with the Bash shell begins with coverage of terminal control sequences to change appearance of text in the terminal. The chapter builds upon this information to demonstrate customization of the terminal prompt. Chapter 2 also introduces aliases, customizing command history, and customizing tab completion. Like the first chapter, this second chapter covers additional general Bash concepts rather than specifics of penetration testing.

Chapter 3: Network Reconnaissance

Chapter 3 of Penetration Testing with the Bash shell transitions from coverage of Linux and bash to "move on to using the shell and the Kali Linux command-line utilities to collect information about the networks you find yourself in." The chapter examines tools such as whois, dig, dnsmap, Nmap, and arping.

Chapter 4: Exploitation and Reverse Engineering

Penetration Testing with the Bash shell's fourth chapter focuses on reverse engineering and tools that "may enable you to discover memory corruption, code injection, and general data- or file-handling flaws that may be used to instantiate arbitrary code execution vulnerabilities." Tools covered in this chapter include Metasploit (including command-line msfcli, mixing msfcli with bash commands and other command line tools, msfpayload, Meterpreter), objdump, and GDB.

Chapter 5: Network Exploitation and Monitoring

The fifth and final chapter of Penetration Testing with the Bash shell focuses "on the network exploitation available in Kali Linux and how to take advantage of it in the modern bash shell environment." This relatively longer chapter begins with discussion of "Media Access Control (MAC) spoofing" and "Address Resolution Protocol (ARP) abuse." The chapter looks at tools such as macchangeer, ifconfig, arpspoof.

Chapter 5 describes man-in-the-middle (MITM) attacks and provides a detailed introduction to ettercap. The chapter also explains server interrogation and describes tools for Simple Network Management Protocol (SNMP) interrogation (snmpwalk and Metasploit's snmp_enum and snmp_login) and for Simple Mail Transfer Protocol (SMTP) interrogation (smtp-user-enum).

There is a section in Chapter 5 on brute force authentication that demonstrates use of Medusa. The section of Chapter 5 on traffic filtering demonstrates use of TCPDump. SSLyze is demonstrated as a tool for "assess[ing] SSL/TLS implementations" and SkipFish and Arachni are demonstrated as tools for scanning web pages and web applications for vulnerabilities.

General Observations
  • The electronic version of Penetration Testing with the Bash shell that I reviewed included numerous colored screen snapshots.
  • I liked the "Further Reading" sections at the end of each chapter that provided links to online information with more detail about subjects covered in the chapter.
  • The first two chapters of Penetration Testing with the Bash shell have very little information specific to penetration testing but provide an overview of some bash features used in later chapters. The third, fourth, and fifth chapters are heavily focused on penetration testing and build upon the bash basics covered in the first two chapters.
  • Penetration Testing with the Bash shell provides background information on various security and assessment concepts as its illustrates the tools available that are related to those concepts.
  • There are some awkward sentence structures in Penetration Testing with the Bash shell and several of the sentences are too long for my taste (especially early in the book), but I was generally able to make out the intent of the writing. An example of the occasional awkward but understandable text is on the first page of the first chapter: "Why are discussing the bash shell?"
  • Although this book does mention Kali Linux specifically and frequently, the majority of the described tools are available as built-in tools or as tools that can be installed separately with other flavors of Linux. With no or just a a bit of effort, one could run the examples in different Linux implementations. It's also worth pointing out that the author repeatedly mentions that several commands runs with no special effort in Kali Linux because things are run as root. In other Linux implementations, you may need to use sudo to apply these tools.
  • Although I am fairly familiar with bash, I still learned a few new things from the first two chapters (primarily the second chapter). I am far less experienced with penetration testing and learned quite a bit from the other three chapters.
Conclusion

Penetration Testing with the Bash shell: Make the most of the Bash shell and Kali Linux's command-line-based security assessment tools outlines how bash in general and Kali Linux in particular provide command-line security assessment tools. The book introduces the tools and how to apply them and explains security-related concepts along the way.

Monday, June 23, 2014

I Don't Think That Software Development Word Means What You Think It Means

There are several terms used inappropriately or incorrectly in software development. In this post, I look at some of these terms and the negative consequences of misuse of these terms.

"agile"

The Agile Manifesto started a movement that resonated with many software developers frustrated with inefficiencies and inadequacies of prevalent software development methodologies. Unfortunately, the relatively simple concepts of the Agile Manifesto were interpreted, changed, evangelized, commercialized, and sold in so many different ways that it became difficult to uniquely describe agile. To some, agile became synonymous with "no documentation" and to others agile meant going straight to coding without any process. So many disparate methodologies and practices are now sold as agile that it's become increasingly difficult to describe what makes something agile or not.

There have been several negative consequences of the multiple interpretations of what agile means. Implementation of so-called agile practices without understanding of agile can lead to failures that are blamed on agile, but which failures may have little or nothing to do with agile. Unrealistic expectations of agile and what it can do for development can lead to inevitable disappointment as there still is no silver bullet. It is difficult to help new developers, developers new to agile, managers, customers, and other stakeholders understand what agile is and how it may or may not be appropriate for them with so many different interpretations. I was at a presentation by an agile enthusiastic several years ago when he suggested that agile was anything that was successful and was not anything that is not successful.

For me, "agile" means processes and approaches that closely match the values outlined in the Agile Manifesto (individuals and interactions, working software, customer collaboration, and responding to change). There are other approaches and methodologies out there that may be useful and positive, but if they aren't inspired by these values, it is difficult for me to hear them called "agile."

"REST"

Roy Fielding's dissertation Architectural Styles and the Design of Network-based Software Architectures popularized the term Representational State Transfer (REST). Unfortunately, many have used REST and HTTP interchangeably and in the process have muddled the conversations about both the REST architectural style and the Hypertext Transfer Protocol (HTTP).

It is easy to see from a historical perspective why REST and HTTP are often treated interchangeably. REST embraced the functionality already provided by HTTP as a significant part of its architectural style at a time other popular architectural styles and frameworks were doing everything they could to hide or abstract away HTTP specifics details. REST leverages HTTP's stateless nature while others were trying to wrap HTTP with state. Although REST certainly played a major role in raising awareness of HTTP, REST is more than HTTP. I have found that many who think of REST and HTTP as one and the same don't appreciate the HATEOAS concept in REST. HATEOAS stands for Hypermedia as the Engine of Application State and refers to the concept of application state being embodied within the hypermedia exchanged between server and client rather than in the client.

"refactoring"

I've known of clients and managers filled with dread when they hear a developer state that he or she is going to "refactor" something. The reason is that "refactoring" too often means the developer plans to change the code structure and "improve" or "fix" behavior as part of this. Refactoring is supposed to be code improvements that do not effect the results of the software but lead to more maintainable code. Too many developers are lured into making other changes "while they are in the code" that change results. Even when for the better, these changes are not in the spirit of refactoring and so, when they have led to breaking of existing functionality, have led to "refactoring" being seen in a bad light.

Comprehensive unit tests and other tests can help ensure that refactoring does not change any expected behavior, but developers should also clearly understand whether the goal is to maintain current functionality with improved code structure (refactor) or actually change/improve functionality and only use the term "refactoring" when appropriate to avoid confusion.

"premature optimization"

I generally agree with the principle behind the now famous quotation, "Premature optimization is the root of all evil." However, my interpretation of this is that one should not write less maintainable or less readable code in an attempt to achieve small expected performance gains. However, as I posted in When Premature Optimization Isn't, this term occasionally gets used as justification for not making good architecture and high-level design decisions just because they have a performance benefit associated with them. Some architectural decisions are difficult to change at a later point and performance does need to be accounted for. Similarly, even at implementation level, there are times when better performing code is as readable and easy to write as less performing code and so there is no good reason to not write the better performing code.

NoSQL

The term NoSQL was an unfortunate one for a class of databases that probably would have been better labeled "Not Relational." As numerous "NoSQL databases" have adopted SQL (without adopting the relational model), alternative terms have been tried such as "Not Just SQL."

"open source"

The term "open source" has often led to confusion about whether the software in question is "free" in terms of "freedom" (libre/free speech) and/or "free" in terms of no monetary price (gratuit/free beer). There can even be confusion about the minor differences between "open source" and "free software." For me, "open source" means source code that I can look at and modify as necessary.

JavaScript

With JavaScript's increased popularity, its poorly chosen name does not seem to confuse as many people as it used to. However, I still do occasionally hear people who think that JavaScript must have some relationship to Java because "Java" is in both languages' names.

SLOC

I generally despise everything about the idea of source line of code. The appeal of SLOC is the pretense that somehow lines of code can be counted the same as beans and widgets. All lines of code are not created equal and there are differences in lines of code across different languages, across different developers, and across different functionality. Some have even gone so far as to think that more SLOC is always a good thing whereas I've found that more concise code with fewer lines of code can often be preferable. I have blogged before on lines of code and unintended consequences.

SOAP

This one is not a big deal in terms of negative consequences from its misuse, but it is worth noting that SOAP no longer stands for Simple Object Access Protocol.

JDBC

This is another one that doesn't really lead to any problems even though it technically has never stood for Java Database Connectivity and is not even an acronym. The fact that it does indeed relate to connecting to databases, that it is Java-related, and that it is so widely said to stand for Java Database Connectivity means that this misuse of the term JDBC has no significant negative side effects. In fact, I suspect that Sun Microsystems folks intentionally wanted people to think of it as an acronym for Java Database Connectivity while explicitly stating that it was not an acronym because it allowed people to quickly understand what JDBC is via their awareness of ODBC.

Conclusion

The incorrect use of many of the terms discussed in this post could be described as largely pedantic, but misuse of a few of them can lead to miscommunication and general confusion. In some cases (such as "agile" and "refactoring"), the misuse of terms has led to negative experiences and soiled reputations for those terms. In other cases (such as using JDBC and SOAP as acronyms when they really are not acronyms), the confusion seems small and harmless as everyone discussing the falsely advertised "acronym" seems to understand what it implies.

Monday, June 2, 2014

Review: DZone's 2014 Guide to Mobile Development

DZone is launching the public release of its DZone's 2014 Guide to Mobile Development today. The 35-page PDF is intended to be used with the DZone Mobile Development Research site to "explore the mobile application development landscape, examining best-practice strategies and comparing tools and frameworks that accelerate mobile development."

For those desiring an "executive summary" of the state of mobile development as described in DZone's 2014 Guide to Mobile Development, a single page (page 3) contains a paragraph and five bullets summarizing what the guide covers along with four "key takeaways" from the mobile development research.

The "Key Research Findings" section (pages 4 and 5) includes summary text and colorful graphics to illustrate results of surveys of mobile developers. The findings include things such as types of mobile developers, types of mobile applications being developed, and common timeline for mobile app development.

Pages 6 and 7 of DZone's 2014 Guide to Mobile Development look at developing mobile apps as web apps, as native apps, and as hybrids of those. Pages 10 and 11 elaborate more on the "state" of apps that are native, web-based, and hybrid and presents a table of 7 comparison factors for the three approaches.

Pages 14-15 of DZone's 2014 Guide to Mobile Development discuss issues related to integration of mobile applications with back-end enterprises. Pages 21-22 discuss perceived performance versus actual performance metrics.

The 23rd page of DZone's 2014 Guide to Mobile Development features a "Mobile Application Development Checklist." Pages 24-34 are the "Solutions Directory" and it is this section that may be of most interest to those trying to decide on tools, frameworks, and platforms to use in their new mobile development projects. Each "solution" has a brief description listed along with certain characteristics (the set of characteristics depend on whether it is a framework, mobile application development platform [MADP], or both).

The DZone 2014 Guide to Mobile Development also includes several pages of full-page advertisements as well as pages split in half with the top half containing text about a mobile development issue and the bottom half containing an advertisement for a related solution addressing the need discussed in text. These half-page text sections and associated advertisements are typically written by "research partners" (Progress/Progress Pacific, Outsystems/Outsystems Platform, ICEsoft/ICEmobile, Telerik/Telerik Platform, and New Relic Mobile Monitoring).

The DZone 2014 Guide to Mobile Development is a polished product that will likely be of most benefit to those considering starting mobile application development or those just entering mobile application development. Although it contains ideas likely to interest even more experienced mobile application developers, much of it is introductory in nature. Experienced mobile developers who want to see what others are doing will also find the research findings interesting and may find it useful if they are looking for an alternate framework or MADP to adopt. This report is not a highly detailed, but instead focuses on high-level trends, survey results, and product offerings that affect mobile development.

The sections of DZone's 2014 Guide to Mobile Development that I found most interesting are the Summary and Key Takeaways, Key Research Findings, Cross-Platform Problems and Solutions, The State of Native vs. Hybrid vs. Web, the checklist, and the Solutions Directory. Reading this report has helped solidify some of my opinions by providing background and support, has helped me increase my understanding of a couple things, and helped me to think about some common mobile development issues from a different perspective. I also was able to read about some frameworks and MADPs that I had not previously been aware of. In short, this report provides a succinct and well presented summary of the overall current state of mobile development.

Tuesday, May 27, 2014

Connecting to Cassandra from Java

In my post Hello Cassandra, I looked at downloading the Cassandra NoSQL database and using cqlsh to connect to a Cassandra database. In this post, I look at the basics of connecting to a Cassandra database from a Java client.

Although there are several frameworks available for accessing the Cassandra database from Java, I will use the DataStax Java Client JAR in this post. The DataStax Java Driver for Apache Cassandra is available on GitHub. The datastax/java-driver GitHub project page states that it is a "Java client driver for Apache Cassandra" that "works exclusively with the Cassandra Query Language version 3 (CQL3)" and is "licensed under the Apache License, Version 2.0."

The Java Driver 2.0 for Apache Cassandra page provides a high-level overview and architectural details about the driver. Its Writing Your First Client section provides code listings and explanations regarding connecting to Cassandra with the Java driver and executing CQL statements from Java code. The code listings in this post are adaptations of those examples applied to my example cases.

The Cassandra Java Driver has several dependencies. The Java Driver 2.0 for Apache Cassandra documentation includes a page called Setting up your Java development environment that outlines the Java Driver 2.0's dependencies: cassandra-driver-core-2.0.1.jar (datastax/java-driver 2.0), netty-3.9.0-Final.jar (netty direct), guava-16.0.1.jar (Guava 16 direct), metrics-core-3.0.2.jar (Metrics Core), and slf4j-api-1.7.5.jar (slf4j direct). I also found that I needed to place LZ4Factory.java and snappy-java on the classpath.

The next code listing is of a simple class called CassandraConnector.

CassandraConnector.java
package com.marxmart.persistence;

import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.Host;
import com.datastax.driver.core.Metadata;
import com.datastax.driver.core.Session;

import static java.lang.System.out;

/**
 * Class used for connecting to Cassandra database.
 */
public class CassandraConnector
{
   /** Cassandra Cluster. */
   private Cluster cluster;

   /** Cassandra Session. */
   private Session session;

   /**
    * Connect to Cassandra Cluster specified by provided node IP
    * address and port number.
    *
    * @param node Cluster node IP address.
    * @param port Port of cluster host.
    */
   public void connect(final String node, final int port)
   {
      this.cluster = Cluster.builder().addContactPoint(node).withPort(port).build();
      final Metadata metadata = cluster.getMetadata();
      out.printf("Connected to cluster: %s\n", metadata.getClusterName());
      for (final Host host : metadata.getAllHosts())
      {
         out.printf("Datacenter: %s; Host: %s; Rack: %s\n",
            host.getDatacenter(), host.getAddress(), host.getRack());
      }
      session = cluster.connect();
   }

   /**
    * Provide my Session.
    *
    * @return My session.
    */
   public Session getSession()
   {
      return this.session;
   }

   /** Close cluster. */
   public void close()
   {
      cluster.close();
   }
}

The above connecting class could be invoked as shown in the next code listing.

Code Using CassandraConnector
/**
 * Main function for demonstrating connecting to Cassandra with host and port.
 *
 * @param args Command-line arguments; first argument, if provided, is the
 *    host and second argument, if provided, is the port.
 */
public static void main(final String[] args)
{
   final CassandraConnector client = new CassandraConnector();
   final String ipAddress = args.length > 0 ? args[0] : "localhost";
   final int port = args.length > 1 ? Integer.parseInt(args[1]) : 9042;
   out.println("Connecting to IP Address " + ipAddress + ":" + port + "...");
   client.connect(ipAddress, port);
   client.close();
}

The example code in that last code listing specified default node and port of localhost and port 9042. This port number is specified in the cassandra.yaml file located in the apache-cassandra/conf directory. The Cassandra 1.2 documentation has a page on The cassandra.yaml configuration file which describes the cassandra.yaml file as "the main configuration file for Cassandra." Incidentally, another important configuration file in that same directory is cassandra-env.sh, which defines numerous JVM options for the Java-based Cassandra database.

For the examples in this post, I will be using a MOVIES table created with the following Cassandra Query Language (CQL):

createMovie.cql
CREATE TABLE movies
(
   title varchar,
   year int,
   description varchar,
   mmpa_rating varchar,
   dustin_rating varchar,
   PRIMARY KEY (title, year)
);

The above file can be executed within cqlsh with the command source 'C:\cassandra\cql\examples\createMovie.cql' (assuming that the file is placed in the specified directory, of course) and this is demonstrated in the next screen snapshot.

One thing worth highlighting here is that the columns that were created as varchar datatypes are described as text datatypes by the cqlsh describe command. Although I created this table directly via cqlsh, I also could have created the table in Java as shown in the next code listing and associated screen snapshot that follows the code listing.

Creating Cassandra Table with Java Driver
final String createMovieCql =
     "CREATE TABLE movies_keyspace.movies (title varchar, year int, description varchar, "
   + "mmpa_rating varchar, dustin_rating varchar, PRIMARY KEY (title, year))";
client.getSession().execute(createMovieCql);

The above code accesses an instance variable client. The class with this instance variable that it might exist in is shown next.

Shell of MoviePersistence.java
package dustin.examples.cassandra;

import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Row;

import java.util.Optional;

import static java.lang.System.out;

/**
 * Handles movie persistence access.
 */
public class MoviePersistence
{
   private final CassandraConnector client = new CassandraConnector();

   public MoviePersistence(final String newHost, final int newPort)
   {
      out.println("Connecting to IP Address " + newHost + ":" + newPort + "...");
      client.connect(newHost, newPort);
   }

   /**
    * Close my underlying Cassandra connection.
    */
   private void close()
   {
      client.close();
   }
}

With the MOVIES table created as shown above (either by cqlsh or with Java client code), the next steps are to manipulate data related to this table. The next code listing shows a method that could be used to write new rows to the MOVIES table.

/**
 * Persist provided movie information.
 *
 * @param title Title of movie to be persisted.
 * @param year Year of movie to be persisted.
 * @param description Description of movie to be persisted.
 * @param mmpaRating MMPA rating.
 * @param dustinRating Dustin's rating.
 */
public void persistMovie(
   final String title, final int year, final String description,
   final String mmpaRating, final String dustinRating)
{
   client.getSession().execute(
      "INSERT INTO movies_keyspace.movies (title, year, description, mmpa_rating, dustin_rating) VALUES (?, ?, ?, ?, ?)",
      title, year, description, mmpaRating, dustinRating);
}

With the data inserted into the MOVIES table, we need to be able to query it. The next code listing shows one potential implementation for querying a movie by title and year.

Querying with Cassandra Java Driver
/**
 * Returns movie matching provided title and year.
 *
 * @param title Title of desired movie.
 * @param year Year of desired movie.
 * @return Desired movie if match is found; Optional.empty() if no match is found.
 */
public Optional<Movie> queryMovieByTitleAndYear(final String title, final int year)
{
   final ResultSet movieResults = client.getSession().execute(
      "SELECT * from movies_keyspace.movies WHERE title = ? AND year = ?", title, year);
   final Row movieRow = movieResults.one();
   final Optional<Movie> movie =
        movieRow != null
      ? Optional.of(new Movie(
           movieRow.getString("title"),
           movieRow.getInt("year"),
           movieRow.getString("description"),
           movieRow.getString("mmpa_rating"),
           movieRow.getString("dustin_rating")))
      : Optional.empty();
   return movie;
}

If we need to delete data already stored in the Cassandra database, this is easily accomplished as shown in the next code listing.

Deleting with Cassandra Java Driver
/**
 * Deletes the movie with the provided title and release year.
 *
 * @param title Title of movie to be deleted.
 * @param year Year of release of movie to be deleted.
 */
public void deleteMovieWithTitleAndYear(final String title, final int year)
{
   final String deleteString = "DELETE FROM movies_keyspace.movies WHERE title = ? and year = ?";
   client.getSession().execute(deleteString, title, year);
}

As the examples in this blog post have shown, it's easy to access Cassandra from Java applications using the Java Driver. It is worth noting that Cassandra is written in Java. The advantage of this for Java developers is that many of Cassandra's configuration values are JVM options that Java developers are already familiar with. The cassandra-env.sh file in the Cassandra conf directory allows one to specify standard JVM options used by Cassandra (such as heap sizing parameters -Xms, -Xmx, and -Xmn),HotSpot-specific JVM options (such as -XX:-HeapDumpOnOutOfMemoryError, -XX:HeapDumpPath, garbage collection tuning options, and garbage collection logging options), enabling assertions (-ea), and exposing Cassandra for remote JMX management.

Speaking of Cassandra and JMX, Cassandra can be monitored via JMX as discussed in the "Monitoring using JConsole" section of Monitoring a Cassandra cluster. The book excerpt The Basics of Monitoring Cassandra also discusses using JMX to monitor Cassandra. Because Java developers are more likely to be familiar with JMX clients such as JConsole and VisualVM, this is an intuitive approach to monitoring Cassandra for Java developers.

Another advantage of Cassandra's Java roots is that Java classes used by Cassandra can be extended and Cassandra can be customized via Java. For example, custom data types can be implemented by extending the AbstractType class.

Conclusion

The Cassandra Java Driver makes it easy to access Cassandra from Java applications. Cassandra also features significant Java-based configuration and monitoring and can even be customized with Java.

Monday, May 19, 2014

Hello Cassandra

A colleague recently told me about several benefits of Cassandra and I decided to try it out. Apache Cassandra is described in A Quick Introduction to Apache Cassandra as "one of today’s most popular NoSQL-databases." The main page for Apache Cassandra states that the "Apache Cassandra database is the right choice when you need scalability and high availability without compromising performance." Cassandra is being used by companies such as eBay, Netflix, Adobe, Reddit, Instagram, and Twitter. This post is a summary of steps for getting started with Cassandra.

Apache Cassandra can be downloaded from the main Apache Cassandra web page. The Download page states that "the latest stable release of Apache Cassandra is 2.0.7 (released on 2014-04-18)" and this is the version I will discuss and use in this post.

For this post, I downloaded and installed the DataStax Community Edition from Planet Cassandra Downloads. The DataStax Community 2.0.7 edition includes "The Most Stable and Recommended Version of Apache Cassandra for Production (2.0.7)." There are DataStax Community Edition downloads available for Mac OS X, Microsoft Windows, and several flavors of Linux.

The next screen snapshot shows the directory listing for the "bin" directory of the Apache Cassandra included with the DataStax Community Edition installation.

From that "bin" directory, the Cassandra server can be started simply by running the appropriate executable. In the case of this single Windows machine, that command is cassandra.bat and this step is illustrated in the next screen snapshot.

The interactive command-line tool cqlsh is also located in the Apache Cassandra "bin" subdirectory. This tool is similar to SQL*Plus for Oracle databases, mysql for MySQL databases, and psql for PostgreSQL. It allows one to enter various CQL (Cassandra Query Language) statements such as inserting new data and querying data. Starting cqlsh from the command line on a Windows machine is shown in the next screen snapshot.

There are several useful observations that can be made from the previous image. As the output of from starting cqlsh shows, this version of Apache Cassandra is 2.0.7, this version of cqlsh is 4.1.1, and the relevant CQL specification is 3.1.1. The immediately previous screen snapshot also demonstrates help provided by running the "HELP" command. We can see that there are several "documented shell commands" as well as even more "CQL help topics."

The previous screen snapshot demonstrated that the "help" command in cqlsh lists individual topics on which the help command can be specifically run. For example, the next screen snapshot demonstrates the output from running "help types" in cqlsh.

In this screen snapshot, we see CQL data types that are supported in cqlsh such as ascii, text/varchar, decimal, int, double, timestamp, list, set, and map.

Keyspaces in Cassandra

Keyspaces are significant in Cassandra. Although this post covers Cassandra 2.0, the Cassandra 1.0 documentation nicely explains keyspaces in Cassandra: "In Cassandra, the keyspace is the container for your application data, similar to a schema in a relational database. Keyspaces are used to group column families together. Typically, a cluster has one keyspace per application." This documentation goes on to explain that keyspaces are typically used to group column families by replication strategy. The next screenshot demonstrates creation of a keyspace in cqlsh and listing the available keyspaces.

The last screen snapshot included an example of using the command SELECT * FROM system.schema_keyspaces; to see the available keyspaces. When one just wants a list of the names of the available keyspaces without all of the other details, it is easy to use desc keyspaces as shown in the next screens snapshot.

Creating a Column Family ("Table")

With a keyspace created, a column family (or table) can be created. The next screen snapshot demonstrates using the newly created movies_keyspace with the use movies_keyspace; statement and then shows using the cqlsh command SOURCE (similar to using @ in SQL*Plus) to run an external file to create a table (column family). The screen snapshot demonstrates listing available tables with the desc tables command and listing specific details of a given table (MOVIES in this case) with the desc table movies command.

The above screen snapshot demonstrated running an external file called createMovie.cql using the SOURCE command. The code listing for the createMovie.cql file is shown next.

CREATE TABLE movies
(
   title varchar,
   year int,
   description varchar,
   PRIMARY KEY (title, year)
);
Inserting Data into and Querying from the Column Family

The next screen snapshot demonstrates how to insert data into the newly created column family/table [insert into movies_keyspace.movies (title, year, description) values ('Raiders of the Lost Ark', 1981, 'First of Indiana Jones movies.');]. The image also shows how to query the column family/table to see its contents [select * from movies].

Cassandra is NOT a Relational Database

Looking at the Cassandra Query Language (CQL) statements just shown might lead someone to believe that Cassandra is a relational database. However, CQL is a relational-like feature added to Cassandra 2.0 intended to help people with SQL expertise more readily adopt Cassandra. Similarly, triggers are being added in 2.0/2.1. Despite the presence of these Cassandra features intended to make it easier for relational database users to adopt Cassandra, there are significant differences between Cassandra and a relational database.

The Cassandra Data Model is a page in the Apache Cassandra 1.0 Documentation that describes some key differences between Cassandra and relational databases. These include:

  • "Cassandra does not enforce relationships between column families the way that relational databases do between tables"
    • There are no foreign keys in Cassandra and there is no "joining" in Cassandra.
    • Denormalization is not a shameful thing in Cassandra and is actually welcomed to a certain degree.
  • Cassandra "table" (column family) modeling should be done based on expected queries to be used.
Conclusion

I've just begun to get my feet wet with Cassandra but look forward to learning more about it. This post has focused on some basics of acquiring and starting to use Cassandra. There is much to learn about Cassandra and some "deeper" topics that really need to be understood to truly appreciate Cassandra include Cassandra architecture (and here), Cassandra Data Modeling (and here), and Cassandra's strengths and weaknesses.

Thursday, May 8, 2014

Video Review: Building an Application with CoffeeScript

Darko Bozhinovski's video course Building an Application with CoffeeScript was published last month by Packt Publishing. In this post, I review this video course on CoffeeScript (described on its main web page as "a little language that compiles into JavaScript" that is "an attempt to expose the good parts of JavaScript in a simple way").

Building an Application with CoffeeScript runs in the same web browser-based Packt Video Player used by other video courses from Packt Publishing that I've previously reviewed: HTML5 Game Development, jQuery UI Development, and JBoss EAP Configuration, Deployment, and Administration. The player runs completely in a web browser and features short video segments (ranging from 1 minute to 9 minutes each) divided into eight sections (chapters) with between 2 and 3 videos per section.

Section 1: CoffeeScript 101

The first section of Building an Application with CoffeeScript includes three videos and the initial video is the longest of the entire video course with a duration of almost 9 minutes. This initial video's summary includes three bullets and provides a link to additional references for more details. The video introduces CoffeeScript via the CoffeeScript site. In describing how CoffeeScript allows the best parts of JavaScript to be used, the video author also references Douglas Crockford's JavaScript site. Much of this first video uses examples on the CoffeeScript site to compare and contrast CoffeeScript with JavaScript. The site shows CoffeeScript and equivalent JavaScript code side-by-side and the video author shows these same CoffeeScript-to-JavaScript comparisons in the web-based JavaScript-to-CoffeeScript compiler js2coffee. As he narrates, he shows how subtle changes to the CoffeeScript or the JavaScript impact the other language in the js2coffee tool. One slightly distracting issue with the first video is the presence of "Topic 3" text at the end of a bullet on the first slide; I suspect this was template text that should have been removed when the bullet was added.

The second video demonstrates how to download and install the CoffeeScript compiler via download of Node.js. The video demonstrates using the command-line compiler to compile a "Hello, World" example written in CoffeeScript to JavaScript and then shows that JavaScript rendered in a web browser.

Section 1's third video introduces cake, described in the CoffeeScript site as, "a (very) simple build system similar to Make and Rake." Bozhinovski demonstrates writing a Cake task that compiles all CoffeeScript files in a given directory to their CoffeeScript equivalents and then demonstrates running that Cake task.

Section 2: Head-first Application Development

Section 2 features three video snippets that cover concepts such as object-oriented programming, inheritance, classes, and MVC. The first video of Section 2 is the one that really started to pique my interest in CoffeeScript. Although I liked some of the conciseness that CoffeeScript offers over JavaScript as shown in earlier video snippets, it was the support for class-based object-oriented programming in CoffeeScript that really caught my attention. The narrator demonstrates using js2coffee that classes in CoffeeScript are functions in JavaScript and one cannot help but notice how much more readable the CoffeeScript classes are than the JavaScript functions. The author also uses this first video of Section 2 to introduce his project with code examples that are used in the course.

The second video snippet of Section 2 focuses on Model-View-Controller and begins this focus with a reference to the Wikipedia page on MVC. Bozhinovski returns to his Github project coffeescript-course again and makes a short detour to advertise benefits of Github and how to start with Github. He then shows that the files in his project are empty and explains that he will populate them as part of the video course. At that point, he creates base model, controller, and view classes.

The third video of Section 2 begins with a focus on class-based inheritance in CoffeeScript. This coverage includes referencing the CoffeeScript site and demonstrating extending the base classes written in the previous video. A significant portion of this video highlights more resources available to viewers interested in CoffeeScript at the CoffeeScript site, via JavaScript frameworks, and at the http://todomvc.com/ site.

Section 3: The Storage Layer – Models and Data Persistence

There are only two video snippets in Section 3, but the section's overall duration is among the highest of the video course. The first video in this section discusses Web/DOM storage and which browser versions support this feature. The author points out advantage of local (web) storage such as its better support among common web browsers as compared to alternatives such as IndexDB and Web SQL Database.

Section 3's first video demonstrates use of localStorage by opening a web brower's console and running JavaScript-based examples using localStorage in that console (brief discussion on how to open this console in different browsers is included). The examples are then shown in js2coffee so that use of localStorage can be seen both directly in JavaScript and in CoffeeScript.

The second video in Section 3 is "the fun part" and begins with a demonstration of writing a class in CoffeeScript that encapsulates persisting and retrieving data values to localStorage. The example highlights the ability to specify static methods on a CoffeeScript class with the @ symbol and demonstrates how these static methods would be called by clients. Section 3's second video also demonstrates completing and persisting the model classes. JSON.parse and JSON.stringify are demonstrated within CoffeeScript as well.

Section 4: Routing and Views

Section 4 is composed of three video snippets. The first video in this section reviews the roles of controller, view, and model and then introduces the concept of routing. The video demonstrates building a routing class for the example application, but the narrator explains the basic theory behind routers and points out third-party routing micro frameworks that are already available for use. The author's examples are relatively simple, associating routes with controllers' methods, but the author points out that more elaborate routing is possible.

The second video of Section 4 builds on the section's first video to cover routers and controllers in more detail. The author demonstrates writing new controller methods and demonstrates more concretely the association between controllers and routers.

Section 4's final video is the longest of the section and introduces views. Along the way, this video demonstrates some more CoffeeScript features such as its constructor method, its multi-line string support, and its for-of loop. The example application at this point has HTML tags added to its rendering portion of its view classes and jQuery is used here as well.

Section 5: Interactions and Event Handling – Using JQuery with CoffeeScript

Using jQuery was mentioned very briefly a couple times in earlier sections, but the two-video Section 5 makes the use of jQuery with CoffeeScript a central theme. The first of the section's two videos demonstrates how to prevent a hypertext action in the example application from going to a newly served page and instead be routed via the router built in Section 4. This is key to implementing a single-page application. This video also demonstrates additional CoffeeScript/jQuery binding concepts and demonstrates CoffeeScript's switch/when statement.

Section's final second and final video starts by revisiting the hash change support in modern browsers. The author also mentions the pushState API. Demonstration of writing a global Event Emitter based on Backbone.js's Backbone.Events class is also demonstrated and it is explained that this approach allows for less tight coupling than using direct calls between views and controllers.

Section 6: Extending Our Application – Manipulating Stored Data

There are three video snippets in Section 6 and all three use creation and enhancement of the example applications category and document concepts to illustrate organization of data and of additional CoffeeScript code in practice. These are code-heavy videos that illustrate practical implementation of new features for the example application.

Section 7: Extending Our Application – Add an External Library

The first video of Section 7 introduces the idea of using Summernote in the example application to support rich text editing. The second video demonstrates integrating Summernote with the example application, including saving the rich text.

The second video also introduces jsPDF and the third video of Section 7 demonstrates integrating jsPDF with the example application so that the example application can export PDF from HTML.

Section 8: Publishing and Real-world Usage for Our Documents

The final section has three videos. The first of these three demonstrates using the Blob API to allow the example application to export documents in text and HTML formats. The second video demonstrates how to allow a user of the example application to publish the document to a WordPress blog. The third and final video of this section (and final video of the course) talks about ways that viewers could customize and enhance the example application built during the course. The author outlines other possible applications that could be built from it and talks about other ways to change it.

General Observations
  • The title "Building an Application with CoffeeScript" articulates well what this video course is. Although the video course is often introductory in nature, it is organized around demonstration of building an application using CoffeeScript and incidentally providing introductory information along the way. This is different than being organized as an introduction to CoffeeScript that happens to build an example application along the way. Instead of providing lengthy lists of features and syntax examples (which is what a course focused on introduction over application building might do), this video course provides just enough introductory coverage of required features and syntax to allow the work of building an example application to take place.
  • Numerous online references are shown and discussed in this video course, making it easier for the viewer to identify sources of additional details and background information. These online resources help the narrator to explain the topic and showing them to the viewer allows the viewer to directly access them after being introduced to them. The video course makes it even easier to find these resources by listing the URLs for most of them in the summary area of each section.
  • There are several occurrences in the video course when the author references the associated GitHub project ("coffeescript-course") for additional or deeper details than covered in the video. This allows the video presentation to avoid getting too deep in details while at the same time allowing viewers to learn more details as desired after finishing the video.
  • Viewers of Building an Application with CoffeeScript will be best served if they have basic familiarity with JavaScript. This is because many of the examples teach CoffeeScript via comparison to JavaScript and because basic familiarity with JavaScript allows the viewer to more quickly appreciate what CoffeeScript offers in its place.
  • I liked that several popular JavaScript frameworks were used in the example application built in this video course. Specific examples of frameworks used in the example application include jQuery, BackBone, and Bootstrap-based Summernote.
  • I liked that several features of modern web browsers were used in the example application built in this video course.
Conclusion

Building an Application with CoffeeScript delivers on what its title promises: demonstration and explanation of building a simple application with CoffeeScript. This video is most likely going to appeal most strongly to developers who have basic JavaScript familiarity and want to get a quick overview of what CoffeeScript offers and how it can ease some of the burdens of JavaScript development.

Friday, May 2, 2014

Book Review: Java EE 7 with GlassFish 4 Application Server

David R. Heffelfinger's Java EE 7 with GlassFish 4 Application Server has been published by Packt Publishing. The subtitle of this book is "A practical guide to install and configure the GlassFish 4 application server and develop Java EE 7 applications to be deployed to this server."

The Preface of Java EE 7 with GlassFish 4 Application Server states that JDK 7 (or newer), GlassFish 4.0, and Maven are needed to build and run the examples in this book. The Preface also expects that readers are expected to have "familiarity with the Java language" and that the book is intended for Java developers wanting to learn Java EE or current Java EE developers wanting to learn about the newest specification.

Chapter 1: Getting Started with GlassFish

The first chapter of Java EE 7 with GlassFish 4 Application Server begins by briefly describing GlassFish and by providing a high-level overview of the new features of Java EE 7. The new Java EE 7 specifications covered at this high level are JavaServer Faces (JSF) 2.2, Java Persistence API (JPA) 2.1, Java API for RESTful Web Services (JAX-RS) 2.0, Java Message Service (JMS) 2.0, Java API for JSON Processing (JSON-P) 1.0, and Java API for WebSocket 1.0.

Chapter 1 lists two of the primary advantages of using GlassFish as a Java EE application server: it being the reference implementation and, as such, it providing implementations of the latest and newest Java EE features. There is no mention of what I perceive to be GlassFish 4's biggest disadvantage: Oracle has declined to provide commercial support for GlassFish 4.

The initial chapter demonstrates how to download GlassFish 4 and mentions that it is also available bundled with NetBeans IDE ("Java EE" or "All" bundles) since version 7.4. The chapter shows the basics of installing the downloaded GlassFish and assumes that JDK 1.7 or later (note there have been rumors of GlassFish 4 not working well on JDK 8 yet) has been installed and that the Java application launcher is available from the environment's path.

Starting GlassFish from the command-line using the well-known (to previous users of GlassFish) asadmin start-domain command is demonstrated in Chapter 1. The chapter shows bringing up a web browser with the URL http://localhost:8080 to verify that GlassFish is running and then demonstrates using the web-based administrative console at URL http://localhost:4848 to deploy a WAR (simpleapp.war) provided on the book's Packt Publishing site. This chapter also demonstrates using the web-based Administrative Console to undeploy the web application as well before demonstrating two ways to deploy the WAR from the command line (by copying the WAR into the autodeploy directory and by using the asadmin deploy command).

Chapter 1 introduces GlassFish domains as a concept and then explains how to work with them using appropriate asadmin domain commands create-domain, delete-domain, and stop-domain.

This meaty first chapter concludes with a demonstration of how to configure GlassFish to use a JDBC driver for working with a relational database. The example specifically demonstrates configuration of a MySQL database driver and datasource, but the author points out that the examples in the rest of the book that work with relational databases use the Apache Derby-based JavaDB that comes bundled with GlassFish.

Nothing in this first chapter on downloading, installing, deploying to, and configuring a data source for GlassFish seems different to me from previous versions of GlassFish. I believe that experienced GlassFish users who are reading Java EE 7 with GlassFish 4 Application Server to learn the new Java EE 7 features and new GlassFish 4 features could skip most of the introductory chapter with the exception of the section providing concisely worded high-level overviews of the new Java EE 7 features. For readers entirely new to GlassFish, this chapter provides a nice starting point for everything you need to do to get GlassFish up and running for use with examples later in the book.

Chapter 2: JavaServer Faces

The second chapter of Java EE 7 with GlassFish 4 Application Server focuses on JavaServer Faces (JSF), which it describes as "the standard component framework of the Java EE platform." This chapter's coverage includes discussion of Facelets as now (as of Java EE 6/JSF 2.0) JSF's "preferred view technology." The chapter describes how adhering to JSF's expected conventions can lead to minimal required configuration.

Chapter 2 continues its JSF coverage with an example XHTML-based Facelet that is described in detailed text. Along the way, the author explains how to use JSF 2.0 project stages and explains how to specify a project stage to GlassFish as a JNDI resource.

JSF's "built-in input validation capabilities" are covered next. A table of standard JSF validators is provided and there is minor discussion on using Bean Validation with JSF. The chapter also includes discussion on creation of custom validators. The example illustrating custom validators uses Apache Commons Validator. When the chapter includes an example of implementing custom validation methods on Named Beans, it makes use of Apache Commons StringUtils.

After Chapter 2 covers customization of message styles and text, it moves onto a section called "Ajax-enabling JSF applications." This section points out that "JSF 2.0 standardized Ajax support by introducing the <f:ajax> tag" and then provides an example of using that new tag. There is thorough coverage of the Ajax tag, how it works, and what its other options are.

The parts of JSF 2.2 that interest me most and which I looked forward most to reading about in this book are JSF 2.2's HTML5 support and JSF 2.2's Faces Flows. Both subjects are covered well in this chapter with examples and descriptions of those examples.

Chapter 3: Object Relational Mapping with JPA

Chapter 3 is dedicated to Java Persistence API and most of the chapter covers basics of JPA that have been in place well before Java EE 7. The chapter describes JPA as "the standard Java EE Object Relational Mapping (ORM) tool" and provides examples and discussion on using JPA with one-to-one relationships, one-to-many relationships, many-to-many relationships, and composite primary keys. The chapter also introduces Java Persistence Query Language (JPQL).

The third chapter discusses how the Criteria API limitations of JPQL. It also introduces JPA 2.1 (Java EE 7) enhancements to the Criteria API that allow "for updating database data via the CriteriaUpdate interface" because Criteria API could only be used for reading data previously.

Chapter 4: Enterprise JavaBeans

The fourth chapter's focus is Enterprise JavaBeans (EJB), which are introduced as "server side components that encapsulate business logic of an application" and "simplify application development by automatically managing transaction management and security." Two types of EJBs (session beans and message-driven beans) are discussed. Although not necessary anymore, it was interesting (or a walk down memory lane) to read the historical information about how session and entity beans have changed since the days of J2EE.

The examples and discussions regarding Session Enterprise JavaBeans include invocation of these deployed beans from a standalone client using appclient and from a web client using JSF and CDI. The examples also involve JPA, making them very inclusive of the significant Java EE specifications.

This fourth chapter covers several other EJB topics include security, the Timer Service, transactions, and the EJB lifecycle. None of these concepts are new to Java EE 7, but EJBs are of course a significant part of many Java EE applications.

Chapter 5: Contexts and Dependency Injection

Contexts and Dependency Injection (CDI), introduced with Java EE 6, is the subject of Chapter 5. The coverage includes named beans, dependency injection, CDI Qualifiers, and CDI named bean scopes (with particular emphasis on conversation scope).

Chapter 6: JSON Processing with JSON-P

Chapter 6 of Java EE 7 with GlassFish 4 Application Server is about Java API for JSON Processing (JSON-P, JSR 353), a specification new to Java EE 7. The chapter begins by introducing JavaScript Object Notation (JSON) as "a human-readable data interchange format ... derived from JavaScript."

The sixth chapter states that "JSON-P includes two APIs for processing JSON - the Model API and the Streaming API" and covers generating JSON and parsing JSON with each of these two APIs. The examples include code and text descriptions as well as brief descriptions of the advantages and disadvantages of JSON Model API versus JSON Streaming API.

Chapter 7: WebSockets

Like Chapter 6, Chapter 7 covers a specification and feature new to Java EE 7 with its coverage of Java API for WebSocket (JSR 356). The chapter covers development of WebSocket endpoints, development of JavaScript-based WebSocket clients, and development of Java-based WebSocket clients. Significant details regarding JSON-P are covered in this chapter and the author refers the read to the Tyrus User Guide for additional details (Tyrus is the "open source JSR 356 reference implementation").

Chapter 8: The Java Message Service

Chapter 8 of Java EE 7 with GlassFish 4 Application Server continues the streak of chapters covering new Java EE 7 specifications by covering Java Message Service (JMS) 2.0.

This is one of the chapters of Java EE 7 with GlassFish 4 Application Server that includes GlassFish-specific coverage within the topic of a general Java EE 7 specification. In this case, the chapter indicates how to configure GlassFish to use JMS by setting up "a JMS Connection Factory, a message queue, and a message topic." Like Chapter 4 on EJBs, this chapter on JMS also demonstrates using the GlassFish-specific applclient.

Chapter 8 coverage of JMS includes sending and receiving messages to/from queues and topics. It also includes an examples of browsing message queues and creating durable subscribers.

Chapter 9: Securing Java EE Applications

The ninth chapter of Java EE 7 with GlassFish 4 Application Server is on securing Java EE applications with Java Authentication and Authorization Service (JAAS) API and GlassFish. The chapter describes using security realms and covers both preconfigured realms (file, admin-realm, and certificate) and "defining additional realms" (with examples including an LDAP realm, a JDBC realm, and custom realms).

Chapter 10: Web Services with JAX-WS

The final two chapters of Java EE 7 with GlassFish 4 Application Server are on using web services with Java EE and Chapter 10 specifically covers working with SOAP-based web services using Java API for XML Web Services (JAX-WS). Chapter 10 defines web services as "application programming interfaces that can be invoked remotely" and that "can be invoked from clients written in any programming language."

Chapter 10 describes using JAX-WS to develop web services, to develop clients of web services, to add attachments to web services calls, to expose EJBs as web services, and to secure web services. The chapter looks at WSDLs and generating Java from WSDLs using GlassFish's wsimport.

Chapter 11: Developing RESTful Web Services with JAX-RS

The final chapter of Java EE 7 with GlassFish 4 Application Server covers REST-based web services support in Java EE as provided by Java API for RESTful Web Services (JAX-RS). Although this was originally added to enterprise Java with Java EE 6, Java EE 7 introduces JAX-RS 2.0.

Chapter 11 introduces REST and covers basic support for REST-based web services that was added with Java EE 6. This discussion covers basic JAX-RS annotations, using GlassFish logs to analyze working functionality, using curl as a client, and using JAXB for Java/XML binding. The chapter then moves onto discussion of Java EE 7's introduction of "a standard client-side API that we can use to easily develop RESTful web service clients." The chapter concludes with a discussion on query parameters and path parameters (@QueryParam and @PathParam).

Other Observations
  • Java EE 7 with GlassFish 4 Application Server liberally uses full color (in the PDF version I reviewed) screen snapshots that have sufficient resolution to be easy on the eyes and to nicely illustrate the concepts. This was particularly the case in the first chapter on installing and configuring GlassFish 4 and in other chapters dealing with the GlassFish web admin console.
  • I like that Java EE 7 with GlassFish 4 Application Server includes code examples that not only illustrate the points being made, but also include common and useful third-party libraries.
  • Heffelfinger has written other Packt Publishing books on J2EE/Java EE topics and portions of those books are the same across the books. For example, portions of Java EE 7 with GlassFish 4 Application Server are also available in Enterprise JavaBeans, Java EE 5 Development using GlassFish Application Server, and Java EE 6 with GlassFish 3 Application Server. Indeed, Java EE 7 with GlassFish 4 Application Server can be viewed as the third edition of the latter two of those books (it says as much by stating that it was "first published" in October 2007, had a "Second Edition" in July 2010, and the "Third Edition" in March 2014). Much of the Java EE and GlassFish content is the same with this edition adding in Java EE 7 new features and GlassFish 4 coverage. As a third edition, this book is as polished as one expects third editions to be.
  • Although Java EE 7 with GlassFish 4 Application Server explicitly covers GlassFish 4, there is not much that I can see in Java EE 7 with GlassFish 4 Application Server that is unique to GlassFish 4 other than its support for the newly added Java EE 7 specifications. The book is really more focused on Java EE in general and Java EE 7 in particular with GlassFish as the Java EE implementation used to demonstrate the examples. This is a great book for someone wanting to learn new Java EE 7 features and for someone wanting to learn how to use basic GlassFish features in Java EE development. The majority of GlassFish 4's new features are implementations of the new Java EE 7 specifications, so it's not surprising that the differences in this edition are more about Java EE 7 than about GlassFish 4.
  • Java EE 7 with GlassFish 4 Application Server's coverage of Java EE 7 covers it cumulatively rather than covering only features new to Java EE with Java EE 7.
Conclusion

Java EE 7 with GlassFish 4 Application Server provides a polished presentation of Java EE as it stands today with its recently included Java EE 7 specifications. GlassFish 4 is the application server used to demonstrate these Java EE concepts.