Example of an ImageIO transcoder

A transcoder is responsible for converting one particular image type to another and is designed in such a way that metadata specific to that image type is not lost.

The following example outputs all transcoders that are defined for converting gif to jpg. Currently there are none, but since ImageIO is pluggable, third-party transcoders should become available soon.

Main.java:

import javax.imageio.stream.*;
import javax.imageio.*;
import java.util.*;
  
public class Main
{
   public static void main(String []args) {
      Iterator readers = ImageIO.getImageReadersByFormatName("gif");
      ImageReader reader = (ImageReader) readers.next();
 
      Iterator writers = ImageIO.getImageWritersByFormatName("jpg");
      ImageWriter writer = (ImageWriter) writers.next();
 
      Iterator transcoders = ImageIO.getImageTranscoders(reader, writer);
      while (transcoders.hasNext()) {
         ImageTranscoder tc = (ImageTranscoder) transcoders.next();
         System.out.println(tc);
      }
   }
}

Using runFinalizersOnExit

If an object cannot be accessed anymore, it is ready for garbage collection. Before the memory is labeled free, the VM will call the object’s method finalize in which you can clean up resources. However, it is possible that the GC may never run (for example, there’s always enough memory). As a design guideline, you should not free up any memory or release database connections inside your finalize method, as you don’t have any control over when it will be invoked. Instead, use a custom cleanup method that is explicitely called when the object is no longer needed.

runFinalizersOnExit specifies that finalize methods will be invoked when the application exits.

Eg. run this example, uncomment and run it again:

public class Main {
   public static final void main(String[] args) {
      //System.runFinalizersOnExit(true); 
      new Main();
   }
 
   protected void finalize() {
      System.out.println("Main object finalized");
   }
}

Since JDK1.2, runFinalizersOnExit has been deprecated. From the API: “This method is inherently unsafe. It may result in finalizers being called on live objects while other threads are concurrently manipulating those objects, resulting in erratic behavior or deadlock.” Check out http://java.sun.com/products/jdk/1.2/docs/guide/misc/threadPrimitiveDeprecation.html for more information on Sun’s view on this issue.

For more information, I wrote to Hans Boehm, an expert on Runtime issues. Here’s what he’s got to say:


Disclaimer: I generally don’t agree with the Java designers on the details of the finalization mechanism. Thus you shouldn’t take this to be authoritative.

My impression is that there are actually two issues. Sun’s documentation implies that they were worried about synchronization issues. What happens if a thread is stuck holding the lock on A, a finalizer needs the lock on A, and if you’ve requested that finalizers be run on exit. You can’t exit?

I have a more fundamental problem with it. It makes it impossible to rely on any finalizer ordering, which I claim makes it impossible ti write reliable nontrivial finalizers. Let’s say that A’s finalizer needs access to object B, which is also finalizable. To make this concrete, let’s say that B actually holds a handle to some object C manipulated by JNI native code, and B’s finalizer explicitly deallocates C with a JNI call. Thus if A accesses B after it is finalized, B will try to follow the dangling native pointer to C. This arises for example if A somehow buffers requests to B, and has to flush them when it’s finalized.

This is somewhat inconvenient with Java finalizers, but it’s not too bad. A needs to ensure that a pointer to B is kept in some static location, so that B doesn’t get finalized first. When A’s finalizer is run, it clears the static pointer to B, readying B for finalization.

But this break with runFinalizersOnExit! At exit, finalizers to statically accessible objects have to be run. A and B may both be accessible, and the runtime has no way to tell which finalizer should be run first. Thus there is no way to prevent the dangling native pointer dereference.

In general with runFinalizersOnExit, you can’t assume that when a finalizer is run, method calls on other objects (or static method calls) are safe, since any other object may have previously been finalized. Presumably parts of the runtime/standard library may also already be finalized. Thus it’s not clear to me that you can really safely do anything useful in a finalizer. Certainly runFinalizersOnExit will break code not designed to run with it.

Hans

Sorting an array

Since JDK1.2, the utility class Arrays in the java.util package provides useful
array manipulation methods such as fill, binary search and sort.
A fast algorithm to sort an unsorted array is QuickSort. It provides you with
O(n*log(n)) time complexity, where n is the number of entries to sort. If you
execute the quicksort algorithm on sorted arrays, it performs very badly (O(n^2)),
a linear sort would do a better job in that case. The sort method of Arrays is based
on a modified quicksort algorithm so that it doesn’t degrade for many datasets
that would cause a normal quicksort to do so.

The method sort is defined for arrays of type byte[], char[], double[], float[], int[],
long[], object[].

Following example demonstrates the use of sort:

