Thursday, October 29, 2009

Internet Archive WayBack Machine: Valuable Technical Reference

Have you ever bookmarked a really good technical resource, but were disappointed when you tried to access that page later and it was gone? Have you ever seen what looks like the perfect linked resource in a blog post, article, or book, but then found the referenced URL to not work? In short term cases such as an intermittent server issue or network problem, Google Cache can be an indispensable tool to see a cached version of the page. When a page has been completely removed for a long time, a web page archiving site is more helpful.

A particularly easy site archive tool to use is Internet Archive's WayBack Machine. This free online tool is very easy to use if you know the URL of the page you care about (which you would if the URL was part of a bookmark or if you clicked on a link to a site that was no longer present). You can enter the URL in the form field at the Wayback Machine page, click on the button saying "Take Me Back."



After doing the above, you see a detailed history of changes to the page at that location. This is demonstrated in the following screen snapshot.



The above screen snapshot demonstrates use of Internet Archive Wayback Machine to see a history of my page on Common Struts Errors and Their Causes that was originally posted on GeoCities, but is no longer available due to the demise of GeoCities.

Even though the page is no longer available at the GeoCities URL, its archived versions can still be viewed via the Internet Archive WayBack Machine. The following two images show what happens when one tries to access the page at its former GeoCities address and then what happens when using one of the Internet Archive WayBack Machine's archived versions.





As the screen snapshots above indicate, the page that is no longer available on GeoCities is still available via Internet Archive WayBack Machine. In my case, I have hosted this page at Google Sites and there are many other mirrored copies of it on the web, but the Internet Archive can be useful for finding pages that don't get copied or hosted on alternative sites. Because Internet Archive WayBack Machine also provides various versions of the same page, a history of a particular page can be seen.

The recent loss of GeoCities-hosted pages only one of many examples of original content being removed from the web. A relatively recent well-known example of loss of original content was the sudden and somewhat surprising online disappearance of why the lucky stiff. The next two screen snapshots show a page from the popular Why's (poignant) Guide to Ruby. The first snapshot indicates that the original page is no longer available at its original URL (http://www.poignantguide.net/ruby/chapter-1.html), but the second snapshot indicates that it is archived and accessible with WayBack Machine (at http://web.archive.org/web/20080526095452/www.poignantguide.net/ruby/chapter-1.html).





So far, I've only discussed the simple search implemented by providing the URL and clicking on the "Take Me Back" button. There are many advanced search options as well. If you have an e-mail or bookmark with a URL that no longer works, you'll often have a date on the e-mail or a date on the bookmark property of when it was created. You can use that date with WayBack Machine to find the page as of that date. This is especially useful for an easy way to recollect history.

What was big in the world of Java in late 2004? To find this out, I could look at archives for some major players in the Java world. For example, the java.sun.com page on the last day of 2004 looked like that shown in the next screen snapshot:



