Java Nits

Java is a good tool, but it seems like noone ever mentions the 'dark side'

Below I summarize a bunch of nits in Java that I find annoying.

JDK1.1.6

In the production release of JDK1.1.6, it looks like someone decided that JDK1 should use Sun's lame package system. This bites:
  • To install, one needs to be root
  • Supporting multiple versions of the jdk is difficult. Since Java is write once, test everywhere, this makes testing difficult.
  • The package system writes to /usr/java and /usr/bin, which means that upgrading the system will lose these changes. At least they could have installed it in /opt
  • The JDK1.1.6 instructions are wrong:
  • The instructions say that it will write to /usr/java. In fact, it writes to /usr/java1.1, /usr/demo/JAVA1.1, /usr/share/man/man1. I have no idea why JAVA1.1 is capitalized in the demo directory.
  • Javadoc

    After writing a documentation system for Itcl, an object oriented extension to Tcl, I find javadoc to be really wanting.
  • It would be nice if there was a way to modify the body background color.
  • The links that point to Java base classes are not live.
    For example, tree.html almost always lists java.lang.Object as the base class, yet that link is not live.
    Unfortunately, there is no canonical place for the Java api documentation (another story).
    One solution would be to have javadoc have an argument that would point to the directory that contains the doc/api directory.
    An issue here is that if the HTML pages are to be browsed over the web, then the location of the doc/api directory needs to be accessible. This could either be a link in the local directory, or a URL back to the master on www.javasoft.com.
  • If you have a @see link in a file, then you have to run javadoc on both files at once to get the link to show up.
    This is bad, because what if I am extending a class that whose documentation files I don't have write priviledges to?
  • The javac compiler looks inside doccomments for the @deprecated tag and prints warnings accordingly In jdk1.1, javadoc takes a @deprecated tag.

    If this tag is present in the doc comment of a method that overrides a method that has a @deprecated tag, then the compiler will not print deprecation warnings.

    For example, PlotBox.java uses the mouseUp() method. If I build with:javac -deprecated PlotBox.java Then I get

    
    PlotBox.java:758: Note: The method boolean mouseUp(java.awt.Event,
      int, int) in class java.awt.Component has been deprecated, and class
      plot.PlotBox (which is not deprecated) overrides it.
        public boolean mouseUp(Event evt, int x, int y) {
    
    If I add an @deprecated doctag:
        /**
         * Set the starting point for an interactive zoom box.
         * Set the starting point for an interactive zoom box.
         * @deprecated As of JDK1.1 in java.awt.component 
         * but we need to compile under 1.0.2 for netscape3.x compatibility.
         */
        public boolean mouseDown(Event evt, int x, int y) { // deprecated
    
    Then javac no longer complains about mouseDown being deprecated. This means that the javac compiler is looking inside doc comments and using the information inside to print warnings. This is sort of bogus to me. In every other language I've used, comments are opaque. See the jdk1.1 deprecation page for more information.
  • CLASSPATH

  • Why does CLASSPATH contain both directories and files? This is a little confusing. LD_LIBRARY_PATH contains only directories. In general, 'path' variables contain directories, not files
  • The great thing about Java is 'code reuse', which means you find a collection of classes that someone has written, you download them, and then you stick them in a directory and use them.
    This is great until you start thinking about the CLASSPATH implications. Most developers will want to have their users set CLASSPATH to a single directory. Also, most developers will want to push 'reused' code down into a separate directory so that it is compartmentalized and easy to identify as contributed code.
    So, most developers will create a lib or utils directory and place all the code that they are borrowing in it. The problem is that if the borrowed code imports classes in the same package, then the CLASSPATH will be wrong if it set to a single top level directory.
    For example, say my product has a top level directory that contains the Java I've written, and the CLASSPATH is set to that top level directory. If I have a borrowed package named stuff, with a Foo class that imports a Bar class, then I'm in trouble.
    I put a borrowed package in the lib/stuff subdirectory, thinking I can refer to those classes as lib.stuff.Foo and lib.stuff.Bar. However, if Foo.java contains imports stuff.Bar, then I won't be able to compile these files unless my CLASSPATH includes the lib subdirectory.
    So, for every package that I reuse I have to put it in a directory that has a entry in CLASSPATH. This means I have to help my user manage their CLASSPATH by writing a startup script on both Unix and Windows that is portable and bulletproof.
  • If Java is suppose to be platform independent, then why is CLASSPATH under Windows separate with semicolons and CLASSPATH under Unis separated by colons? Of course the reason is that in Windows, a colon is used to separate a drive name from the rest of a path, and in Unix a semicolon is used to end separate commands.
    Still, this means that we need to be able to process two types of CLASSPATHS inside Java. Also, every developer needs to write their own tools to manipulate the CLASSPATH.
  • Threads

  • Why do Java threads have different scheduling behaviours on different platforms? This is terrible if you are trying to create platform independent applications.
    The solution is to write a layer on top of the Java thread system that preserves determinacy. This is a daunting proposition at best.
  • BTW - for native threads under Solaris, see: http://www.javasoft.com/products/jdk/1.1/index.html

    cxh at eecs