There doesn't seem to be a lot of Java-related articles on Knol that represent content not available elsewhere. The bigger issue is other sites with more Java content. The demise of GeoCities and Knol remind us that it's always possible for Java-heavy content sites to eventually succumb.

Other Options

It's probably true that in many cases the content on Knol is available elsewhere, albeit perhaps in different forms and not organized the same way. However, there is still the possibility that some original content will be lost and it's even more likely that creative packaging of content will be lost. The Internet Archive Wayback Machine will also likely have cached values of many of the Knol entries.

If you regularly reference any Knol entries, you may want to make a local copy of them. I like to save my favorite web references as local PDFs using one of the many browser plug-ins for writing PDFs (Chrome has this capability built in). On the Web, there's never any guarantee that a link here today will still be here there tomorrow. Because this is especially true on small and little-known sites,I tend to save any articles or posts I highly value on these lesser known sites to PDF.

Conclusion

Knol never reached the size in terms of content of GeoCities, but it is newer, so the information that is lost may be more timely and relevant than the majority of that lost with GeoCities' demise. That being stated, there is useful content on Knol that may be lost forever. The imminent demise of Know, coupled with GeoCities' demise, remind us of the fragility of "permanent" on the Web.

In this post, I look focus on a different set of seven NetBeans hints that may not be as "indispensable" as the first set, but which I have found to be very useful in moving existing code and my own mindset about writing code in Java into the era of JDK 7. NetBeans 6.9 began the introduction of numerous new hints that I've become quite fond of for moving forward into improved performance and safety in JDK 7.

Suggesting EnumMap and EnumSet

Two of the hints that were introduced with NetBeans 6.9 in the "Performance" category are "Map replaceable with EnumMap" (described in NetBeans Java Hints as "Finds instantiations of Maps that can be replaced with EnumMap") and "Set replaceable with EnumSet" (described as "Finds instantiations of Sets that can be replaced with EnumSet"). I have posted before regarding the advantages of using EnumMap and EnumSet, so I find these to be two very useful hints when working with existing code. Although the Enum and associated EnumMap and EnumSet have all been around since J2SE 5, there may be code bases where these were not used because the code is older or because developers did not think of them when creating their maps or sets.

The next series of snapshots demonstrate in a static fashion how these hints identify potential situations where EnumSet and EnumMap are potentially more efficient. The first image shows an example of the hint to use EnumSet. The second through fourth images demonstrate the hint for using EnumMap along with selecting the action to apply an EnumMap and the result of that action.

JDK 7 Upgrade Hints

NetBeans 7.x offers several hints related to Java 7 syntax and language support in the "JDK 1.5 and later" category of hints. These hints provide more examples of where NetBeans hints can help bring existing Java code bases into a newer and more current version of the JDK. One important thing to note here is that NetBeans will only identify these hints if the source version associated with the NetBeans project is JDK 7 (1.7).

Two of the NetBeans hints related to JDK 7 are related to catching exceptions. Both the "Join catch sections using multicatch" hint ("Join catch sections using multicatch") and the "Use specific catch" hint ("Converts catch (Throwable) or catch (Exception) to multicatch catching the exceptions thrown by the try body.") were introduced with NetBeans 7.0.

The three screen snapshots that follow show an extremely convoluted piece of code that does demonstrate the "Join catch section using multicatch" hint. The three images show display of the hint, choosing to apply the hint, and the result of applying the hint.

Another exception handling hint in NetBeans related to JDK 7 is the "Use specific catch hint." The idea of catching a more specific exception than Exception (or the even more general Throwable) is not new to JDK 7, but this is a JDK 7-dependent hint because it places multiple specific checked exceptions in a JDK 7 multicatch when it does the conversion. In fact, the hint doesn't apply if there is only one known checked exception that could be more specific than Exception or Throwable. Runtime exceptions (unchecked exceptions) are not considered for obvious reasons (they're not checked after all!) and only the presence of multiple checked exceptions in the try clause will lead to this hint.