import java.util.Arrays;
 
public class Main
{
   public static void main(String args[]) {
      int values[] = { 5, 74, 23, 99, 6, 0, -2, -60 };
 
      System.out.println("Unsorted array:");
      printArray(values);
 
      Arrays.sort(values);
 
      System.out.println("Sorted array:");
      printArray(values);
   }
 
   public static void printArray(int []values) {
      for (int i=0; i<values.length; i++) {
         System.out.print(values[i] + " ");
      }
      System.out.println();
      System.out.println();
   }
}

outputs:

Unsorted array:
5 74 23 99 6 0 -2 -60 
 
Sorted array:
-60 -2 0 5 6 23 74 99 

You can just as easily sort an array of user-defined objects. The only catch
is that you will have to define a comparator to tell the method whether object
A is less than, equal or bigger than object B.
Here’s an example:
RedColorComparator is introduced, a Comparator that only takes into account the red value of
the RGB value.

import java.util.Comparator;
import java.util.Arrays;
import java.awt.Color;
 
public class Main
{
   public static void main(String []args) {
      Color colArr[] = { new Color(43, 100, 100), new Color(170, 59, 255),
                         new Color(0, 0, 0),      new Color(220, 220, 220),
                         new Color(10, 255, 255), new Color(255, 0, 0) };
 
      System.out.println("Unsorted array:");
      printArray(colArr);
 
      Arrays.sort(colArr, new RedColorComparator());
 
      System.out.println("Sorted array:");
      printArray(colArr);
   }
 
   public static void printArray(Color colArr[]) {
      for (int i=0; i<colArr.length; i++) 
         System.out.println(colArr[i]);
      System.out.println();
   }
}
 
class RedColorComparator implements Comparator
{
   public int compare(Object o1, Object o2) {
      int red1 = ((Color) o1).getRed();
      int red2 = ((Color) o2).getRed();
      return (new Integer(red1)).compareTo(new Integer(red2));
   } 
}

outputs:

Unsorted array:
java.awt.Color[r=43,g=100,b=100]
java.awt.Color[r=170,g=59,b=255]
java.awt.Color[r=0,g=0,b=0]
java.awt.Color[r=220,g=220,b=220]
java.awt.Color[r=10,g=255,b=255]
java.awt.Color[r=255,g=0,b=0]
 
Sorted array:
java.awt.Color[r=0,g=0,b=0]
java.awt.Color[r=10,g=255,b=255]
java.awt.Color[r=43,g=100,b=100]
java.awt.Color[r=170,g=59,b=255]
java.awt.Color[r=220,g=220,b=220]
java.awt.Color[r=255,g=0,b=0]

Dynamically compile a Java source file and execute a method on it

You can use the package sun.tools.javac located in JDK/lib/tools.jar. Make sure you add this Jar file to your classpath!

When your invoke compile, you pass a String array containing the file to compile, and optionally also other compile options, eg. new String[] { “-classpath”, “c:mylibs”, “Test.java” }.

Main.java:

import java.lang.reflect.*;
import java.io.*;
 
public class Main
{
   public static void main(String []args) throws Exception {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
    
      sun.tools.javac.Main compiler = 
             new sun.tools.javac.Main(baos, "javac"); 
      boolean compileOk = compiler.compile(new String[] {"Test.java"}); 
 
      System.out.println("Compiled ok? " + compileOk);
 
      if (compileOk) {
         Class c = Class.forName("Test");
         // create a new instance of Test
         Object o = c.newInstance();
  
         // invoke a method on it
         Method m = c.getMethod("method", new Class[] { });
         m.invoke(o, new Object[] { });
      }
      else {
         System.out.println("Error compiling");
      }
   }
}

Test.java:

public class Test
{
   public void method() {
      System.out.println("Method in class Test executed!");
   }
}

Running Main outputs:

Compiled ok? true
Method in class Test executed!

Creating Java Threads

A thread allows you to do more things at once. It’s like a family sitting at the dinner table with in the middle one big pot of spaghetti (CPU). Every member of the family would be a thread and everybody gets its turn to eat some.

For Sun’s definition, check here: What is a thread?

There are several ways to create a thread. The following are a couple of examples that will each perform the same two tasks: 1) ask for first and last name of user with System.in 2) calculate the sum of all numbers from 1 to 123456789. While the program is waiting for input from the user, it is meanwhile performing the calculation.

Method 1

Extend from Thread class, define a public void run() method (the starting point of a thread) and call start on an instance of that class:

ThreadExample1.java:

import java.io.*;
 