We can see from the above screen snapshot (I had entered http://web.archive.org/web/20041231/java.sun.com/ with a day but no time, but it resolved to http://web.archive.org/web/20041231092116/java.sun.com/ with a day and appropriate time) that big topics at the end of 2004 included early access to binaries and source of Java SE 6 (then still called as J2SE 6 or Mustang) and NetBeans 4.0.

As a final example, I'll look at something from the very early days of Java. The URL http://web.archive.org/web/19970211220056/www.sun.com/sunworldonline/swol-10-1995/swol-10-javadigest.html provides an interesting article from SunWorld Online called Java users reveal their habit. This makes for very interesting historical perspective for those of us in the Java community. For those of us who have been around since the public inception of Java, it is a reminder that applets were once the "big thing" in the Java world. For those who are not familiar with the early days of Java, it can provide an interesting perspective on how far things have come (and how much some things are still the same).

Assuming that the deal for Oracle to acquire Sun Microsystems goes through, there is some question about what will happen to the wealth of Java resources available online at domains such as http://java.sun.com/ (such as the JDK 6 Documentation). These articles and other documents will almost assuredly continue to exist (even if at a different URL that includes "oracle" in its name), but it is still comforting to know that the archived versions should also be available via the WayBack Machine.

There are many valuable benefits to having old web pages still available after their deletion and having the ability to see older versions of a particular web page. When one runs into the all-too-common frustration of finding a bookmark or link that is no longer valid, the Internet Archive WayBack Machine is a very welcome tool. However, such power can also be abused. Some articles that talk about people who are not too happy with the power of the WayBack Machine include Internet Archive Sued Over WayBack Machine and Internet Archive Settles Suit Against WayBack Machine.

As an interesting side note, there is a Java-based, open source implementation of the WayBack Machine called wayback.


Conclusion

There is no question that the ability to link documents via hyperlinks is one of the main reasons for the success of HTTP and the World Wide Web. It is very convenient to click on links in bookmarks, e-mail messages, articles, blogs, and even type in URLs from books and go directly to the referenced site. On the other hand, one of the greatest disappointments when using the web is when a hyperlink is no longer valid. Although a search engine might be able to tell you a page's new location (or the location of a mirror or copy), or Google Cache might be used to see a cached version of a page that is temporarily down, a tool like the Internet Archive WayBack Machine is sometimes what is needed to see a page that is no longer otherwise available. In cases where the page still exists, but information that was previously available has been removed, WayBack Machine's ability to see historical versions of that particular page is very useful. In many ways, using WayBack machine definitely feels like time travel.

Wednesday, October 28, 2009

Reocities: GeoCities Rising from the Ashes

I previously wrote about the potential loss of historical technical details as a result of the demise of Yahoo! GeoCities. I listed several useful technical pages hosted on GeoCities that might be lost. Others have also pointed out that GeoCities provided a perspective of the early days of personal web pages with profound value for those interested in studying the history of the web.

I read with interest Jennifer Van Grove's post One Man's Quest to Bring GeoCities Back from the Dead. The endeavor she highlights, instantiated as the ReoCities site, is interesting enough because of the salvaged data of potentially significant value. Perhaps even more interesting, though, is the technical challenge associated with this and the approach being used. More details on this can be found in The Making Of, a story of stress and scripting.

According to the Wikipedia entry for GeoCities, other efforts to archive potentially valuable data hosted on GeoCities include Internet Archive and InternetArchaeology.

Monday, October 26, 2009

Maintaining a Software Development Library (Books)

For as long as I can remember, I have always loved books. When I was growing up and my parents would offer to buy my brothers and me something at the store, I'd almost always select some fictional book while my brothers would select toys. As an adult, I don't read as much fiction as I'd like, but I do buy and read (at least portions) of a lot of technical books. I've got technical books strewn around the house in several different book cases in several different rooms. My wife asks me to take more of them to work, but I have my two long book shelves at work filled as well. In this blog post, I look at why I value these books (versus the information freely available on the web), how I get many of them for really low prices, and how I finally determine when a book has gone beyond usefulness to uselessness and often even to being a hindrance.


Why Books?

With the prevalence of blogs and online articles, why do we even need technical books? I have found that blogs and articles can be superior to books in terms of cutting-edge knowledge and in terms of strange corner cases. However, books are typically better at providing "big picture" introduction to a topic and at providing in-depth thorough coverage of a topic. Books can also be taken just about anywhere, though e-books are becoming more portable with devices such as the Amazon Kindle. I still prefer the ability to write notes in my book and I find that my memory of a certain concept or description seems to be better with physical associations I make mentally. Books often provide more consistent and thorough coverage of a topic than can be covered in a collection of blog posts and articles, even when written by the same individual or team.


Acquiring the Technical Book

I have purchased some real stinkers when I have not adequately researched what I was purchasing. Fortunately, I have gotten better at picking better technical books. There are several factors that aid in this process. Reviews on sites like Amazon.com can be insightful, especially when reviewers express why they like or dislike a particular book. There are also many bloggers who post reviews of technical books. Furthermore, many users groups also provide book reviews. Asking fellow developers and colleagues about the books they own and/or have read can also be enlightening. It is best to consider a wide set of reviews rather than a single review when trying to determine whether to purchase a particular book.

I have sometimes made a decision to purchase a book after borrowing it from a colleague or from the library. This was the case with the Second Edition of Effective Java. I was "on the fence" about purchasing the Second Edition (until it fell in price on the Amazon Marketplace at least) until I borrowed a colleague's Second Edition and realized how much was added in that edition. I have also found several highly useful books and some not-so-useful books after borrowing them from the library and evaluating them. In a few cases, I have gotten the tip or piece of knowledge I needed from a particular book during the period I had it borrowed from the library and did not need to purchase it after borrowing it.

Many publishers offer sample chapters that allow one to preview a portion of a technical book and this can provide insight to the author's writing style and level of detail. Entire older editions of some books are available online. For example, Bruce Eckel makes old editions of some of his books available online. O'Reilly has its Open Books Project with online editions of books that can be reviewed (and sometimes this is the only way to easily access out of print books). If you like what you read there, you can purchase the latest edition to get up-to-date information.

Speaking of older editions, there can be times when acquiring an older edition of a particular book is satisfactory. An older edition can be much less expensive than the latest edition. Traditional and online bookstores will deeply discount the older editions before the new editions come out. Depending on how important the information in the new edition is, considering an older edition can be a useful approach.

When I purchase a technical book, I often first consider Amazon Marketplace. The Amazon Marketplace has the advantage of being hosted directly on Amazon.com and allowing the purchase to be made via Amazon using one's Amazon account. This implies no need for a special account and means that Amazon handles the financial transaction. I am more comfortable trusting my credit card information with a single vendor (Amazon) than with each individual third-party vendor that sells on Amazon Marketplace. My experience is that the new or used books purchased through Amazon Marketplace often arrive quickly and in outstanding shape.

There are a couple things to be aware of when using Amazon Marketplace. For one, shipping and handling is added to the price and typically purchasing $25 worth of merchandise does not mean free shipping when purchasing through the Marketplace. There are times when the fulfillment is through Amazon on a Marketplace purchase and in some of those cases the purchase can use the free shipping with $25 purchase option or Amazon's other prime shipping deals. There are times, especially for newer and more popular technical books, when it costs almost as much or even more to purchase the Marketplace book and pay the shipping (often $3.99 per book) as it costs to buy the book new directly from Amazon with free shipping.

A second consideration with purchasing books on Amazon Marketplace is that the third-party vendor typically arranges the actual administration of the order fulfillment. This can mean a delay in delivery, though it varies widely from very quick vendors to very slow vendors. If you need the book in the next several days, you might want to consider another option.


Using the Technical Book

Although I love books in general and technical books in particular, I rarely read technical books cover to cover. I have only read portions of most of my technical books. In some cases, I have read the entire book several times, but never cover-to-cover. I have read a few technical books cover-to-cover, but that is the exception rather than the norm.

I like to read portions of many of these books during small amounts of available free time. This can include waiting for a car to be serviced, waiting at a doctor's office, waiting for a train on railroad tracks, etc. I almost always have a book with me in the car for such situations. I also read portions of books directly related to whatever I'm working on at the time.

A technical book is often used as a reference and, in such cases, a good index is highly valuable. I have found that a really good index can turn a mediocre book into a trusted resource. Even the best indexes often lack every term I find myself frequently looking up in the book. Because of this, I have gotten in the habit of adding my own index entries in my most-used books for terms and pages that I expect I may want to look up again in the future.

Besides writing in my own index entries, I also often write notes in my books referencing other sections of the book that are related. I like to record any substantive changes on relevant pages in the book to help address obsolescence that is unavoidable with technical books. For example, the Spring Framework Reference is almost always going to be more current than a printed book can ever hope to be. Therefore, my favorite Spring book has many notes in it adding new or changed features in the Spring Framework that I have found out about via blogs, articles, or reading the Spring reference.


Saying Goodbye

Because I enjoy books so much, it can be difficult to part with one, even when it has lost its usefulness. For one thing, there is always the possibility that I might need it again. It can be difficult to admit that I probably won't. Another hindrance to getting rid of a particular book occurs when it is outdated, but I hesitate to invest in a newer edition or improved version. There are also logistical issues such as how to determine when a book has lost its usefulness and deciding on the best way to get rid of it (paper recycling, book use recycling, trash, etc.).

When a book gets so old that it actually contains information that is no longer accurate, it can be risky to use. This is because it can teach incorrect principles that have to be unlearned and can waste a lot of time trying to figure out why something doesn't work as described in the book. In a worst-case scenario, one might even be dissuaded from using a particular technology because of frustrations that are a direct result of using an obsolete and/or incorrect book.

Some books are easier to get rid of because the covered technologies are obviously obsolete. For example, I shouldn't have much trouble getting rid of my book on J# because it is extremely unlikely at this point that I'll ever need that book. Even better examples are books on specific versions of products or implementations that are no longer available or are no longer regularly used.

With some still-popular languages and frameworks it can be more difficult to determine when a book on the subject has passed its useful life. For example, it is my opinion (assuming one is developing in JDK 1.4, J2SE 5, or Java SE 6) that any book on Java that was written before JDK 1.1 is not worth reading or using. Although a book on JDK 1.2 or JDK 1.3 might be a little better, I really don't think most Java books focused on a version of Java prior to JDK 1.4.2 are worth keeping (or at least regularly referencing). JDK 1.4 was a "game changer" in the world of Java development and it is my opinion that any Java book with real usefulness must address at least that version. Similarly, any Flex book covering Flex 2 or Flex 3 might be fine, but any book addressing Flex before Flex 2 (Flex 1.0 or Flex 1.5) is generally not worth keeping or using.

I typically am too much of a cheapskate to purchase a newer edition of the same book unless the new edition offers enough to justify its purchase. An example of when this has been the case is Effective Java. What makes this example interesting is that even after purchasing the Second Edition, I have retained my First Edition copy. The reason for this is that the First Edition is still largely valid and I like to have it around when I have loaned my Second Edition to someone else or have left it somewhere other than my work desk. The point of this is that even purchasing a newer edition of a particular book may not necessarily mean it is time to get rid of the older edition.

When the time comes to part with a technical book, there are several options. If the book is still relevant (not usually the case for me because I wait until the book is completely useless to anyone to part with it), it can be sold online (such as through the previously mentioned Amazon Marketplace, eBay, or other used book selling venue). A book with some remaining relevance might also be donated to a library, a school, or to fellow developers who are working with the language or technology and don't have a better book (especially if they are using an older version to which the book is more applicable). If a book has become so obsolete that it has no value to anyone, the best remaining option is to have its materials recycled.

There are several good blog posts on getting rid of technical books. These include Don Demsak's Recycling Technical Books, Book Recycling, and How Can I Reuse or Recycle Old Books? (see feedback comments as well), and How Book Recycling Can Help the Environment.


Ideas for Good Technical Books

Looking for ideas for some good technical books to add to your personal library? Here are some lists of others' favorite technical books:
StackOverflow: 'Must Have' Books on Your Bookshelf (2009)
What Is The Single Most Influential Book Every Programmer Should Read? (2008)
Top 100 Best Software Engineering Books, Ever (2008)
The Best Books Every Programmer Should Read (2006)
Coding Horror: Recommended Reading for Developers (2004)
Elliotte Rusty Harold's Ten Must-Have Technical Books (2003)


Conclusion

A technical book can be a valuable resource in improving one's skills. However, most of us want to be careful without our money and (perhaps even more careful) with our time. We want to spend our money and time as efficiently as possible. In this blog post, I have recorded some of the things I have learned to improve the efficiency of money and time I invest in acquiring, using, and finally retiring of technical books.

Firefox 3.6 Requires Java SE 6 Update 10

Java SE 6 Update 10 was a significant release despite its version numbering indicating a minor release. Among other advancements, Java SE 6 Update 10 introduced the Next-Generation Java Plug-in for a better Java applet experience. It has now been announced that Firefox 3.6 (Namoroka) will require this next-generation plug-in. Users can access the web page at http://java.com/en/download/help/testvm.xml to test the version of Java supported on a particular machine. The Firefox 3.6 for Developers page specifies advancements in support for Cascading Style Sheets, HTML, JavaScript, DOM, and XPath.

Sunday, October 25, 2009

RMOUG Training Days 2010 Abstracts: Groovy, REST, and Better UIs

As I noted in my previous post, my two abstracts have been accepted by the Rocky Mountain Oracle Users Group (RMOUG) for presentation at Training Days 2010. I have also learned that Bill Jackson's abstract for "Ten Easy Ways To Build a Better GUI" has been accepted as well. I will include the abstracts for my two presentations and for Bill's presentation later in this post.

I am eager to present these two presentations because they are inspired by the presentations that I had planned to present at Colorado Software Summit 2009. Incidentally, that conference would have started tonight with the annual Sunday evening reception famous for its good food and interesting conversation. It was a great way to casually and comfortably kick off an absolutely terrific conference. I was sad to hear about the end of this conference and don't like thinking about what I am missing this week. It certainly would have been nice to be getting my brain crammed full of software development concepts and ideas this week in beautiful Keystone, Colorado. As I stated, however, the opportunity to present presentations at RMOUG Training Days 2010 similar to what I had planned for CSS 2009 is a positive one.

My two abstracts that were accepted for RMOUG Training Days 2010 are "Applied Groovy: Scripting for Java Development" and "RESTful Java." The abstracts for these two presentations are (may differ slightly from what will appear in the conference materials):


Applied Groovy: Scripting for Java Development

As a dynamic language that runs on the JVM and can be used anywhere the Java programming language is used, Groovy is a great choice for building, testing, and maintaining Java SE and EE applications. This presentation briefly summarizes some basics of Groovy and advantages of using Groovy before moving onto demonstrating how to use Groovy to improve the ability to build and test standard and enterprise Java applications. Although the basics of Groovy will be covered initially in the presentation for those who have not used Groovy previously, most of the syntax and other features of Groovy covered in this presentation will be presented in conjunction with use of Groovy in the building and testing of applications for the Java platform.


RESTful Java

The Java platform provides many types of support for building REST-based web services and REST-compliant clients. This presentation will briefly summarize the main principles of the Representational State Transfer style of web services before covering several of the most popular Java-based approaches for working with REST. The presentation will focus on JSR 311 (“JAX-RS: The Java API for RESTful Web Services”), Jersey (the JSR 311 reference implementation), Restlet, and Enunciate while also covering other useful tools related to REST-oriented development with Java.


Bill Jackson's abstract is called "Ten Easy Ways to Build a Better GUI." His abstract is shown next and, as its name implies, focuses on Graphical User Interfaces (GUIs).


10 Easy Ways to Build a Better GUI

In the world of graphic user interfaces, form nearly always follows function. From Dilbert jokes about GUIs designed by engineers to MySpace’s reputation for ugly pages it’s clear that designing attractive, useful, and well thought-out GUIs is much easier said than done.

However, positive examples in the commercial world such as Apple’s well-earned reputation for stylish products show just how much impact a well designed user interface can have. This presentation will cover 10 basic steps for building more intuitive, attractive, and useful user interfaces. The discussion will include issues such as usability, data presentation, form layout, color selection, icon acquisition, and a host of other issues that will help attendees to understand the basic steps to making programs that users actually like. The benefits of these skills go beyond the aesthetic issues to help raise user productivity and product longevity. The presentation will not require any specific programming knowledge and will apply to desktop applications and web pages alike



My presentations planned for RMOUG Training Days 2010 will be changed to some degree because of the different venue and different audience characteristics. The Groovy presentation is conceptually almost exactly what I planned for Colorado Software Summit except that I was going to speak on JRuby there. The RESTful Java presentation will be 60 minutes at RMOUG Training Days 2010 rather than the 90 minutes it would have been at Colorado Software Summit 2009. Because of the shorter duration, it will necessarily be less detailed at Training Days, but I think that may fit the different audience better anyway. I will focus on basics of REST and then cover at a high level (with some API details) how to apply Java tools and frameworks to build REST-based applications.

Rocky Mountain Oracle Users Group Training Days 2010 will take place February 16-18, 2010, at the Colorado Convention Center in Denver, Colorado.

Saturday, October 24, 2009

Java SourceVersion and Character

The SourceVersion class provides information on Java source versions and can provide some interesting details, including demonstration of terminology covered in the Java Language Specification. In this blog posting, I look briefly at some of the more interesting observations one can make using this class that was introduced with Java SE 6 in conjunction with the Java long-timer class Character.

The SourceVersion class provides several handy static methods for ascertaining details about the source version of the current Java runtime. The methods SourceVersion.latest() and SourceVersion.latestSupported() provide details regarding the latest source versions that can be "modeled" and "fully supported" respectively.

The following code snippet demonstrates these two methods in action.


out.println("Latest source version that can be modeled: ");
out.println("\tSourceVersion.latest(): " + SourceVersion.latest());
out.println("Latest source version fully supported by current execution environment ");
out.println("\tSourceVersion.latestSupported(): " + SourceVersion.latestSupported());


The output from running this code is shown next.



As the code example and corresponding output above indicate, the currently supported modeled version and currently fully supported versions are easily accessible. Although the SourceVersion class was introduced with Java SE 6, it has been built to be support future versions of Java. Not only does the Javadoc documentation state that "additional source version constants will be added to model future releases of the language," but the SourceVersion.values() method also provides all supported version enums. A code example and associated output are shown next to demonstrate this method in action.


out.println("SourceVersion enum Values:");
final SourceVersion[] versions = SourceVersion.values();
for (final SourceVersion version : versions)
{
out.println("\t" + version);
}




The Javadoc documentation tells us the meanings of the various enum values shown in the above output. Each represents a different "source version of the Java programming language" and the platform version it is associated with. As shown earlier, the RELEASE_6 is associated with Java SE 6, RELEASE_5 is associated with J2SE 5, RELEASE_4 is associated with JDK 1.4, RELEASE_3 is associated with JDK 1.3, RELEASE_2 is associated with JDK 1.2, RELEASE_1 is associated with JDK 1.1 and RELEASE_0 is associated with "the original version." The Javadoc documentation for Java SE 7 indicates that SourceVersion.RELEASE_7 is supported in Java SE 7.

The SourceVersion class provides three static methods that each indicate whether a provided CharSequence is an identifier, keyword, or name. The three methods that allow one to dynamically determine if a particular CharSequence fits one or more of the types identifier, name, or keyword are (respectively) SourceVersion.isIdentifier(), SourceVersion.isName(), and SourceVersion.isKeyword().

Using these methods allows one to determine if a particular string is reserved as a keyword, is even considered a valid identifier, and if a string that is a valid identifier is not a keyword and is thus a valid name. The isName() method returns true for a "syntactically valid name" that is not also a keyword or literal. The isKeyword() method indicates if the provided string is one of the keywords listed here.

I have run many different strings of various combinations of these three types in the following code.


public static void printIdentifierTest(final String stringToBeTested)
{
out.println(
"Is '" + stringToBeTested + "' an identifier? "
+ SourceVersion.isIdentifier(stringToBeTested));
}

public static void printKeywordTest(final String stringToBeTested)
{
out.println(
"Is '" + stringToBeTested + "' a keyword? "
+ SourceVersion.isKeyword(stringToBeTested));
}

public static void printNameTest(final String stringToBeTested)
{
out.println(
"Can '" + stringToBeTested + "' be used as a name? "
+ SourceVersion.isName(stringToBeTested));
}

public static void printTests(final String stringToBeTested)
{
out.println("\n=============== " + stringToBeTested + " ===============");
printIdentifierTest(stringToBeTested);
printKeywordTest(stringToBeTested);
printNameTest(stringToBeTested);
}

public static void printTests(
final String stringToBeTested,
final String alternateHeaderString)
{
out.println("\n=============== " + alternateHeaderString + " ===============");
printIdentifierTest(stringToBeTested);
printKeywordTest(stringToBeTested);
printNameTest(stringToBeTested);
}

/**
* Main function for demonstrating SourceVersion enum.
*
* @param arguments Command-line arguments: none expected.
*/
public static void main(final String[] arguments)
{
final String dustinStr = "Dustin";
printTests(dustinStr);
final String dustinLowerStr = "dustin";
printTests(dustinLowerStr);
final String instanceOfStr = "instanceof";
printTests(instanceOfStr);
final String constStr = "const";
printTests(constStr);
final String gotoStr = "goto";
printTests(gotoStr);
final String trueStr = "true";
printTests(trueStr);
final String nullStr = "null";
printTests(nullStr);
final String weirdStr = "/#";
printTests(weirdStr);
final String tabStr = "\t";
printTests(tabStr, "TAB (\\t)");
final String classStr = "class";
printTests(classStr);
final String enumStr = "enum";
printTests(enumStr);
final String assertStr = "assert";
printTests(assertStr);
final String intStr = "int";
printTests(intStr);
final String numeralStartStr = "1abc";
printTests(numeralStartStr);
final String numeralEmbeddedStr = "abc1";
printTests(numeralEmbeddedStr);
final String dollarStartStr = "$dustin";
printTests(dollarStartStr);
final String underscoreStartStr = "_dustin";
printTests(underscoreStartStr);
final String spacesStartStr = " dustin";
printTests(spacesStartStr, " dustin (space in front)");
final String spacesInStr = "to be";
printTests(spacesInStr);
}


When the above code is executed the output shown next is generated.


=============== Dustin ===============
Is 'Dustin' an identifier? true
Is 'Dustin' a keyword? false
Can 'Dustin' be used as a name? true

=============== dustin ===============
Is 'dustin' an identifier? true
Is 'dustin' a keyword? false
Can 'dustin' be used as a name? true

=============== instanceof ===============
Is 'instanceof' an identifier? true
Is 'instanceof' a keyword? true
Can 'instanceof' be used as a name? false

=============== const ===============
Is 'const' an identifier? true
Is 'const' a keyword? true
Can 'const' be used as a name? false

=============== goto ===============
Is 'goto' an identifier? true
Is 'goto' a keyword? true
Can 'goto' be used as a name? false

=============== true ===============
Is 'true' an identifier? true
Is 'true' a keyword? true
Can 'true' be used as a name? false

=============== null ===============
Is 'null' an identifier? true
Is 'null' a keyword? true
Can 'null' be used as a name? false

=============== /# ===============
Is '/#' an identifier? false
Is '/#' a keyword? false
Can '/#' be used as a name? false

=============== TAB (\t) ===============
Is ' ' an identifier? false
Is ' ' a keyword? false
Can ' ' be used as a name? false

=============== class ===============
Is 'class' an identifier? true
Is 'class' a keyword? true
Can 'class' be used as a name? false

=============== enum ===============
Is 'enum' an identifier? true
Is 'enum' a keyword? true
Can 'enum' be used as a name? false

=============== assert ===============
Is 'assert' an identifier? true
Is 'assert' a keyword? true
Can 'assert' be used as a name? false

=============== int ===============
Is 'int' an identifier? true
Is 'int' a keyword? true
Can 'int' be used as a name? false

=============== 1abc ===============
Is '1abc' an identifier? false
Is '1abc' a keyword? false
Can '1abc' be used as a name? false

=============== abc1 ===============
Is 'abc1' an identifier? true
Is 'abc1' a keyword? false
Can 'abc1' be used as a name? true

=============== $dustin ===============
Is '$dustin' an identifier? true
Is '$dustin' a keyword? false
Can '$dustin' be used as a name? true

=============== _dustin ===============
Is '_dustin' an identifier? true
Is '_dustin' a keyword? false
Can '_dustin' be used as a name? true

=============== dustin (space in front) ===============
Is ' dustin' an identifier? false
Is ' dustin' a keyword? false
Can ' dustin' be used as a name? false

=============== to be ===============
Is 'to be' an identifier? false
Is 'to be' a keyword? false
Can 'to be' be used as a name? false



The above output demonstrates that a valid name must be a valid identifier without being a keyword. A keyword must be a valid identifier, but not all identifiers are keywords. Some string values that are not keywords or reserved words are not even identifiers because they don't meet the rules of Java identifiers.

The examples above indicate that we cannot use a name for a variable or other construct that begins with a numeral, but we can use $ and _ for the first character in a name. Another way to determine this is through use of the static method Character.isJavaIdentifierStart(char). The following code snippet demonstrates this along with the similar method Character.isJavaIdentifierPart(char), which returns true if the provided character can be in the name anywhere other than the first character.


public static void printTestForValidIdentifierCharacter(
final char characterToBeTested)
{
out.println(
"Character '" + characterToBeTested
+ ( Character.isJavaIdentifierStart(characterToBeTested)
? "': VALID "
: "': NOT VALID ")
+ "FIRST character and "
+ ( Character.isJavaIdentifierPart(characterToBeTested)
? "VALID "
: "NOT VALID ")
+ "OTHER character in a Java name.");
out.println( "\tType of '" + characterToBeTested + "': "
+ Character.getType(characterToBeTested));
}

public static void demonstrateCharacterJavaIdentifierStart()
{
out.println("\nTEST FOR FIRST AND OTHER CHARACTERS IN A VALID JAVA NAME");
printTestForValidIdentifierCharacter('A');
printTestForValidIdentifierCharacter('a');
printTestForValidIdentifierCharacter('1');
printTestForValidIdentifierCharacter('\\');
printTestForValidIdentifierCharacter('_');
printTestForValidIdentifierCharacter('$');
printTestForValidIdentifierCharacter('#');
printTestForValidIdentifierCharacter('\n');
printTestForValidIdentifierCharacter('\t');
}


The output from the above appears below.


TEST FOR FIRST AND OTHER CHARACTERS IN A VALID JAVA NAME
Character 'A': VALID FIRST character and VALID OTHER character in a Java name.
Type of 'A': 1
Character 'a': VALID FIRST character and VALID OTHER character in a Java name.
Type of 'a': 2
Character '1': NOT VALID FIRST character and VALID OTHER character in a Java name.
Type of '1': 9
Character '\': NOT VALID FIRST character and NOT VALID OTHER character in a Java name.
Type of '\': 24
Character '_': VALID FIRST character and VALID OTHER character in a Java name.
Type of '_': 23
Character '$': VALID FIRST character and VALID OTHER character in a Java name.
Type of '$': 26
Character '#': NOT VALID FIRST character and NOT VALID OTHER character in a Java name.
Type of '#': 24
Character '
': NOT VALID FIRST character and NOT VALID OTHER character in a Java name.
Type of '
': 15
Character ' ': NOT VALID FIRST character and NOT VALID OTHER character in a Java name.
Type of ' ': 15


Because the Character.getType(char) method has been with us for quite a while and predates the J2SE 5-introduced enum construct, this method returns primitives integers. One can refer to Java's Constant Field Values to determine what each of these constants stand for.

To make the above example's output a little more readable, I have added a simple "converter" method that converts the returned int to a more readable String. I have only added switch cases for the integers returned from my example, but one could add cases for all supported types represented by different integers.


public static String extractReadableStringFromJavaCharacterTypeInt(
final int characterTypeInt)
{
String characterType;
switch (characterTypeInt)
{
case Character.CONNECTOR_PUNCTUATION :
characterType = "Connector Punctuation";
break;
case Character.CONTROL :
characterType = "Control";
break;
case Character.CURRENCY_SYMBOL :
characterType = "Currency Symbol";
break;
case Character.DECIMAL_DIGIT_NUMBER :
characterType = "Decimal Digit Number";
break;
case Character.LETTER_NUMBER :
characterType = "Letter/Number";
break;
case Character.LOWERCASE_LETTER :
characterType = "Lowercase Letter";
break;
case Character.OTHER_PUNCTUATION :
characterType = "Other Punctuation";
break;
case Character.UPPERCASE_LETTER :
characterType = "Uppercase Letter";
break;
default : characterType = "Unknown Character Type Integer: " + characterTypeInt;
}
return characterType;
}


When the integers returned from Character.getType(char) in the example two listings ago are run through this switch statement, the revised output appears as shown next.


TEST FOR FIRST AND OTHER CHARACTERS IN A VALID JAVA NAME
Character 'A': VALID FIRST character and VALID OTHER character in a Java name.
Type of 'A': Uppercase Letter
Character 'a': VALID FIRST character and VALID OTHER character in a Java name.
Type of 'a': Lowercase Letter
Character '1': NOT VALID FIRST character and VALID OTHER character in a Java name.
Type of '1': Decimal Digit Number
Character '\': NOT VALID FIRST character and NOT VALID OTHER character in a Java name.
Type of '\': Other Punctuation
Character '_': VALID FIRST character and VALID OTHER character in a Java name.
Type of '_': Connector Punctuation
Character '$': VALID FIRST character and VALID OTHER character in a Java name.
Type of '$': Currency Symbol
Character '#': NOT VALID FIRST character and NOT VALID OTHER character in a Java name.
Type of '#': Other Punctuation
Character '
': NOT VALID FIRST character and NOT VALID OTHER character in a Java name.
Type of '
': Control
Character ' ': NOT VALID FIRST character and NOT VALID OTHER character in a Java name.
Type of ' ': Control


The SourceVersion class is useful for dynamically determining information about the Java source code version and the keywords and valid names applicable for that version. The Character class also provides useful information on what a particular character's type is and whether or not that character can be used as the first character of a name or as any other character in a valid name.

Who Should Oracle Sell MySQL To?

There is no shortage of people calling for Oracle to sell MySQL. I keep reading that Oracle should sell MySQL to "a suitable third-party" or to a "neutral third party." I understand why these people feel passionate about this, but "loose" terminology like this is always dangerous. It implies that this is an easy thing to do and that there is a line of suitors out there waiting to snap up MySQL for a fair market price.

I wonder if there is a line of potential MySQL purchasers out there just waiting for an opportunity to bid on MySQL. Should Oracle have to shed MySQL even for a low-ball price in the name of market competitiveness? Can a company make significant money off of MySQL? Did Sun make money off of MySQL? Should Oracle or Sun take a loss on MySQL in the name of community betterment? Should another company purchase MySQL even if they don't believe they can ever earn back their investment (without even considering a desired profit margin) in the name of community betterment? Is eminent domain a consideration here?

Some companies make money related to shepherding open source projects; many do not. Ironically, at the time it seemed that Sun's purchase of MySQL overshadowed Oracle's purchase of BEA. Sun purchased MySQL for roughly one billion U.S. dollars ($800 million cash plus $200 million debt assumption). Can Oracle expect to get at least that for MySQL? Or, is MySQL worth more or less than that now? One could argue its only worth what someone else will pay for it. Is someone willing to pay more than $1 billion for MySQL? Should Oracle be forced to sell MySQL to the highest bidder regardless of the amount bid?

I have no idea what the fate of MySQL would be under Oracle, but I am almost as curious and uncertain about what price Oracle could get for MySQL. It is probably much like my most trusted old cars have been: they have been worth quite a bit more to me because they are cheap to own and operate and I know they are in good condition. However, they are not worth nearly as much to anyone else. I wonder if this is a similar case: is MySQL worth much more to Oracle than it is to anyone else? One could make an argument that "the community" values MySQL more, but it is nearly impossible for "the community" to purchase something like this for any reasonable price. What would be required in that case is either Oracle donating MySQL or selling it at significant discount or a "representative" of the community stepping forward to purchase it. Is there any organization out there ready to step up and be that representative? Does any organization have sufficient selfish motivation to do this?

It's easy to suggest that Oracle should sell to a "suitable third party?" That's just talk. The potentially significantly more difficult thing might be to actually find a buyer that meets the definition of "suitable" to all involved. I would love to hear those who state that Oracle should sell MySQL do more than state things as though if are as easily implemented as they are stated. I'd like to see who is willing to bid for MySQL and how much they're willing to bid. Of course, even those organizations interested in bidding on MySQL are not likely going to share their offers publicly. So, we're left wondering if there are any buyers out there willing to pay anything close to what Oracle feels the value of MySQL is.

MySQL may be one of the best examples one can think of where its value to the overall community is tremendous (perhaps many times more than $1 billion in this case), but it is much more difficult for any single organization to see enough individual value to justify purchasing it (in this case for anywhere close to $1 billion). There is no question that MySQL brings significant value to its users, but does it carry enough value to whoever owns it to justify its purchase? Or, is this another example of the problems of the commons? For my part, I can see how MySQL might be of more value to Oracle than it is to any other single party. This makes a sale difficult because Oracle wants more than any individual organization is willing to pay. MySQL is almost certainly more valuable to the collective community, but the collective community is not structured to make the purchase.

If someone is to purchase MySQL without a deep discount from what Oracle likely thinks it is worth, that "someone" will need to have a plan how they will make money from their ownership of MySQL. The more they pay for MySQL, the more revenue they need to be able to directly trace back to ownership of MySQL. Which organizations are in a position to profit from owning MySQL? How can these organizations most readily make money off ownership of MySQL? I don't know the answers to all of these questions, but I'd love to hear others' ideas.