All of this is depicted in the following screen snapshots. The first screen snapshot depicts the hint appearing because two checked exceptions are possible in the try block. The second image proves that the presence of one checked exception is insufficient for the hint to appear (one of them is commented out). The third image shows both checked exceptions applicable again and how to select the action to take place. The fourth image depicts the results of accepting the hint's recommended action: the general Exception is changed to a multicatch with the two specific checked exceptions that might be encountered.

NetBeans 6.9 introduced the "Use switch over Strings where possible." hint ("Marks cascades of ifs which can be converted to switch over Strings."). This allows developers to more readily recognize a lengthy series of conditionals based on Strings that can be refactored to use JDK 7's support for switching on Strings. The next three screen snapshots demonstrate the providing of this hint, the ability to apply the hint, and the result of the application of the hint.

JDK 7 introduced the diamond syntax to make use of generics a little more concise. NetBeans 7.1 has introduced the hint "Can Use Diamond" (described as "Warns about places where the diamond operator in JDK 7 can be used instead of explicit type parameters") to help migrate code to use of this more concise syntax. The next three screen snapshots show how the hint appears, the action that can be taken by clicking on it, and the result of that action being taken.

The "Convert to try-with-resources" hint ("Converts try finally block to try-with-resources") introduced with NetBeans 7.0 helps developers identify situations in which the handy and safer approach of using the new try-with-resources can be applied.

The next four images depict use of the "Convert to try-with-resources" hint in NetBeans. The first screen snapshot shows that if a resource is first checked in a conditional for non-null status, the hint does not appear. The second image shows that removing the condition on the resource leads to the hint appearing. The third screen snapshot shows the prompt to apply the action associated with the hint and the fourth image shows the results of applying the hint. The example in these snapshots is adapted from the example provided in the Java Tutorial page The try-with-resources Statement. NetBeans converts the try-finally (no catch in this case) example provided in that tutorial to essentially the try-with-resources example shown in the same tutorial.

This blog post has covered seven NetBeans hints that aid developers in taking advantage of newer features of Java (JDK 7 in particular). Enabling these hints (including associating the NetBeans project with JDK 7) enables developers to quickly identify pieces of legacy code that can be modernized when the compiler is upgraded to JDK 7 and can also help developers learn to write new code using these new constructs and features. The hints covered in this post are:

The "end" that most software developers are striving for is delivery of software solutions that make their users' lives easier and more productive. Unit tests can be extremely valuable in obtaining this end and certainly add to software quality, but the overly zealous unit tester must beware of allowing the unit tests themselves to displace this end goal. It's all too easy to allow oneself to get so bound up in writing exhaustive and "perfect" unit tests that one puts the true end goal at risk. In the remainder of this post, I look at ways in which developers can allow unit testing to move from helping achieve the desired end to unintentionally displacing the real end and putting it at risk.

The concept of code coverage can be a useful one as long as it's not taken too far. Code coverage appears to provide high return for the effort for a while, but there comes a point of diminishing returns when gaining additional code coverage comes at much greater cost and may not be worth that cost. It's also important to recognize that even the often highly expensive 100% code coverage typically means only all lines of code were executed and does not check all possible paths through the code.

All Code's Unit Testability is Not Equal

The post Selective Unit Testing – Costs and Benefits clearly articulates well the differences in difficulty (cost) and advantages (benefits) of unit testing of different types of code. In cases where the advantages/benefits of a unit test are high and the cost/effort is low, the value of unit testing is obvious. On the opposite extreme, there are types of code that receive little benefit from unit testing.

There Are Other Effective Types of Testing

I have seen multiple disparate groups of developers build and unit test their respective code bases flawlessly and then suffer through the pain of trying to integrate their thoroughly unit tested code with the other groups' thoroughly unit tested code. This happens when the involved groups have written comprehensive unit tests based on their own assumptions and without regard for functional and integration tests. A certain minimum number of unit tests are always necessary, but there may be cases where less important unit tests should not displace better or more comprehensive integration tests. When looking at code coverage, I prefer to look at code coverage from all types of tests rather than simply code coverage provided via unit tests.