public class ThreadExample1
{
   public static void main(String []args) {
      // create instance of thread1 and 2
      UserInputThread thread1   = new UserInputThread();
      CalculationThread thread2 = new CalculationThread();
 
      // start up the threads, start is defined in the
      // Thread class and the VM will call the run() method
      thread1.start();
      thread2.start();      
   }
}
 
// Thread 1: ask for user input
class UserInputThread extends Thread
{
   public void run() {
      try {
         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
         System.out.println("What is your first name?");
         String firstName = br.readLine();
         System.out.println("What is your last name?");
         String lastName  = br.readLine();
 
         System.out.println("Hi " + firstName + " " + lastName);
      }
      catch(IOException e) {
         e.printStackTrace();
      }
   }
}
 
// Thread 2: perform some calculation
class CalculationThread extends Thread
{
   public void run() {
      int n = 123456789;
      long total = 0;
      for (int i=1; i<n; i++) {
         total += i;
      }
      System.out.println("Total of summing up numbers from 1 to " + n + " = " + total);
   }
}

Method 2

Mark the class you want as a thread with the interface Runnable, define a public void run() method (the starting point of a thread), pass the Runnable class to a new instance of a Thread and call start on it:

ThreadExample2.java:

import java.io.*;
 
public class ThreadExample2
{
   public static void main(String []args) {
      // create an instance of each class, both implement
      // the interface Runnable 
      Runnable thread1 = new UserInputThread();
      Runnable thread2 = new CalculationThread();
 
      // create instances of Thread and pass the Runnable 
      // objects.  Starting up the threads will cause the
      // VM to call run()
      new Thread(thread1).start(); 
      new Thread(thread2).start();
   }
}
 
// Thread 1: ask for user input
class UserInputThread implements Runnable
{
   public void run() {
      try {
         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
         System.out.println("What is your first name?");
         String firstName = br.readLine();
         System.out.println("What is your last name?");
         String lastName  = br.readLine();
 
         System.out.println("Hi " + firstName + " " + lastName);
      }
      catch(IOException e) {
         e.printStackTrace();
      }
   }
}
 
// Thread 2: perform some calculation
class CalculationThread implements Runnable
{
   public void run() {
      int n = 123456789;
      long total = 0;
      for (int i=1; i<n; i++) {
         total += i;
      }
      System.out.println("Total of summing up numbers from 1 to " + n + " = " + total);
   }
}

Method 3

Compact, anonymous instance:

ThreadExample3.java:

import java.io.*;
 
public class ThreadExample3
{
   public static void main(String []args) {
      // create thread 1, override run() and start it
      new Thread() {
         public void run() {
            try {
               BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
               System.out.println("What is your first name?");
               String firstName = br.readLine();
               System.out.println("What is your last name?");
               String lastName  = br.readLine();
 
               System.out.println("Hi " + firstName + " " + lastName);
            }
            catch(IOException e) {
               e.printStackTrace();
            }
         }
      }.start();
 
      // create thread 2, override run() and start it
      new Thread() {
         public void run() {
            int n = 123456789;
            long total = 0;
            for (int i=1; i<n; i++) {
               total += i;
            }
            System.out.println("Total of summing up numbers from 1 to " + n + " = " + total);
         }
      }.start();
   }
}

Timeout on a network connection

If you didn’t know that there is a method available, you’d probably think of using a timer thread that closes the connection when it times out. There is an easier way to handle network timeouts. You can have better
control over your socket communications using socket options. And, to make developer’s life easy, there is this useful option called SO_TIMEOUT.

import java.net.*;
import java.io.*;
 
public class Main
{
   public static void main(String args[]) throws Exception {
      if (args.length != 3) {
         System.err.println("Usage: java Main <URL> <PORT> <TIMEOUT>");
         System.exit(1);
      }
  
      Socket s = new Socket(args[0], Integer.parseInt(args[1]));
 
      // set a timeout (in milliseconds)
      s.setSoTimeout(Integer.parseInt(args[2]));
 
      BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
      DataOutputStream dos = new DataOutputStream(s.getOutputStream());
 
      // get the homepage (/) by sending a GET command to the HTTP port
      dos.writeBytes("GET / HTTP/1.0rnrn");
 
      // read response, when timeout occurs, InterruptedIOException is thrown
      try {
         String line;
         while ((line = br.readLine()) != null) {
            System.out.println(line);
         }
      }
      catch(InterruptedIOException e) {
         System.out.println("Timed out after " + args[2] + " milliseconds.");
      }
      finally {
         br.close();
      }
   }
}

Now try to run it with different values for timeout:

C:> java Main www.yahoo.com 80 10
Timed out after 10 milliseconds.
 
C:> java Main www.esus.com 80 1000
 
[snip: yahoo home]