Thứ Hai, 9 tháng 3, 2009

Including Images in Javadoc with NetBeans

There are times when it is useful to include images and other non-source files in the documentation generated with Javadoc. The Javadoc tool documentation refers to these types of non-Java source files as Miscellaneous Unprocessed Files and states that they should be placed in a doc-files subdirectory within the package directory to which the non-source file applies.

When using Javadoc directly or via direct use of Ant, these doc-files subdirectories are copied into the generated Javadoc documentation directories and are available to the HTML pages that make up the generated documentation. Unfortunately, the Javadoc mechanism provided by NetBeans 6.1 and NetBeans 6.5 for a standard NetBeans Java Application project does not support this unprocessed file copying directly. Fortunately, this is easy to address.

This issue of NetBeans Ant-based Javadoc generation target not copying non-source files is discussed in the Sun Forum on the Javadoc Tool in the javadoc not copying from doc-files directories thread. In that forum, two postings recommend adding an alternate Ant target or overriding the NetBeans-built Ant target for generating Javadoc to support this copying. These are both useful approaches, but I think the easiest approach is to simply take advantage of NetBeans's hook for additional Javadoc tool arguments.

NetBeans generates a target with name -javadoc-build in the generated build-impl.xml file that resides in the project's nbproject directory. This target invokes the Ant core javadoc tag to run the Javadoc tool. This target uses a nested fileset tag to specify that all Java files (**/*.java) should have documentation generated. Because **/*.java is specified, only Java files have documentation generated.

One really easy way to have non-Java files copied to the generated Javadoc documentation is to take advantage of the additionalparam attribute of the Javadoc tag. I often use this attribute to specify the -linksource argument in Javadoc generation, but it can be used to specify that all directories and files under the source directory get copied by specifying the -sourcepath argument. For example, if the source directory is specified with a property like ${src.dir}, one can set additionalparam=-sourcepath ${src.dir}. NetBeans allows the additionalparam option for Javadoc to be easily specified by setting the ${javadoc.additionalparam} property in the project.properties file in the same nbproject directory.

The javadoc.additionalparam property is very useful in the NetBeans development environment when one needs to override settings of its Javadoc generation that do not provide their own property-based handles.

Thứ Bảy, 7 tháng 3, 2009

Colorado Software Summit 2008 Keynote Presentations Released

Colorado Software Summit 2009 has been announced (25-30 October 2009) and the main web site has been redesigned as part of this announcement. The two keynote presentations from last year's edition, Colorado Software Summit 2008, have also been made available from this main page.

As has been a conference tradition for many years, John Soyring opened the technical portion of the conference on Monday morning with the opening keynote presentation Change ... that Matters. Simon Phipps presented the Thursday morning keynote presentation The Adoption-Led Market: The Third Wave of Open Source? I blogged on these presentations after attending them and those postings are available here (Soyring's presentation) and here (Phipps's presentation).

In addition to these two keynote addresses from Colorado Software Summit 2008, you can find presentations from earlier versions of the conference on the Previous Conferences page. The page points out that additional presentations from Colorado Software Summit 2008 will be made available throughout the year.

Chủ Nhật, 1 tháng 3, 2009

JavaOne 2009 News: Initial Acceptance/Rejection Announcements

An idea of the types of presentations that will be available at this year's edition of JavaOne (2009) is starting to form with notices going up all over the blogosphere about presentations being accepted or rejected. I have been curious if JavaFX would be the dominant topic for a third straight year. As we hear more about which presentations have been accepted, we may begin to know if JavaFX is going to be the Main Event once again. Note that All JavaOne Blogs provides a nice collection of blog postings focused on the 2009 JavaOne Conference. The JavaOne Conference on Facebook is also available.


2009 JavaOne General Background

According to this announcement for open registration, over 1300 abstracts were submitted for the 2009 JavaOne Conference. This also explains that "35 external reviewers" plus a "panel of Sun employees" review the abstracts.

The topics that are the focus of 2009 JavaOne are Rich Media Applications and Interactive Content, Mobility, Services, and Core Technologies.

Kirk Pepperdine's blog posting Your JavaONE Proposal Has Been Rejected explains Kirk's perspective on why Sun employees do get the lion's share of presentations at JavaOne. He asserts that there is no favoritism, but that it is more a reflection of the fact that it is Sun employees working on the products being selected for discussion. He also points out (and Cay Horstmann's feedback comment reiterates) that there are many more high-quality presentations than available slots.

Lukas Hasik explains in one of his blog postings that only Sun employees are allowed to submit Hands-On Labs (HOLs) for JavaOne and that the process for these differs from that for presentations and Birds of a Feather (BOFs).

