Tuesday, December 13, 2011

Sneaking a Peek at Guava Release 11

The recent reddit/java thread If you still don't know why Guava is awesome .... references the Guava Explained Wiki page. As I was looking at this, I noticed the page focused on Guava Math Explained. I have blogged several times regarding Guava features, but I was not aware of the referenced math-related classes. That's when I realized that these refer to Guava Release 11. At that point, it seemed interesting to snoop out other enhancements we might expect from the next release of Guava. I briefly cover some of the clues already available as to the enhancements coming with Guava Release 11, but caveat this discussion with the obvious disclaimers that things are subject to change before its final release and that I have no inside knowledge of Guava's inner workings.

The previously referenced Guava Explained Wiki page is only one of several of Guava's Wiki pages that have been updated by wasserman.louis in the past 36 hours (from this post's publication).

Most of the updated Guava Wiki pages appear to be updated to associate the "Explained" label with the entry and tie it in to the "Guava Explained" wiki page. However, the Guava Math Explained Wiki page is definitely new.

The classes in the Guava Math utilities appear to belong to the com.google.common.math package with is an all-new package containing four classes: BigIntegerMath, DoubleMath, IntMath, and LongMath. The class-level Javadoc description for each of these four Guava math classes tell us that each class has "implementations of many methods" which "are based on material from Henry S. Warren, Jr.'s Hacker's Delight, (Addison Wesley, 2002)." As is the case with many of Guava's other classes, these classes supplement the methods provided by Java SDK's Math and other mathematical classes.

Although the main Guava Libraries page currently points to Guava Release 10 Javadoc as its "API docs for the most recent release," the "pre-release API docs in git" currently points to documentation that references Guava Release 11. For example, while com.google.common.math is not available in the standard Guava API documentation (Release 10), the package is documented in the pre-release API documentation (Release 11). The newer, "pre-release" API documentation gives us some of our best clues regarding likely future Guava features.

In the blog post Groovy Script for Comparing Javadoc Versions, I used a Groovy script to compare versions of Java by comparing the constructs they added or removed in each new version. I made some adaptations to that script to compare arbitrary listing of Strings and have applied it to compare the "most recent release" (10) of Guava to the "pre-release" (11). Here is the modified script for comparing the two.

diffVersionsJavadocs.groovy
#!/usr/bin/env groovy
// diffVersionsJavadocs.groovy
//
// Examples using Guava:
//
// Guava Release 10:
//    http://docs.guava-libraries.googlecode.com/git-history/v10.0.1/javadoc/allclasses-noframe.html
// Guava Release 11:
//    http://docs.guava-libraries.googlecode.com/git/javadoc/allclasses-noframe.html

if (args.length < 4)
{
   println "\nUSAGE: diffVersionsJavadocs first_label first_url second_label second_url"
   println "\n\twhere first_label is name of first version"
   println "\t      first_url is URL of Javadoc for first version (usually allclasses)"
   println "\t      second_label is name of second version"
   println "\t      second_url is URL of Javadoc for second version (usually allclasses)"
   System.exit(-1)
}
@Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='0.9.7')

def firstXml = new XmlParser(new org.ccil.cowan.tagsoup.Parser()).parse(args[1])
def firstUrls = firstXml.'**'.a.@href
def firstLabel = args[0]

def secondXml = new XmlParser(new org.ccil.cowan.tagsoup.Parser()).parse(args[3])
def secondUrls = secondXml.'**'.a.@href
def secondLabel = args[2]

compareSetsOfStrings(secondUrls, secondLabel, firstUrls, firstLabel)

/**
 * Compare first Collection of Strings to second Collection of Strings by
 * identifying which Strings are in each Collection that are not in the other.
 *
 * @param firstStrings First Collection of Strings to be compared.
 * @param firstLabel Name of first collection of Strings.
 * @param secondStrings Second Collection of Strings to be compared.
 * @param secondLabel Name of second collection of Strings.
 */
def void compareSetsOfStrings(
   Collection<String> firstStrings, String firstLabel,
   Collection<String> secondStrings, String secondLabel)
{
   println "Constructs in ${firstLabel} But Not in ${secondLabel}"
   def firstButNotSecond = firstStrings - secondStrings
   printIndentedStrings(firstButNotSecond)

   println "Constructs in ${secondLabel} But Not in ${firstLabel}"
   def secondButNotFirst = secondStrings - firstStrings
   printIndentedStrings(secondButNotFirst)
}


/**
 * Print the provided Strings one per line indented; prints "None" if the
 * provided List of Strings is empty or null.
 *
 * @param strings The Strings to be printed
 */