I also question all the attention that unit tests are receiving at the expense of the other kinds of tests (functional, integration, etc.). The truth is that functional tests serve your users, while unit tests serve you — the developer. A unit test is just a convenience that allows you to track down bugs faster. At the end of the day, the reason you write tests is to make sure that your users will be able to be productive with your application, not to make sure that you can debug faster.

I also like how Igal Tabachnik puts it in the post Where unit testing fails: "The road to successful unit testing begins with understanding what unit testing is, but most importantly – what it isn’t."

Unit Testing is Not the Sole Means to the End

Not only are there other valuable types of testing, there are also other valuable software development tactics and methodologies for producing high-quality software the meets or exceeds customer expectations. Unit testing is a valuable part of this overall approach, but should not diminish or overshadow other approaches such as design and code inspections, appropriate collaboration, code analyzers, and so forth.

Sacrificing Other -ilities for Testability

As valuable as I believe unit testing is, the thing I probably find most frustrating about unit testing in Java is having to compromise a desired language design feature in production code for the sake of unit testing. To be sure, there are many cases where unit testing encourages better practices in the production code. For example, unit testing encourages smaller methods, a feature that is generally considered a strength in code maintainability and readability. However, there are times when I want to make my class final or a method final or private and this can be orthogonal to unit testability.

It galls me to have to give up long-term design considerations and benefits to make testing possible. I want the software I deliver to be of high quality and enjoy readability and maintainability. It is difficult to have to give some of this up in some cases in the name of testability. Fortunately, unit testing often forces better design. But in the cases when I must choose between elegant design and production code with hacked test code to test that elegant design or hacked design and production code to accommodate elegant test code, remembering that unit testing is not the end itself provides the appropriate frame of reference for making that call.

The good news is that modern unit testing frameworks are steadily reducing the types of desirable traits in production code that must be compromised to support unit testing. Unit test frameworks such as PowerMock use bytecode manipulation to overcome most of these issues.

Group Think

Whether we call it the Lemming Effect or peer pressure or group think, there's no question that we in the software development community tend to chase fads and shiny things. Unit testing has been part of software development for many years, but the increasing emphasis on it over the last decade has benefited software development. Unit testing has a long history in software development and has long since proven itself to not be a fad. However, I sometimes feel that some developers (particularly those who don't realize how long unit testing has been around) think it's something new that the rest of us don't understand. In their zeal to promote it as a "new thing," they actually make the act of unit testing more important than the goal of unit testing.

It is often the case in software development that evangelists and defenders of a particular product, language, framework, or technology cannot allow for any hint of a weakness or disadvantage to be discussed in relation to their favorite item. Any suggestion that their preferred product might not be the best thing since sliced bread is met with derision and scoffing. This ridiculous and unrealistic stance reduces constructive discourse about the advantages, disadvantages, opportunities, risks, and costs associated with a given approach. In the case of unit testing, this might be compounded by the fact that this practice was met with some skepticism by a large number of developers for numerous years and strong evangelism to change that has been largely successful but doesn't know now how to contain itself.

Conclusion

This post has assumed constrained resources and schedules. For those who have the luxury of not facing constrained resources and short timetables, there may be sufficient time to write and maintain all of the tests for all types of code no matter how trivial and still deliver a final product in time. However, many of us are in circumstances where costs and benefits of different aspects of software development must be evaluated. In such cases, it is important to keep focus on the true long-term goal and use effective unit testing to achieve this goal while not allowing unit testing itself to become the end goal. As with most things in software development, the level and type of unit testing should based on experienced judgment of the value gained versus the cost expended. Unit testing is a means to an end; it is not the end itself.

Saturday, March 24, 2012

This post references some of the recent blog posts and articles that have interested me. Topics include Java-specific topics such as Java EE, JavaFX, Scala, and Gradle as well as more general software development topics such as software patents and open source.

Patents may work in other industries, where the cost of innovation is so high that a temporary, state-sanctioned monopoly provides just enough time to gain a return on the investment. But that investment-return ratio has a completely different value for software. It turns out that software patents have little bearing on encouraging innovation. ... Software patents are ... bad news for most innovators in the software industry.