Eric D. Schabell has posted a copy of a rejection letter that explains that the submitted abstracts exceeded capacity by over 400% and provides a link to the well-known post How to Get Your JavaOne Talk Accepted.

There is much discussion about an under-representation of Groovy, Grails, and Griffon at this JavaOne. Among other posts, this is highlighted in Thoughts on Groovy, Grails, Griffon at JavaOne and No Grails at JavaOne.


Specifically Accepted Presentations

The following are some of the presentations that have been advertised by someone as selected for 2009 JavaOne. I expect to see more blogs on accepted presentations this coming week and then, of course, the full schedule to be released in the near future. UPDATE: Some of the linked-to announcements of accepted abstracts have been added since the original posting.




Specifically Rejected Presentations

Bloggers are understandably less excited about announcing their rejected abstracts, but their experiences do provide insight into the process and what the likely focus of the conference will be. Also, these people are in good company as many well-known speakers seem to have their abstracts rejected. This 2005 post shows that this is nothing new.




The 2009 JavaOne Conference will be held June 2-5, 2009. Contrary to a purported rumor, this edition of JavaOne will again be held at The Moscone Center in San Francisco.

Thứ Bảy, 28 tháng 2, 2009

Locating The Classpath Definition Used in Java Code

In a previous blog posting, I listed some "everyday problems" Java developers will often face and included some ideas and links related to addressing these issues. One of the focal points of that post was Java classpath issues. One tool that I neglected to mention in that post (but will be adding belatedly when I add a link to this post) is use of Java security-related classes to identify where the class definition used in a Java application comes from on the classpath.

The ability to identify the source of a class definition in a Java application is an especially useful tactic when one knows or has reason to suspect that a particular class is defined twice on the classpath, possibly with different definitions. In general, the first definition of a class found on the classpath is the one used, but this technique can verify the class definition being used or can be useful when there is a very large classpath that makes it difficult to identify all instances of a particular classpath entry.

As discussed in How to Determine Where Your Java Class is Actually Located, Where's That Class Coming From?, How to Know from Which JAR Your Class is Loaded From, Where Did That Class Come From?, Where to Find JARs?, and J2SE Security, the Java SE Security model provides a convenient mechanism for identifying the source (JAR or .class file) of a class definition used in a Java application. This approach involves getting the ProtectionDomain from a class's Class and using that ProtectionDomain to obtain a CodeSource which provides a URL to the source of that particular class definition.

I will include the full code a little later, but here is a sample of code focused on using these Security APIs to get class definition information.


/**
* Provides the name of the classpath entry that provides the class definition
* of the provided object.
*
* @param objectInQuestion Object for which classpath source of instance is
* desired.
*/
public static final String getClassPathSource(final Object objectInQuestion)
{
final StringBuilder builder = new StringBuilder();
final Class clazz = objectInQuestion.getClass();
final ProtectionDomain protectedDomain = clazz.getProtectionDomain();
final CodeSource codeSource = protectedDomain.getCodeSource();
if (codeSource != null)
{
builder.append("CodeSource: ").append(codeSource.toString());
builder.append(Constants.NEW_LINE);
final URL url = codeSource.getLocation();
builder.append("URL: ").append(url.toString());
}
else // codeSource == null
{
builder.append("CodeSource for ")
.append(clazz.getCanonicalName())
.append(" is null.");
}
return builder.toString();
}


As the code listing above shows, it is a relatively straightforward process to use get a particular object's Class to obtain a ProtectionDomain from which a CodeSource can be obtained. The CodeSource provides the getLocation() and toString() methods that make it really easy to display the classpath locations from which the class definition came.

The code snippet above can be used in a class such as the ClassPathIdentifier class shown next.

ClassPathIdentifier.java


package classpathidentifier;

import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;

