How to schedule tasks or perform tasks repeatedly

There is an excellent tutorial at The Java Tutorial called
Using the Timer and TimerTask Classes.

It explains how to use a timer to schedule tasks or to perform tasks repeatedly. With the Timer and TimerTask classes you don’t have to create your own threads, it’s all done for you. Thank you Joshua Bloch for writing these classes.

On a side note, Joshua Bloch is one of the premier Java engineers. Recently he left Sun for Google. Gosh, that must have hurt Sun.

java.io.FileNotFoundException for valid URL

In one of our ATG servlet’s we were making a normal HTTP call to a page located on our ATG Dynamo server.

url = new URL(urlString);
connection = (HttpURLConnection)url.openConnection();
reader = new InputStreamReader(connection.getInputStream());

Free Daddy and His Little Shadow Girls at The Skate Park Creative Commons on FlickrHowever when trying to get the input stream we got a FileNotFoundException yet we were able to go to the same URL using a browser. Googling around we found this lovely thread about the same problem.

To summarize the thread, the problem was in our proxy settings which are set on Windows in localconfig/environment.bat and on UNIX in localconfig/environment.sh. An example of proxy settings on Windows is set PROXY_ARGS=-Dhttp.proxyHost=192.168.1.134 -Dhttp.proxyPort=8080.

The proxy server did not recognize our machines as valid clients so it rejected our requests. Once we changed the proxyHost argument to point to a valid server then this problem was fixed.

JDBC Optimization for Populating a Table

Today I was trying to determine how to optimize the populating of a table. I was using ATG Relational Views which took 3.5 minutes to add 6000 lines to a table.

After googling for awhile I learned how to do this using JDBC directly and was able to do the same populating in 0.14 minutes. That’s quite a performance improvement.

It would be interesting to contract the performance differences using ATG’s repository implementation but right now I am developing on ATG 4.5.1 so I can’t.

These are the links to the sites I used to educate me on PreparedStatement‘s and batching.

ONJava.com: An Introduction to JDBC, Part 3
JavaWorld.com: Overpower the Prepared Statement
PreciseJava.com: Best practices to improve performance in JDBC
DBA-oracle.com: Optimize Oracle INSERT performance

Find a class’s runtime origin

JavaWorld has a great article on finding a class’s runtime origin called Back to your Class roots. Below is the highly useful getClassLocation method from the article.

/**
 * Given a Class object, attempts to find its .class location.
 * Use for testing/debugging only.
 * 
 * @return URL that points to the class definition; null if not found
 */
public static URL getClassLocation (final Class cls) {
  if (cls == null) throw new IllegalArgumentException ("null input");
  
  URL result = null;
  final String clsAsResource = cls.getName ().replace ('.', '/').concat (".class");
  
  final ProtectionDomain pd = cls.getProtectionDomain ();
  // java.lang.Class contract does not specify if 'pd' can ever be
  // null; it is not the case for Sun's implementations, but guard
  // against null just in case:
  if (pd != null) {
    final CodeSource cs = pd.getCodeSource ();
    // 'cs' can be null depending on the classloader behavior:
    if (cs != null) result = cs.getLocation ();
    
    if (result != null) {
      // Convert a code source location into a full class file location
      // for some common cases:
      if ("file".equals (result.getProtocol ())) {
        try {
          if (result.toExternalForm ().endsWith (".jar") ||
            result.toExternalForm ().endsWith (".zip")) 
            result = new URL ("jar:".concat (result.toExternalForm ())
              .concat("!/").concat (clsAsResource));
          else if (new File (result.getFile ()).isDirectory ())
            result = new URL (result, clsAsResource);
        }
        catch (MalformedURLException ignore) {}
      }
    }
  }
  
  if (result == null) {
    // Try to find 'cls' definition as a resource; this is not
    // documented to be legal, but Sun's implementations seem to allow
    // this:
    final ClassLoader clsLoader = cls.getClassLoader ();
    
    result = clsLoader != null ?
      clsLoader.getResource (clsAsResource) :
      ClassLoader.getSystemResource (clsAsResource);
  }
  
  return result;
}

Serial Version UID

It is simple to make a class serializable, just have it implement the java.io.Serializable interface. However it is not easy to support the serialized form forever.

One issue is the serial version UID. Every serializable class has a unique identification number associated with it. If you do not specify the identification number explicitly by declaring a private static final long field named serialVersionUID, the system automatically generates it by applying a complex deterministic procedure to the class… If you change [the class] in any way … the automatically generated serial version UID changes. If you fail to declare an explicit serial version UID, compatibility will be broken.

Bloch, Joshua. Effective Java. p. 214

To generate the serial version UID for a class use the serialver tool which comes with the Java SDK. The serialver tool returns the serial version UID for one or more classes.

Example:

$ serialver -classpath 'build;C:/foo/classes.jar' com.bar.FooMessage

or

> serialver -classpath build;C:\foo\classes.jar com.bar.FooMessage

An even easier way to generate the serial version UID is to use the Eclipse IDE. If your class implements the java.io.Serializable interface and it does not have a serial version UID then Eclipse will give a warning about this next to the class name. If you click on the warning you can choose the option “Add generated serial version ID.”

Note, currently there is a bug with Eclipse and generating the serial version UID. When attempting to generate a serial version UID you will see a dialogue window which says “Computing serial version ID….” and “Starting virtual machine…”. Unfortunately this hangs and you are forced to kill your Eclipse IDE. I started seeing this bug yesterday after installing some JDBC plugins and the GEF plugin, I’m not sure if it’s related to that. I tried disabling the plugins but I still see the problem. Before I wasn’t having this problem.