Phipps also looks at the relationship between software patents and open source software. He writes, "The problem is that open source software is defenseless against the anticompetitive abuse of patents."

Some of the feedback comments on this post are interesting because they demonstrate the differences of opinions between Java EE evangelists and Spring Framework evangelists (with comments from employees of both Oracle and SpringSource/VMWare among them). It is interesting to see the role reversal in this situation. Evangelists of the Spring Framework (even before it was so named) helped convince the Java enterprise development community of the problems with early J2EE, but now it seems the tables have turned and similar evangelism is advertising the "legacy" nature of Spring Framework as compared to modern Java EE.

The IBM DeveloperWorks article From Java code to Java heap is fairly comprehensive, providing background details on JVM memory handling and a focus on the impact of different Java collections on memory. This article also references the HotSpot option -XX:+UseCompressedOops as well as the similar IBM JVM option -Xcompressedrefs.

In the post Groovy, A Reasonable JVM Language for DevOps, Geoffrey Papilion writes that Groovy provides the "JVM glue" he sought for "a simple JVM language that allows me to use any native object." After demonstrating use of Groovy for a "quick script to get data from JMX into ganglia fromSsolr," he concludes

So, if you're working in a Java with a bunch of Java apps, think about giving Groovy a chance for writing some of your monitoring tests, and metric collectors. It is a simpler language than Java to put together those little applications that can tell you how your system is performing, and well within the reach of your average DevOps engineer.

I started this post with reference to an opinion-oriented post on open source and patents. It seems symmetrically pleasing to close this post with references to other opinion-oriented pieces. Tyler Menezes discusses technical and cultural reasons he won't use Ruby on Rails in the simply titled post I will not learn Rails. James Whittaker provides a articulate and insightful post Why I left Google.

Brian Fox points out that JSON's license agreement states "The Software shall be used for Good, not Evil." Fox further points out that "compliance is impossible" and that "this isn't even open source." He asserts that "this additional clause adds an unnecessary complication" and I tend to agree. The folks in suits are not comfortable with objective statements in the license agreements.

Conclusion

I have summarized and linked to Java-specific and general software development posts of interest in this blog post. The software development industry continues to be ever-changing and full of news.

Monday, March 19, 2012

I have blogged before on the handy Apache Commons ToStringBuilder and I was recently asked what the seemingly cryptic text appearing in the generated String output constitutes. The colleague asking the question correctly surmised that what he was looking at was a hash code, but it did not match his instance's hash code. I explained that ToStringBuilder adds the identity hash code in hexadecimal format to its output. In this post, I look in more depth at ToStringBuilder's use of the identity hash code presented in hexadecimal format. Even those not using ToStringBuilder might find this information useful as Java's standard Object.toString() also uses a hexadecimal representation of what is effectively its identity hash code.

I'll begin with a very simple Java example using ToStringBuilder. This example uses three Java classes (Person.java, Employee.java, and Main.java) that are shown next.

The output depicted above shows the String in question printed for both instance's output generated by ToStringBuilder. The String representation of the instance of Person class includes the String "1f5d386" and the String representation of the instance of Employee class includes the String "1c9b9ca". These strings are the hexadecimal representation of each object's identity hash code.

The strings "1f5d386" and "1c9b9ca" do not look like the integer hash codes many of us are used to seeing because of their hexadecimal representation. The Integer.toHexString(int) methods [available since JDK 1.0.2] is a convenience method for printing an integer in hexadecimal format and can be used to convert "normal" hash codes to see if they match those generated by ToStringBuilder. I have added calls to this method on the instances' hash codes in the new version of the Main class.

As the output indicates, the hexadecimal representation of the hash code for the Person instance does indeed match that shown in the ToStringBuilder-generated String for that instance. However, the same cannot be said for the Employee instance. The difference is that the Person class does not override the hashCode() method and so uses the identity hash code by default while the Employee class does override its own hashCode() (and therefore being different than the identity hash code).

With this in place, we can now compare the the identity hash code to the string generated by ToStringBuilder.