/**
* This class reports what entry in the classpath provides the definition of
* the provided Object.
*/
public final class ClassPathIdentifier
{
/** This class is not intended for public consumption. */
private ClassPathIdentifier() {}

/**
* Provides the name of the classpath entry that provides the class definition
* of the provided object.
*
* @param objectInQuestion Object for which classpath source of instance is
* desired.
*/
public static final String getClassPathSource(final Object objectInQuestion)
{
final StringBuilder builder = new StringBuilder();
final Class clazz = objectInQuestion.getClass();
final ProtectionDomain protectedDomain = clazz.getProtectionDomain();
final CodeSource codeSource = protectedDomain.getCodeSource();
if (codeSource != null)
{
builder.append("CodeSource: ").append(codeSource.toString());
builder.append(Constants.NEW_LINE);
final URL url = codeSource.getLocation();
builder.append("URL: ").append(url.toString());
}
else // codeSource == null
{
builder.append("CodeSource for ")
.append(clazz.getCanonicalName())
.append(" is null.");
}
return builder.toString();
}

/**
* Test method to demonstrate use of this functionality.
*/
public static void main(final String[] arguments)
{
if (arguments.length < 1)
{
System.err.println("You must provide a fully qualified Class name.");
System.exit(-1);
}
final String classForSource = arguments[0];
if (classForSource.isEmpty())
{
System.err.println("You must provide a valid string for class path/name.");
}
System.out.println("You provided class of " + classForSource + " ...");

try
{
final Class clazz = Class.forName(classForSource);
final Object object = clazz.newInstance();
System.out.println("Source: " + getClassPathSource(object));
}
catch (ClassNotFoundException classNotFoundEx)
{
System.err.println("Could not find class " + arguments[0]);
}
catch (InstantiationException instanceEx)
{
System.err.println("Unable to instantiate instanceof " + classForSource);
}
catch (IllegalAccessException illegalAccessEx)
{
System.err.println("Illegal Access trying to instantiatite " + classForSource);
}
}
}


It is not exciting, but I include the code listing for the Constants class next for completeness.

Constants.java


package classpathidentifier;

/**
* Constants used in simple example demonstrating one way to determine the
* classpath entry from which a particular instance was specified.
*/
public class Constants
{
/** This constructor is not intended for public consumption. */
private Constants() {}

public final static String NEW_LINE = System.getProperty("line.separator");
}


For this example, I am also using a basic class called SomeClass, which is defined next.

SomeClass.java


package classpathidentifier;

public class SomeClass
{
/** An integer. */
private final int someInt;

/** Some String. */
private final String someString;

/**
* Constructor accepting arguments to populate an instance of me.
*/
public SomeClass(final int newInt, final String newString)
{
this.someInt = newInt;
this.someString = newString;
}

/**
* Provide my integer value.
*
* @return My integer value.
*/
public int getSomeInt()
{
return this.someInt;
}

/**
* Provide my String value.
*
* @return My String value.
*/
public String getSomeString()
{
return this.someString;
}

/**
* Provide String representation of me.
*
* @return My String representation.
*/
@Override
public String toString()
{
final StringBuilder builder = new StringBuilder();
builder.append("Some Int: ").append(this.someInt).append(Constants.NEW_LINE);
builder.append("Some String: ").append(this.someString);
return builder.toString();
}
}


With all of the classes defined above, it is time to turn to an executable class that can drive out use of these APIs. The relatively simple Main class demonstrates the approach of using Class->ProtectionDomain->SourceCode->getLocation() to determine the original source on the classpath of that class's definition.

Main.java


package classpathidentifier;

/**
* Main class that is separate from ClasspathIdentifier class, but uses that
* class.
*/
public class Main
{
/** My instance of SomeClass. */
private SomeClass someClass = new SomeClass(5, "Five");

/** No-arguments constructor doesn't do anything exciting. */
public Main() {}

/**
* Provide access to my instance of SomeClass.
*
* @return My instance of SomeClass.
*/
public SomeClass getSomeClass()
{
return this.someClass;
}

/**
* Main function for running me.
*
* @param arguments Command-line arguments; none expected.
*/
public static void main(final String[] arguments)
{
final Main me = new Main();
printString(ClassPathIdentifier.getClassPathSource(me));
printString(ClassPathIdentifier.getClassPathSource(me.getSomeClass()));
printString(ClassPathIdentifier.getClassPathSource(me.getSomeClass().getSomeInt()));
printString(ClassPathIdentifier.getClassPathSource(me.getSomeClass().getSomeString()));
}

/**
* Print provided String.
*
* @param stringToPrint String to be printed.
*/
private static void printString(final String stringToPrint)
{
System.out.println(Constants.NEW_LINE);
System.out.println(stringToPrint);
}
}


This class demonstrates how this approach works on different classes. When I run this Main class as part of a JAR, the output appears as shown below.



As the above screen snapshot demonstrates, the getLocation() method (and the toString()) provide a URL to the JAR file from which the class was found. The command at the top of the output window shows that this class was indeed in the JAR because that JAR is the only item on the classpath.

The next screen snapshot shows execution of the Main class using the classes directory in the classpath rather than using a JAR.



In this case, we can see that the source of the classpath entries was the directory rather than a JAR file. What happens when both (the JAR and classes directory) are on the classpath? The next screen snapshot demonstrates this with the JAR first and then with the directory first.



The last screen capture indicates that whatever class definition appears first on the classpath (when reading from left to right) is the one used by the class loader for that application.

Finally, you may have noticed that the classes Integer and String from the core Java API have null values for CodeSource.

Conclusion

There are situations when a mismatch of class definitions or multiply defined class definitions cause runtime headaches. In such cases, an approach like that demonstrated in this blog posting can be useful and provide some relief.