def void printIndentedStrings(Collection<String> strings)
{
   if (!strings?.isEmpty())
   {
      new TreeSet(strings).each
      {
         println "\t${it}"
      }
   }
   else
   {
      println "\tNone"
   }   
}

For convenience, I placed the two URLs I provided to the script for comparing Guava 10 to Guava 11 in the script comments at the beginning of the script. The next screen snapshot shows running the script and its output.

The Groovy script comparing Javadoc for Guava Release 10 to Guava Release 11 indicates that four constructs have been removed from Guava Release 11 that were in Guava Release 9. These are EvictionListeners (class), MapEvictionListener (interface), AbstractListenableFuture (class), and UninterruptibleFuture (interface). All of these had been clearly marked in the Javadoc for deprecation in the Release 10 documentation, including specific statements that they were scheduled to be removed in Release 11 and what should be used instead of them. (I had posted in Effective Javadoc Documentation Illustrated in Familiar Projects that this advertised version from which a deprecated construct would be removed is a particularly effective documentation tool.)

Guava Release 11 introduces several entirely new constructs. These were shown in the screen snapshot above but are listed here in bullet form for convenience.

Constructs in Release 11 But Not in Release 10 (per Javadoc comparison)
  • com/google/common/cache/AbstractLoadingCache.html
  • com/google/common/cache/CacheLoader.InvalidCacheLoadException.html
  • com/google/common/cache/ForwardingLoadingCache.SimpleForwardingLoadingCache.html
  • com/google/common/cache/ForwardingLoadingCache.html
  • com/google/common/cache/LoadingCache.html
  • com/google/common/cache/Weigher.html
  • com/google/common/collect/ImmutableTable.Builder.html
  • com/google/common/collect/ImmutableTable.html
  • com/google/common/collect/Queues.html
  • com/google/common/collect/RangeSet.html
  • com/google/common/collect/SortedMultiset.html
  • com/google/common/escape/ArrayBasedCharEscaper.html
  • com/google/common/escape/ArrayBasedEscaperMap.html
  • com/google/common/escape/ArrayBasedUnicodeEscaper.html
  • com/google/common/escape/CharEscaper.html
  • com/google/common/escape/CharEscaperBuilder.html
  • com/google/common/escape/Escaper.html
  • com/google/common/escape/Escapers.Builder.html
  • com/google/common/escape/Escapers.html
  • com/google/common/escape/SourceCodeEscapers.html
  • com/google/common/escape/UnicodeEscaper.html
  • com/google/common/html/HtmlEscapers.html
  • com/google/common/math/BigIntegerMath.html
  • com/google/common/math/DoubleMath.html
  • com/google/common/math/IntMath.html
  • com/google/common/math/LongMath.html
  • com/google/common/net/HttpHeaders.html
  • com/google/common/net/PercentEscaper.html
  • com/google/common/net/UriEscapers.html
  • com/google/common/primitives/UnsignedInteger.html
  • com/google/common/primitives/UnsignedInts.html
  • com/google/common/primitives/UnsignedLong.html
  • com/google/common/util/concurrent/AbstractScheduledService.CustomScheduler.html
  • com/google/common/util/concurrent/AbstractScheduledService.Scheduler.html
  • com/google/common/util/concurrent/AbstractScheduledService.html
  • com/google/common/util/concurrent/AsyncFunction.html
  • com/google/common/util/concurrent/AtomicDouble.html
  • com/google/common/util/concurrent/AtomicDoubleArray.html
  • com/google/common/util/concurrent/AtomicLongMap.html
  • com/google/common/xml/XmlEscapers.html

Besides the new math classes, other Groovy constructs that I look forward to trying out include the new collection classes, the new concurrency classes, the new unsigned primitive classes, and the escapers (com.google.common.escape package, com.google.common.html.HtmlEscapers class, com.google.common.net.PercentEscaper, com.google.common.net.UriEscapers, and com.google.common.xml.XmlEscapers).

The script executed above only showed entirely new constructs to Guava Release 11, but Guava Release 11 will also be getting new methods on existing objects. For example, the highly useful Guava Strings class appears to be getting two new methods [commonPrefix(CharSequence,CharSequence) and commonSuffix(CharSequence,CharSequence).] and Objects.ToStringHelper appears to be getting numerous new convenience methods.

Being an open source project, Guava's new features may be best "peeked" at by looking at the source code itself. Guava's Javadoc documentation is generated such that clicking on a construct's name in its Javadoc page will display that construct's source code. In some cases, this may be quicker than downloading the code, though the advantage of downloading source code is obviously the ability to view it in your favorite IDE.