The last example definitively demonstrates that ToStringBuilder includes the hexadecimal representation of the system identity hash code in its generated output. If one wants to use the hexadecimal representation of the overridden hash code rather than of the identity hash code, an instance of ToStringStyle (typically an instance of StandardToStringStyle) can be used and the method setUseIdentityHashCode(boolean) can be invoked with a false parameter. This instance of ToStringStyle can then be passed to the ToStringBuilder.setDefaultStyle(ToStringStyle) method.

As a side note, the equals(Object) and hashCode() methods in the Employee class shown above were generated automatically by NetBeans 7.1. I was happy to see that, with my source version of Java for that project specified as JDK 1.7, this automatic generation of these two methods took advantage of the Objects class.

I have used ToStringBuilder-generated output throughout this post to facilitate discussion of hexadecimal representations of identity hash codes, but I could have simply used the JDK's own built-in "default" Object.toString() implementation for the same purpose. In fact, the Javadoc even advertises this:

The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:

getClass().getName() + '@' + Integer.toHexString(hashCode())

The only reason I did not use this example to begin with is that I almost always override the toString() method in my classes and do not get this "default" implementation. However, when I use ToStringBuilder to implement my overridden toString() methods, I do see these hexadecimal representations. I am likely to reduce my use of ToStringBuilder as I increase my use of Objects.toString().

Many of us don't think about hexadecimal representations or identity hash codes in our daily Java work. In this blog post, I have used ToStringBuilder's output as an excuse for looking a little closer at these two concepts. Along the way, I also briefly looked at the Integer.toHexString(Object) method, which is useful for printing numbers in their hexadecimal representation. Knowing about Java's support for hexadecimal representation is important because it does show up in toString() output, in labeling of colors, memory addresses, and in other places.

Tuesday, March 13, 2012

Typesafe today announced the release of Typesafe Stack 2.0, the latest version of its open source software stack. Typesafe Stack 2.0 is a comprehensive platform for building applications in Java and Scala that can scale to the largest workloads in cloud computing and virtualized enterprise datacenter environments. The release adds the innovative Play web framework for the first time, and includes Akka event-driven middleware 2.0, with significant enhancements for building concurrent and distributed applications.

Because I'm new to Play, Akka, and even Scala, I welcomed the opportunity to ask the folks at Typesafe questions about the Typesafe Stack 2.0 from a beginner's perspective. The following questions were asked of and answered by Typesafe President and CEO Donald Fischer. With these questions, I tried to find out what I needed to know to determine the motivation for beginning use of Typesafe Stack 2.0 and where to start in my efforts to learn and use it.

Q&A with Typesafe CEO Donald Fischer

Question: What are the most compelling advantages of the Typesafe Stack 2.0?

Some of the most compelling advantages of the Typesafe Stack versus legacy platforms are:

Strategies for working in a world of horizontal scale. Modern software needs to take advantage of more cores and more machines, rather than faster single cores.

An emphasis on developer agility, productivity, and enthusiasm. Developers want to work quickly and focus on business logic rather than boilerplate.

An emphasis on pragmatic interoperability. The Typesafe Stack APIs can be used from Java or Scala or both; and they can be adopted incrementally. It's as simple as adding some jars to your project.

Question: How much familiarity with Scala is required to use Typesafe Stack 2.0?

While the Typesafe Stack includes Scala, and is built on a Scala foundation, both the Play web framework and Akka middleware offer native APIs for both Java and Scala. So developers can build applications that leverage all of the capabilities of the Typesafe Stack without any specific knowledge of Scala (though we don't think they'll be able to resist the added productivity that Scala provides once they get a taste).

Question: On a spectrum of 100% Java to 100% Scala with a combination of the two between those ends of the spectrum, what portion of the spectrum is supported by Typesafe Stack 2.0? (Can one use Typesafe Stack 2.0 with Java only?)

100% of the functionality in the Typesafe Stack frameworks (Akka and Play) is supported for both Scala and Java.

Question: What is the easiest way to get started using the overall Typesafe Stack 2.0?

Question: What online resources are available regarding the use of Typesafe Stack 2.0?

We've collected a variety of resources including videos from project contributors, commercial users, and the community here: http://typesafe.com/resources