Thứ Năm, 26 tháng 2, 2009

Software Development Atrocities Committed in the Name of Flexibility

Although it is difficult to measure and quantify, most of us have heard and do believe that flexibility is an important part of software development. There are numerous advantages gained from software that is designed and implemented to be flexible and adaptive. However, I think it is worth asking, "Can we have too much of a good thing?"

The human body, in some situations, can indeed have too much flexibility. I think the same is true for software. In this blog posting, I will explain why I believe that we as software developers sometimes allow the desire for extreme flexibility to overshadow more important software characteristics.


Benefits of Flexible Software

There are several benefits to flexible software that have made this flexibility desirable to software developers.

Software Maintenance Benefits

It is a generally accepted observation that software maintenance costs significantly exceed development costs. Therefore, it is sensible to want to make the software as adaptive and flexible to bug fixes and other maintenance activities as possible.

Software Modifications/Enhancement Benefits

Another generally accepted observation in the software development world is that requirements and customer desires can and do change. Again, flexible software is key to dealing with this likely scenario.

Software Reuse Benefits

Advertised benefits of software reuse can sometimes be difficult to realize without significant cost because the original software is not flexible enough to be easily reused outside of its very narrow initial application. The idea here is that one can increase the reusability of one's software by making it more flexible.


Drawbacks of Developing Flexible Software

Software flexibility is generally a desirable characteristic because of the benefits described above. However, this flexibility is often far from free and, in some cases, can even be a detriment.

Higher Initial Cost of Flexible Software

In some cases, it can be significantly more difficult (and correspondingly more expensive) to introduce the desired flexibility into the developed software. In the extreme case, it is definitely cheaper to initially hard-code values all over the place, but we have all learned (usually through hard experience) that the costs of doing this are so great that we should take the time to use properties, XML, or other more dynamic values for our software. This is a case where the flexibility does come at a higher initial cost, but almost always "pays for itself" in the long term. This situation is one in which long-term benefits seem to dwarf the initial higher cost of more flexible software. However, not all situations are the same and there are situations where the long-term benefits may not justify or even cover the initial costs.

YAGNI

Software development projects have a notoriously bad record for not completing on time or on budget. There are several explanations for this as eloquently called out in the software development classic The Mythical Man-Month, but certainly one part of this is the desire we seem to have to add features and flexibility that will likely not need or only remotely may need. Extreme Programming introduced the term "You Aren't Gonna Need It" (YAGNI). This well-known term essentially serves as a reminder that we should not waste time and effort on things that we will never need. As the blog posting Using YAGNI Responsibly reminds us, this does not mean that we should shortchange long-term benefits like flexibility. Instead, we should be more realistic about the ratio of costs to benefits.

Greater Difficulty to Understand

Flexibility can sometimes make the software more difficult to understand or use initially. This occurs when certain techniques that make software more flexible also happen to create more classes, interfaces, and other pieces of code that must be understood.

Less Practical Use

Although appropriately chosen flexibility can increase the overall usefulness of a piece of software, too much or inappropriate flexibility can actually have the opposite effect. For example, a framework or library that is supposed to help improve development productivity will not likely be successful in that goal if it is as flexible as the programming language upon which it is based. To be useful, the framework usually needs to make some assumptions and limit some flexibility.


Examples of Flexibility Gone Wrong

Using Java String Rather than Java Enum for a Constant

A specific example that I have repeatedly observed in which the desire for flexibility has blinded experienced developers is overuse of the Java String. We had to wait a long time to get a Java enum, but the wait was worth it. It is painful to see the enum go unused even in situations screaming for its use. When I ask a developer why he or she is not using an enum rather than a String when the range is finite, the usual answer is something like "It is more flexible. What if I find myself needing to add a new value down the road?" This answer effectively implies that the benefit of being able to add an arbitrary String at any point in the future is worth more than the type safety, readability, comparison performance, and other benefits of the enum. This actually might be the case if the range of values changes frequently or is so large that it feels like it is not finite, but I have heard this argument multiple times for small sets of finite and fixed data with no obvious changes or additions in the near future or in the future at all.

Wide-Open SQL Statements

You don't have to work in software development with databases long to realize the dangers of using dynamic SQL in applications. While allowing any arbitrary string to be executed against the database is certainly more flexible, it is also far more dangerous and unpredictable. In fact, errors related to this kind of thinking are included in the CWE/SANS Top 25 Most Dangerous Programming Errors. Although it seems obvious that one should not do this, it is an example where enthusiasm for extreme flexibility could lead one astray and blind him or her to the downsides.


The Flexibility Continuum

Because flexibility in software is generally a desirable quality, the tricky part is knowing how much flexibility to add to a piece of software for long-term benefits without running up extraordinary costs or creating something too complex to maintain or use. Part of the difficulty is that the appropriate degree of flexibility is difficult to identify because it depends on context and because it depends on the often unpredictable future. Experience improves our ability to predict when the extra effort to add flexibility will pay off, but we cannot expect to always be correct. Sometimes, we will plan more flexibility than is actually needed while at other times we may wish we had spent a little more time making our application more flexible. Still, I think it is better to use our best engineering judgment when deciding how flexible to be than to blindly go to one extreme (no flexibility) or the other (complete flexibility at all cost).

In general, "throw-away" code such as demonstration code or prototypes will require less flexibility while larger and longer-term applications will require much greater flexibility. The longer an application is in production and use, the more likely that users will want new features and changes. Frameworks and libraries intended to be used by applications tend to need much greater flexibility than end applications that are not intended to be used as part of another application. Even with these guidelines, deciding on the exact level of flexibility for a given software project is still difficult due to the largely unforeseeable future events

It seems that sometimes we see extremism in which the developer does not believe in any flexibility, hard codes everything, doesn't design for extensibility, and generally makes software nearly impossible or extremely costly to even slightly enhance. However, the opposite extreme is to spend undue time and effort to obtain unnecessary flexibility and to sacrifice other software benefits to obtain that flexibility.


Flexibility's Best Uses

Where we choose to apply flexibility is an important consideration. Flexibility tends to be most useful if it is at an architecture or design level. Low-level code is almost always easier and cheaper to change than architectural concepts. Many good practices will naturally lead to greater flexibility while at the same time delivering other benefits. For example, modularity can make code easier to understand while at the same time increasing code's flexibility. Extensibility can be a benefit now and in the future. In fact, extra effort to justify additional flexibility is easiest to justify when we can realize benefits of that flexibility both now and in the long-term.

The worst time to expend significant resources on flexibility is when that proposed flexibility has minor and unlikely benefits now or in the future. What is especially frustrating is when one exerts significant time and effort for a level of flexibility that is truly unattainable or unrealistic, but wastes time and effort trying to achieve it anyway.


Conclusion

It is generally a good idea to design and implement our software to be extensible, maintainable, and flexible. However, even flexibility can be taken to an extreme where we spend inordinate amounts of time, money, and effort to design and write the software features that may never be needed and we may even end up with something too flexible to be used practically. Software development is filled with trade-offs and the degree of flexibility we should employ in our applications is a trade-off with the amount of time and resources to spend to gain that degree of flexibility.

Flexibility is a necessary characteristic of any software application of long term significance, but the desire for extreme flexibility does not justify ignoring all other desirable software characteristics. Depending on the context, duration, and future use of a software application, flexibility can be anywhere from a highly desirable characteristic to a necessary characteristic. However, flexibility must not be the excuse for over-engineering, over-designing, or over-complicating an application; or the excuse for indulging in a software development guilty pleasure; or for making a software project go over time and budget. Above all, the ability to easily change our software for something that might happen in the future should not limit our ability to deliver what is needed and desired today.

Thứ Hai, 23 tháng 2, 2009

Small Java 7 Language Changes

Project Coin is the name of the OpenJDK work covering small language changes for Java SE 7. The current Java.net poll question asks which of the proposed Project Coin features is most interesting. I often like to gauge the interests of the Java developer community based on these poll questions and their results. In this case, I am not going to analyze the results because, at the time of this writing, the vote total is just over 100. Instead, I am going to describe what each of the proposed features are and what my own level of interest in each is.

The choices to vote for to answer the question of which Project Coin feature is most interesting are: switch statement support for Strings, ability to catch multiple exceptions with the same catch clause, using type parameters for more concise constructors, call methods with exotic names, bracket notation for collections, and any feature not already listed. I will now briefly summarize each of these features and state my own level of interest in each feature.


Strings in Switch Statements

There was a time when I really wanted this feature. In fact, I have even written about this feature in the ActionScript language and compared it to Java. This feature is less important to me now that we have the powerful and typesafe enum. That being said, I know several Java developers who prefer Strings because of greater flexibility. For them, switching on String would help them avoid long if-then-else blocks.

For me, I generally find that I only really use switch for things that are finite and for which individual differences are more frequent than similarities. In other words, in many cases, if something needs such flexibility that it is better supported by Strings than by Enums, then it is typically the case that I don't need to switch on individual values anyway.

Many people have expressed interest in having the ability in Java to switch on Strings. Accounts of this interest are available in Java Switch Statements Should Allow Strings, Not Just Ints, A Switch on String Idiom for Java, Java String Switch, and Switch on String in Java.