Question: Are there any books available or planned that cover the individual products within Typesafe Stack 2.0 as well as the overall integrated stack?

Yes, we've accumulated a collection of books here: http://typesafe.com/resources/books
We're proud that several of these books are authored by Typesafe employees, including Martin Odersky, Josh Suereth, Heiko Seeberger, and Philipp Haller.

Question: What is the licensing for Typesafe Stack 2.0 and is it consistent across the individual products and the overall stack?

The Typesafe Stack is 100% open source. It's complemented by the commercial Typesafe Subscription, which adds support, maintenance, and tools including the new Typesafe Console. The Typesafe Console is available exclusively to Typesafe Subscription customers.

Question: What potential enhancements are planned for Typesafe Stack 2.0?

Upcoming releases of the Typesafe Stack will include additional clustering features and enhanced support for building applications that adapt to elastic cloud environments.

Typesafe Stack 2.0 appears to offer developers several advantages, one of which is the ability to learn the Scala language, the Play framework, and the Akka toolkit all while solving difficult problems associated with modern software development. The press release alludes to these problems in the sentence, "Typesafe provides the most scalable software platform designed for the computing architectures of the future -- multicore, parallel and cloud applications."

Typesafe's licensing model is a familiar one with significant product (the Typesafe Stack 2.0) available via an open source license and add-on tools available for a commercial subscription. The advantage of this is that a developer can "play" (no pun intended) with Typesafe Stack 2.0 and then later move to Typesafe Subscription as needed and desired. It has been my experience that, generally speaking, it is an advantage to have a large corporate sponsor of an open source product I am using. Corporate sponsorship tends to mean dedicated resources invested in improving and maintaining the product. Examples include the Spring Framework and Groovy (SpringSource), NetBeans and GlassFish (Sun/Oracle), Eclipse (IBM), etc. Typesafe's optional commercial support for Typesafe Stack 2.0 is potentially useful for customers, but Typesafe's apparent commitment to the product's development and maintenance is highly valuable as well.

Specific licensing information for the products of Typesafe Stack 2.0 can be found at the Typesafe Licenses page. As of this writing, this page reports that "Scala and the Scala IDE for Eclipse are available under the Scala License", Play and Akka are licensed with the Apache License, Version 2.0, and "Simple Build Tool (sbt) is available under the BSD license."

Conclusion

The press release, the answers to my questions above, and the plethora of resources available on the Typesafe site all imply a highly beneficial product. I am not in any way affiliated with Typesafe and I have not yet tried Typesafe Stack 2.0 out for myself, but it looks very promising. If nothing else, playing with it and possibly applying it to real problems might be one of the best ways to learn Scala, Play, and Akka, but one can always fall back to Java when using it if necessary.

Saturday, March 10, 2012

The JavaOne 2012 Call for Papers has been issued. The window for submission is March 14 through April 9. Notifications regarding accepted and declined proposals will be made in late May or early June and speakers whose proposals are accepted are expected to confirm their session by the middle of June. JavaOne 2012 is September 30 through October 4, 2012, in San Francisco, California. JavaOne 2012 is again being held in conjunction with Oracle OpenWorld 2012 and OpenWorld begins its call for papers on March 14 as well.

Thursday, March 8, 2012

The current Java.netpoll question is, "How critical is it for JSR-310 (new Date and Time API) to be implemented in Java 8?" At the time of my writing of this post, nearly 150 respondents have voted and an overwhelming percentage have answered either "Very" (53%) or "It would be nice, but we can get by using the current classes" (22%). With 3/4 of the respondents feeling that it would either "be nice" or is "very important" to get a new Java Date/Time API, I think it's safe to say that Java's current Date and Calendar approach has not grown on us. Perhaps my biggest surprise so far with the survey results is that 2% of the respondents have stated, "I prefer the current date and time classes." Maybe that's from the people who wrote those classes?