In the end, I have a slight preference toward the ability to switch on Strings, but the emphasis is on slight.


Multi-Exception Catch

This is another "small change" that many Java developers have requested. For example, the blog posting Wanted: Multiple Exception-type Catch Blocks talks about why this would be useful. This feature is described in Alex Miller's section on the Improved Catch Clause.

I have run into the situation more than once when it would be nice to catch multiple exceptions and handle them with the same exception handling code. I have found this to be especially true when using older libraries and frameworks that make use of large sets of checked exceptions. For example, in working with Remote JMX, there are many common checked exceptions one encounters. The developer is usually forced to either catch a very general exception to handle all of them or to list each one out individually to handle them differently. Being able to combine two or three closely-related JMX exceptions in the same handling block would be handy.

Even with the benefits described above, this is still a feature for which I only have a slight preference. With the trend toward unchecked exceptions except for things that can really be expected to be handled, I have run into this problem far less. Also, there seems to be a trend for frameworks to use exception hierarchies and I can often catch the parent exception for general exception handling for that API or framework.


Bracket Notation for Collections

This feature refers to the ability to reference a particular item in a Collection with square brackets similar to how Arrays are accessed. Shams Mahmood makes a persuasive argument for a similar feature (instantiation of a collection like an array) in his blog posting My Java 7 Wishlist Regarding Collections. In the blog posting Double Brace Intialization, Isa Goksu describes how double curly braces apply an anonymous inner class and obtain a similar effect. He also points out multiple issues with this approach. The Java Idioms site covers this double brace initialization approach in even greater detail.

The argument for the ability to treat Collections more like arrays is that this syntax is easier and more concise. According to this argument, Collections would be even more widely accepted and used instead of arrays if Collections had this array-like syntax. This is another feature that could be handy, but I only have slight preference for.


Concise Constructors with Type Inference

This feature would allow the compiler to understand the generic types being used in a constructor based on the newly instantiated object's data type rather than necessarily needing to redeclare the generic type as we do today. The pain associated with this redundant type information is lessened by today's powerful IDEs. That being said, it also seems sensible that a statically typed language like Java could take advantage of the fact that it knows the generic type on the left side of the equals sign to imply what static types are used on the right hand side of the equals sign.

It's become a tiresome theme, but this is another feature that I won't mind having, but also won't lose any sleep over not having. Again, I have only a slight preference for the addition of this feature.


Exotic Method Name Calling

The aim of this feature request is for Java to allow methods to be called in non-Java languages. Many of these non-Java languages allow their methods to have characters not supported in Java method names. While this would be of the least benefit to me in the short-term, I could see this feature providing the greatest long-term benefit as it is likely that we'll see the trend toward mixed language use continue to grow.


Conclusion

It is not surprising that "small language changes" tend to be, for me at least, also smaller in terms of enthusiasm and excitement. Of course, I also don't have strong feelings from a negative perspective on these small changes. If all of them were implemented, I would occasionally benefit. If none of them were implemented, I'd only occasionally miss them.

One other observation that can be made from looking at these Project Coin changes is that many of them meant more to me in the past, but the passage of time and improving language features have reduced my degree of interest in these features. The long-awaited arrival of the Java enum, the rise of the powerful Java IDEs, and other advancements have reduced the urgent need for these changes to some degree. The one exception to this is the exotic method name support, a feature for which need is actually relatively new and is likely to grow rather than diminish.

The final personal observation from this is that, at least for the small things, the Java language is very mature and there are very few small things that I have a strong longing for. In other words, I'm pretty happy with the Java programming language generally.

Thứ Ba, 17 tháng 2, 2009

Day-to-Day Java Development Tools and Techniques

There are some common things that are useful to know in many day-to-day Java development activities. It is especially helpful for someone new to Java development to know where to find this information, but I have found bookmarking these sources to be useful even as I have gained experience developing Java applications. Because one of the primary purposes for me writing a blog is to provide myself with an easy way to find things I am looking for, I am using this blog posting to collect some of these sources of information that I frequently use for Java development in one place. Because these items are related to the development of Java applications rather than to source code, it is not surprising that many of the items are specific to the JVM I am using.


Java Processes: jps

There are many times in Java development when it is important to know which Java processes are running. More specifically, I find myself needing the process ID of Java applications for running other tools against those processes or for terminating processes. There are several Sun JDK development tools, but one of my favorites is the jps tool (JVM Process Status Tool). This "experimental" tool lists the Java processes running on the target HotSpot JVM. As I previously blogged, my favorite use of this tool is jps -lm.


JVM Arguments

Java Application Launcher