I tend to use Java's date/time/calendar APIs off and on. When I use them, I really don't like them, but do start to tolerate them. I begin to forget how much I loathe them until I use them again. I recently helped a colleague familiar with Java (but not with the date/time APIs) to understand how to do some Date/Calendar/String manipulation and presentation. Explaining this mess out loud to him made the ridiculous difficulty of using these too-flexible APIs even more obvious to me. I could see on his face that he was thinking I was either kidding him or didn't know what I was talking about. Although I've gotten to the point where I can make them make do, it's much more difficult than it should be.

The current Java.net survey confirms my feeling after working with numerous Java developers and after reading many blogs and articles that the vast majority of Java developers are anxious to get a better standardized way of handling dates and times in Java.

As the screen snapshot below demonstrates, NetBeans 7.1 builds the source code above fine as shown in the Output Window when the version of Java associated with the project is Java SE 6. However, the NetBeans editor shows the red squiggly lines indicating compiler error. The next image shows what the error message is.

Although NetBeans 7.1 is able to build the code shown above when it's part of a project associated with Java SE 6 (Update 31 in this case), the code editor still reports the error shown above. This is because NetBeans uses a different version of the Java compiler internally than the one explicitly associated with the project being edited. If I change the version of Java associated with the NetBeans project for the source code above, it will no longer build in NetBeans. This is shown next.

There are a couple interesting things about this bug. First, the fact that this code compiles fine in Java SE 6 but is addressed and does not compile in Java SE 7 means that it is possible for code working in Java SE 6 to not work when the code base is moved to Java SE 7. I downloaded the latest version of JDK 6 available (Java SE 6 Update 31) and confirmed the original code shown above still builds in Java SE 6. It does not build in Java SE 7.

There are other versions of the code above that do not build in Java SE 6 or in Java SE 7. For example, if the code above is changed so that the methods return the same type, the code doesn't build even in Java SE 6. Similarly, if the Collection parameters to the two overloaded methods include a "raw" Collection (no parameterized type), it won't compile in Java SE 6 either. Of course, even if the return types are different, if the same Collection parameterized types are passed to both overloaded methods, even Java SE 6 won't compile this. These three situation are depicted in the following three screen snapshots.

The code that builds in Java SE 6 but not in Java SE 7 needs to have overloaded methods that differ in both return types and in terms of the parameterized types of the collections that make up their method parameters. It doesn't matter if a given return type matches or is related to the parameterized type of the method's parameter as long as they differ. If the return types are the same, Java SE 6 detects a compiler error. Java SE 6 also detects the error if the erased parameters boil down to the same collection after erasure and the return types are not different.

A second interesting thing about this bug is how its handled in NetBeans. Because NetBeans use its own internal compiler that does not necessarily match the version of the compiler that the developer has associated the IDE project to, you can run into situations like this where the code actually builds in the IDE, but the IDE's functionality such as code editors and project browsers indicate the code breaking.

Because NetBeans 7.1 uses its own internal Java compiler for the code editor, one might wonder if this means Java 7 features could be sneaked in and would work in the IDE but then would not build when attempted from the command line or when explicitly built in the IDE. The next screen snapshot demonstrates why that is not the case. In that snapshot, a Java 7 specific feature is in the code and NetBeans 7.1 properly warns that this is not compatible with the Java 1.6 source setting.

The colleague who showed me this issue realized its existence because NetBeans 7.1 reported the "name clash ... have the same erasure" even when he was working with Java SE 6 code. This discovery was "accidental" due to the newer version of NetBeans using Java SE 7 compiler internally, but he welcomed the opportunity to fix the issue now rather than when he migrates to Java SE 7.

I found this issue worth posting a blog post on because it provides a warning about a bug that may already be in some Java SE 6 code bases but will be made all too evident when the code base is moved to Java SE 7. I also posted this because I think it's important to be aware that modern versions of NetBeans use an internal compiler that may be of a different version than the compiler the developer has explicitly associated with his or her NetBeans project.

Friday, March 2, 2012

A recent reddit Java thread is titled "Share a useful class from the standard Java Class Library!" and starts with the comment, "There are so many available classes and sometimes ones exist that you don't realize. Share one that you use that the rest of us may not be aware of!" In this post, I look at some of the (mostly JDK) classes mentioned in the forty (at time of this writing) responses to this request.