The environment a Java application runs in can be significantly tweaked via the use of JVM arguments. In addition, JVM arguments allow for different levels of monitoring and analysis of the executing Java application. The command java -help lists the standard options (standard across different JVM implementations) for the Java application launcher. The command java -X can be used to see the Java application launcher's non-standard (X for extension specific to that JVM) arguments. In the HotSpot JVM, some frequently used extension arguments are -Xms and -Xmx for initial Java heap size and maximum Java heap size respectively.

The -Xbootclasspath option can be used to either prepend (/p) or append (/a) resources to the bootstrap classpath.

If you wish to detect which JVM arguments your currently running Java application is using, you can use the ManagementFactory.getRuntimeMXBean().getInputArguments() call as described in Accessing JVM Arguments from Java. This technique takes advantage of Platform MXBeans available since J2SE 5 (custom MXBeans support was added in Java SE 6).

Two useful sources of information on the JVM parameters available when using Sun's JVM are A Collection of JVM Options and Charles Nutter's Favorite Hotspot JVM Flags. Both of these resources list and describe some/all of the not-recommended-for-the-casual-developer double X arguments (-XX) that are available.

Java Compiler

The javac Java compiler also has command-line arguments that can be of great use. Like the java application launcher, the javac compiler that comes with the Sun Java SDK includes both standard options and non-standard/extension options. These options are displayed in a manner consistent with that used for the application launcher. Non-standard options include bootstrap classpath append and prepend options, setting of endorsed standards path, setting of directory of installed extensions, and enabling and disabling of specific warnings (-Xlint options including -Xlint:path).


Warnings

-Xlint

The warnings reported by the Java compiler can be very useful in identifying things that either may be larger current problems than one realizes or could easily turn into more significant problems. Sun's javac compiler allows one to take relatively granular control of which warnings are enabled and disabled using -Xlint (all warnings are reported when this is used by itself). Specific warnings can be reported by providing the type of warning after the -Xlint: notation. If no reports of warnings are desired (other than those the Java Language Specification requires), the notation -Xlint:none is used.

@SuppressWarnings

One can use the @SuppressWarnings annotation introduced with J2SE 5 to mark in code the warnings that should not be reported when the code is compiled. However, a natural question is which specific warnings can be suppressed in-code using this annotation. It turns out that this is compiler-specific. For Sun's compiler, the available warnings that can be suppressed with @SuppressWarnings are listed here and here.


Java Classpath Issues

Classpath Basics

The Java classpath can be one of the most confusing things for a new Java developer. The classpath can become a complicated mess even for experienced developers when different issues arise due to different classloader behaviors, the presence of slightly different versions of libraries on the classpath, and incorrectly typed classpaths. Fortunately, there are several tools to help understand and better work with the classpath.

For those just learning Java and Java classpaths, a good starting point is to read Elliotte Rusty Harold's articles Managing the Java Classpath (Windows) and Managing the Java Classpath (Unix). These articles provide a good overview of the options one has for setting a classpath, why dynamically setting the classpath is preferred over using an environment variable, and provides the basics of how classpaths work with Java packages.

Because the Sun Java compiler will ignore an entry on the classpath that it cannot resolve, it is easy to think that one has correctly typed in a classpath entry even if it is incorrectly typed. The -Xlint:path extension option instructs the Java compiler to report any classpath entries that cannot be resolved.

The JARs, .class files, and other resources specified on a command-line classpath using -classpath or -cp are typically not the only resources on an application's classpath. Other sources of classpath information that must be considered include the standard Java classpath (for standard Java classes), jre/lib/ext, and jre/lib/endorsed (uses bootstrap classpath). In addition classpaths may be different when using an IDE and are different when using web servers and application servers (classpath is typically determined by the contents of the WAR file and EAR file in those cases).

ClassNotFoundException Versus NoClassDefFoundError

One thing that can be a little tricky when first learning Java is distinguishing between the ClassNotFoundException and the NoClassDefFoundError. The Javadoc API documentation for each of these explains their use and why they might occur. In most cases, the easy way to differentiate between the two is that the ClassNotFoundException indicates that a class needed for compilation cannot be found on the classpath and a NoClassDefFoundError indicates that the matching class that was found at compile time cannot be found at runtime. This differentiation between compile time and run time can be useful in figuring out when the classpath entry is missing.

It is also interesting to note that while ClassNotFoundException is a checked exception extending Exception directly, NoClassDefFoundError is actually an Error rather than an Exception. Note that ClassNotFoundException can actually be encountered during runtime in a variety of situations such as the runtime on-the-fly compilation of JavaServer Pages, reflection, and, as the API states, "when an application tries to load in a class through its string name." Generally speaking, the causes of NoClassDefFoundError are more diverse and difficult to resolve than those of ClassNotFoundException.

Some interesting and in-depth articles on class loading are available in the Demystifying Class Loading Problems series. Other references regarding the difference between these two exceptions are available at Difference Between ClassNotFoundException and NoClassDefFoundError, What is the Difference Between ClassNotFoundException and NoClassDefFoundError?, Java Fanatics: NoClassDefFoundError versus ClassNotFoundException, and ClassNotFoundException and NoClassDefFoundError.

UPDATE (2 March 2009): Identifying an Instance's Original Classpath Definition

UPDATE (2 March 2009): This subheading and entire paragraph have been added since the original post. Some of the NoClassDefFoundErrors one might run into can be traced to multiple definitions of the same class on the classpath with slight differences. One way to see which class definition a loaded class is using is described in another blog post of mine.



System Properties

Java provides some standard properties that can be used for several different benefits. An often used property from this set include line.separator for a platform-independent reference to a new line. It is not easy to remember all of the available system properties, especially those that are not used often. Fortunately, several resources either list these or provide code examples of how to see a list of them. For example, Java Standard System Properties lists them, How to Print All the Java System Properties demonstrates how to programmatically list them, and Java: System Properties both demonstrates how to get the properties via code and lists them. The Javadoc-based API documentation for System.getProperties() lists the system properties that are always available. I've even been known to blog on properties before.

The Platform MXBean RuntimeMXBean provides a RuntimeMXBean.getSystemProperties() method that can be used to see the system properties as well.


View Swing GUI's Hierarchy with CTRL-SHIFT-F1

A nifty trick with Swing-based applications is the ability to use CTRL-SHIFT-F1 to see the Swing GUI's hierarchy. This is further demonstrated and explained in the Tech Tip Ctrl-Shift-F1 in Swing Applications.


serialver

The command-line serialver tool is useful for generating servialVersionUID attributes on classes that implement the Serializable interface. I have blogged previously on the serialver tool.


jar Tool and JAR Files

jar Tool

With the prevalence of IDEs and Ant and Maven for building Java code, it is easy to forget about the jar command. However, knowledge of the jar command can be useful for writing and running simple tests and examples. One of jar's characteristics that makes it most useful is the fact that it uses the ZIP compression format and uses similar syntax to the tar command. The versatile jar command can even be used to display the contents of an Adobe AIR .air file.

Executable JAR Files

JAR files can be made executable so that they can be run with a command line java -jar someJar.jar without the need to specify classpath information or the main executable class in the JAR. The classpath and the main class to execute do not need to be explicitly stated because they are embedded in the executable JAR's manifest file with the Class-Path and Main-Class name/value pairs respectively. There are a few details to be aware of when using executable JARs (such as specifying the class path entries via directories relative to the location of the executable JAR file) and these details are covered in the blog posting Executable Jar File in Java.

JAR Manifest File Information

You can place essentially any name/value pair in a manifest file on its own line. While virtually any names and values can be used, there are some standard and accepted manifest name/value pairs one might wish to use. These include Class-Path, Main-Class, package version information (Specification-Title, Specification-Version, Specification-Vendor, and implementation equivalents). The Manifest file is also used to seal packages in JAR files. See also the Wikipedia entry on Manifest File for more details.


JVM JMX Instrumentation

The JVM itself has been instrumented with Java Management Extensions (JMX) support since J2SE 5. This provides valuable information regarding the JVM and applications running in the JVM. Sun provides JConsole (since J2SE 5) and VisualVM (since Java SE 6 Update 7) with their SDK for easy developer monitoring of the JVM and its deployed applications.

Platform MXBeans have been provided with the Sun JVM since J2SE 5 and provide a wide variety of details regarding the JVM. Platform MXBeans provide information on JVM topics such as thread contention, operating system details, memory analysis, and logging management. As described earlier, the RuntimeMXBean provides interesting information such as the classpath in effect, the boot classpath, system properties, and JVM vendor and specification details. The available Platform MXBeans are described in greater detail in Using the Platform MBean Server and Platform MXBeans.

Java EE application servers also provide information via JMX.


UPDATE (18 February 2009) Generating a Stack Trace

UPDATE (18 February 2009) Eyal Lupu reminded me (see feedback) of a very handy tool during debugging (especially when processes are hanging). Forced generation of a stack trace with a SIGQUIT, CTRL+\, or CTRL-BREAK (Windows) is described in greater detail in An Introduction to Java Stack Traces.


Documentation

Some of the Java documentation resources that I use most often include the overall JDK 6 Documentation (includes links to many of the other documents referenced in this blog posting), the Java SE 6 API documentation, the Java EE 5 API documentation, and specialized documentation such as the Spring Reference Manual and the Oracle Technology Network JPA Annotations Reference. Perhaps my favorite tool for finding useful documentation is the Google search engine.