How long has the VM been running

In JDK 1.5, use the RuntimeMBean management class in the java.lang.management package.

Main.java:

import java.lang.management.*;
import java.util.*;
 
public class Main
{
   public static void main(String []args) {
      RuntimeMBean mbean = ManagementFactory.getRuntimeMBean();
      while (true) {
         long uptime = mbean.getUptime();
          
         System.out.println("VM has been running for " + uptime + " ms.");
         try { Thread.sleep(1500); } catch(Exception e) { }
      }
   }
}

outputs:

VM has been running for 50 ms.
VM has been running for 1552 ms.
VM has been running for 3054 ms.
VM has been running for 4557 ms.
VM has been running for 6059 ms.
. . .

Getting the state of a thread (running, blocked, etc)

This becomes very simple with the new java.lang.management package in JDK 1.5. The following example starts up a Task thread and a Monitor Thread. The Monitor thread prints out the state of the Task thread every half a second. All possible thread states are documented in the API docs.

Main.java:

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMBean;
import java.lang.management.ThreadState;
 
public class Main
{
   public static void main(String []args) {
      final Task t1 = new Task();
       
      t1.setName("Task Thread");
      t1.start();
       
      Thread monitorThread = new Thread() {
         public void run() {
            ThreadMBean mbean = ManagementFactory.getThreadMBean();
            ThreadInfo threadInfo1 = mbean.getThreadInfo(t1.getId());
 
            System.out.println("tMonitoring " + t1.getName() + " for 10 secondsn");
            System.out.println("tcountertstatettTotal CPU Time"); 
            for (int i=0; i<20; i++) {
               threadInfo1 = mbean.getThreadInfo(t1.getId());
               System.out.println("t" + t1.getCounter() + "t" + threadInfo1.getThreadState() + "  t" + 
                                  (mbean.getThreadCpuTime(t1.getId()) / 1000000) + " ms");
               
               try { Thread.sleep(500); } catch(Exception e) { }
            }
             
            t1.terminate();
         }
      };
       
      monitorThread.start();
   }
}
 
class Task extends Thread
{
   long counter = 0;
   private boolean terminated = false;
 
   public void run() {
      while (true) {
         if (terminated) return;
         
         counter++;
         for (int i=0; i<50000000; i++) { }
         try { Thread.sleep(100); } catch(Exception e) { }
      }
   } 
    
   public long getCounter() {
      return counter;
   }
    
   public void terminate() {
      terminated = true;
   }
}

outputs:

        Monitoring Task Thread for 10 seconds
 
        counter state           Total CPU Time
        1       Running         110 ms
        3       Sleeping        360 ms
        5       Sleeping        610 ms
        8       Running         911 ms
        10      Running         1211 ms
        12      Sleeping        1472 ms
        14      Sleeping        1712 ms
        17      Running         2012 ms
        19      Running         2313 ms
        21      Sleeping        2573 ms
        23      Sleeping        2824 ms
        26      Running         3104 ms
        28      Sleeping        3424 ms
        30      Sleeping        3675 ms
        33      Running         3965 ms
        35      Running         4266 ms
        37      Sleeping        4536 ms
        39      Sleeping        4786 ms
        42      Running         5087 ms
        44      Running         5387 ms

Getting the parameters passed to the VM at runtime

With the new java.lang.management package in JDK 1.5, this becomes very simple now.

Main.java:

import java.lang.management.*;
import java.util.*;
 
public class Main
{
   public static void main(String []args) {
      RuntimeMBean mbean = ManagementFactory.getRuntimeMBean();
      List list = mbean.getInputArguments();
       
      Iterator iter = list.iterator();
      while (iter.hasNext()) {
         String s = (String) iter.next();
         System.out.println(s);
      }
   }
}

For example, run it with

java -Xmx200M -Xrs Main

outputs:

-Xmx200M
-Xrs

Detecting a deadlock with ThreadMBean in JDK 1.5

This example shows how to use the ThreadMBean class in JDK 1.5 to detect a deadlock. ThreadMBean is a management class (package java.lang.management) that provides functionality to query the thread system of the JVM.

The example creates three threads A, B and C which end up in a deadly embrace: A waits for a lock that B holds, B waits for a lock that C holds and C waits for a lock that A holds. The method findMonitorDeadlockedThreads returns the list of Thread ids involved in the deadlock.

FindDeadlock.java:

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMBean;
import java.lang.management.ThreadState;
 
public class FindDeadlock
{
   Object a = new Object();
   Object b = new Object();
   Object c = new Object();
   
   public static void main(String []args) {
      final FindDeadlock fd = new FindDeadlock();
   
      Thread t1 = new Thread() {
         public void run() {
            while (true) { fd.m1(); }
         }
      };
      
      Thread t2 = new Thread() {
         public void run() {
            while (true) { fd.m2(); }
         }
      };
      
      Thread t3 = new Thread() {
         public void run() {
            while (true) { fd.m3(); }
         }
      };      
      
      t1.setName("First thread");
      t2.setName("Second thread");
      t3.setName("Third thread");
      
      t1.start();
      t2.start();
      t3.start();
      
      // give the time for the threads to go into a deadlock
      try { Thread.sleep(1000); } catch(Exception e) { } 
      
      ThreadMBean mbean = ManagementFactory.getThreadMBean();
      long[] threads = mbean.findMonitorDeadlockedThreads();
      if (threads != null) {
         for (int i=0; i<threads.length; i++) { 
            ThreadInfo threadInfo = mbean.getThreadInfo(threads[i]);
            ThreadState threadState = mbean.getThreadState(threads[i]);
            
            System.out.print(threadInfo.getThreadName() + "(" + threadState + ") is waiting for ");
            System.out.print(threadInfo.getLockOwnerName() + " to release ");
            System.out.println("the lock " + threadInfo.getLockName());
         }
      }
   }
   
   public void m1() {
      synchronized(a) {
         try { Thread.sleep(100); } catch(Exception e) { }
         synchronized(b) {
            System.out.println("m1 got through");
         }
      }
   }
   
   public void m2() {
      synchronized(b) {
         try { Thread.sleep(100); } catch(Exception e) { }
         synchronized(c) {
            System.out.println("m2 got through");
         }
      }
   }
   
   public void m3() {
      synchronized(c) {
         try { Thread.sleep(100); } catch(Exception e) { }
         synchronized(a) {
            System.out.println("m3 got through");
         }
      }
   }   
}

outputs:

Third thread(Blocked) is waiting for First thread to release the lock java.lang.Object@d9f9c3
First thread(Blocked) is waiting for Second thread to release the lock java.lang.Object@1a46e30
Second thread(Blocked) is waiting for Third thread to release the lock java.lang.Object@3e25a5

Creating a JComboBox that doesn’t close when I click one of its JCheckBox items

Main.java:

import javax.swing.*;
import java.awt.*;
import java.util.*;
 
public class Main extends JFrame
{
   public Main() {
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       
      getContentPane().setLayout(new FlowLayout());
       
      Vector v = new Vector();
      v.add("Europe");
      v.add(new JCheckBox("Brussels", false));
      v.add(new JCheckBox("Paris", false));
      v.add(new JCheckBox("London", false));
      v.add("United States");
      v.add(new JCheckBox("New York", false));
      v.add(new JCheckBox("Detroit", false));
      v.add(new JCheckBox("San Francisco", false));
 
      getContentPane().add(new JComboCheckBox(v));
   }
    
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(300, 300);
      main.setVisible(true);
   }
}

JComboCheckBox.java:

import javax.swing.*;
import java.awt.event.*;
 
import javax.swing.plaf.ComboBoxUI;
import javax.swing.plaf.basic.*;
import javax.swing.plaf.metal.MetalComboBoxUI;
 
import com.sun.java.swing.plaf.motif.MotifComboBoxUI;
import com.sun.java.swing.plaf.windows.WindowsComboBoxUI;
 
import java.awt.*;
import java.util.*;
 
public class JComboCheckBox extends JComboBox 
{
   public JComboCheckBox() { 
      init(); 
   }
    
   public JComboCheckBox(JCheckBox[] items) { 
      super(items); 
      init(); 
   }
    
   public JComboCheckBox(Vector items) { 
      super(items); 
      init(); 
   }
    
   public JComboCheckBox(ComboBoxModel aModel) { 
      super(aModel); 
      init(); 
   }
    
   public void updateUI() {
      ComboBoxUI cui = (ComboBoxUI) UIManager.getUI(this);
      if (cui instanceof MetalComboBoxUI) {
         cui = new MetalNoCloseComboBoxUI();
      } else if (cui instanceof MotifComboBoxUI) {
         cui = new MotifNoCloseComboBoxUI();       
      } else if (cui instanceof WindowsComboBoxUI) {
         cui = new WindowsNoCloseComboBoxUI();
      }
       
      setUI(cui);
   }
    
   class MetalNoCloseComboBoxUI extends MetalComboBoxUI {
      protected ComboPopup createPopup() {
         return new NoCloseBasicComboPopup(comboBox);
      }
   }
 
   class WindowsNoCloseComboBoxUI extends WindowsComboBoxUI {
      protected ComboPopup createPopup() {
         return new NoCloseBasicComboPopup(comboBox);
      }
   }
 
   class MotifNoCloseComboBoxUI extends MotifComboBoxUI {
      protected ComboPopup createPopup() {
         return new NoCloseBasicComboPopup(comboBox);
      }
   }
    
   private void init() {
      setRenderer(new ComboBoxRenderer());
      addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) { 
            itemSelected(); 
         }
      });
   }
 
   private void itemSelected() {
      if (getSelectedItem() instanceof JCheckBox) {
         JCheckBox jcb = (JCheckBox)getSelectedItem();
         jcb.setSelected(!jcb.isSelected());
         repaint();
      }
   }
 
   class ComboBoxRenderer implements ListCellRenderer {
      private JLabel label;
      
      public ComboBoxRenderer() { 
         setOpaque(true); 
      }
      
      public Component getListCellRendererComponent(JList list, Object value, int index, 
                                                    boolean isSelected, boolean cellHasFocus) {
         if (value instanceof JCheckBox) {
            list.repaint();
         }
         if (value instanceof Component) {
            Component c = (Component)value;
            if (isSelected) {
               c.setBackground(list.getSelectionBackground());
               c.setForeground(list.getSelectionForeground());
            } else {
               c.setBackground(list.getBackground());
               c.setForeground(list.getForeground());
            }
            
            return c;
         } else {
            if (label==null) {
               label = new JLabel(value.toString());
            }
            else {
               label.setText(value.toString()); 
            }
            
            return label;
         }
      }
   }
 
   class NoCloseBasicComboPopup extends BasicComboPopup
   {
      public NoCloseBasicComboPopup(JComboBox combo) {
         super(combo);         
      }
   
      protected MouseListener createListMouseListener() {
         return new ListMouseHandler();
      }
   
      protected class ListMouseHandler extends MouseAdapter {
         public void mousePressed(MouseEvent e) {
         }
      
         public void mouseReleased(MouseEvent anEvent) {
            comboBox.setSelectedIndex(list.getSelectedIndex());
            Object o = list.getSelectedValue();
            if (! (o instanceof JCheckBox)) {
               hide();
            }
         }
      }   
   }   
}

Putting a JCheckbox in a JComboBox

Here’s a working example:

Main.java:

import javax.swing.*;
import java.awt.*;
import java.util.*;
 
public class Main extends JFrame
{
   public Main() {
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       
      getContentPane().setLayout(new FlowLayout());
       
      Vector v = new Vector();
      v.add("Europe");
      v.add(new JCheckBox("Brussels", false));
      v.add(new JCheckBox("Paris", false));
      v.add(new JCheckBox("London", false));
      v.add("United States");
      v.add(new JCheckBox("New York", false));
      v.add(new JCheckBox("Detroit", false));
      v.add(new JCheckBox("San Francisco", false));
 
      getContentPane().add(new JComboCheckBox(v));
   }
    
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(300, 300);
      main.setVisible(true);
   }
}

JComboCheckBox.java:

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
 
public class JComboCheckBox extends JComboBox 
{
   public JComboCheckBox() { 
      init(); 
   }
   
   public JComboCheckBox(JCheckBox[] items) { 
      super(items); 
      init(); 
   }
   
   public JComboCheckBox(Vector items) { 
      super(items); 
      init(); 
   }
   
   public JComboCheckBox(ComboBoxModel aModel) { 
      super(aModel); 
      init(); 
   }
   
   private void init() {
      setRenderer(new ComboBoxRenderer());
      addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) { 
            itemSelected(); 
         }
      });
   }
 
   private void itemSelected() {
      if (getSelectedItem() instanceof JCheckBox) {
         JCheckBox jcb = (JCheckBox)getSelectedItem();
         jcb.setSelected(!jcb.isSelected());
      }
   }
 
   class ComboBoxRenderer implements ListCellRenderer {
      private JLabel label;
      
      public ComboBoxRenderer() { 
         setOpaque(true); 
      }
      
      public Component getListCellRendererComponent(JList list, Object value, int index, 
                                                    boolean isSelected, boolean cellHasFocus) {
         if (value instanceof Component) {
            Component c = (Component)value;
            if (isSelected) {
               c.setBackground(list.getSelectionBackground());
               c.setForeground(list.getSelectionForeground());
            } else {
               c.setBackground(list.getBackground());
               c.setForeground(list.getForeground());
            }
             
            return c;
         } else {
            if (label ==null) {
               label = new JLabel(value.toString());
            }
            else {
               label.setText(value.toString());
            }
               
            return label;
         }
      }
   }
}

Converting a ByteArrayInputStream to a ReadableByteChannel

Main.java:

import java.nio.channels.*;
import java.nio.*;
import java.io.*;
 
public class Main
{
   public static void main(String []args) throws Exception {
      byte[] buffer = "contents of the buffer".getBytes();
      ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
 
      ReadableByteChannel byteChannel = Channels.newChannel(bais);   
      ByteBuffer bb = ByteBuffer.allocate(10);
      
      int n;
      while ((n = byteChannel.read(bb)) > -1) {
         bb.rewind();
         
         for (int i=0; i<n; i++) {
            System.out.print((char) bb.get());
         }
      }
   }
}

Using the classes CacheRequest and CacheResponse

JDK 1.5 provides a framework into which an caching implementation can be plugged. A standard protocol handler can use the ResponseCache class to get documents from the cache. For example, if the flag useCaches is set on a URLConnection (true by default), an attempt is made to fetch the content from the cache, implementation specified by ResponseCache.

Here’s an example with implementations of ResponseCache, CacheResponse and CacheRequest:

Main.java:

import java.net.*;
import java.io.*;
import java.nio.channels.*;
import java.util.*;

public class Main
{
   public static void main(String []args) throws Exception {
      if (args.length != 1) {
         System.err.println("Usage: java Main <URL>");
         System.exit(0);
      }

      ResponseCache.setDefault(new MyResponseCache());

      // download first time
      System.out.println("Downloading " + args[0] + " a first time");
      String doc = download(args[0]);
      
      System.out.println("nnDownloading " + args[0] + " a second time");
      // download second time (automatically from cache!)
      doc = download(args[0]);
   }
   
   public static String download(String urlString) throws Exception {          
      URL url = new URL(urlString);
      URLConnection connection = url.openConnection();
 
      connection.setConnectTimeout(5000);
      connection.connect();

      BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
      String lineSeparator = System.getProperty("line.separator");
      StringBuffer sb = new StringBuffer();
      String line;
      while ((line = br.readLine()) != null) {
         sb.append(line);
         sb.append(lineSeparator);
      }
      
      return sb.toString();
   }
}

class MyResponseCache extends ResponseCache
{
   public CacheResponse get(URI uri, String requestMethod, Map<String,List<String>> requestHeaders) {
      String cacheFilename = createCacheFilename(uri);
      if (!new File(cacheFilename).exists()) {
         System.out.println(""+uri + " does not exist in cache.");
         return null;
      }
      
      System.out.println("Retrieving " + uri + " from cache.");
      return new MyCacheResponse(createCacheFilename(uri));
   }
   
   public CacheRequest put(URI uri, URLConnection conn) {  
      System.out.println("Storing " + uri + " in cache.");    
      return new MyCacheRequest(createCacheFilename(uri));      
   }
   
   private String createCacheFilename(URI uri) {
      String suri = uri.toString();
      
      String notAllowed = "\/:*?"<>|";
      StringBuffer result = new StringBuffer();
      for (int i=0; i<suri.toString().length(); i++) {
         if (notAllowed.indexOf(suri.charAt(i)) == -1) {
            result.append(suri.charAt(i));
         }
      }
      return result.toString();   
   }
}

class MyCacheResponse extends CacheResponse
{
   private String filename;

   public MyCacheResponse(String filename) {
      this.filename = filename;
   }

   public Map<String, List<String>> getHeaders() throws IOException {
      return new HashMap<String, List<String>>();
   }

   public ReadableByteChannel getBody() throws IOException {
      return Channels.newChannel(new BufferedInputStream(new FileInputStream(filename)));
   }
}

class MyCacheRequest extends CacheRequest
{
   private String filename;
     
   public MyCacheRequest(String filename) {
      this.filename = filename;
   }
   
   public WritableByteChannel getBody() throws IOException {
      return Channels.newChannel(new BufferedOutputStream(new FileOutputStream(filename)));
   }
   
   public void abort() {
   }
}

Using a ProxySelector

Here’s a working example that says everything. MyProxySelector is automatically contacted when URLConnection is about to make a connection.

Main.java:

import java.net.*;
import java.io.*;
import java.util.*;

public class Main
{
   public static void main(String []args) throws Exception {
      if (args.length != 1) {
         System.err.println("Usage: java Main <URL>");
         System.exit(0);
      }
      
      System.out.println("Old ProxySelector: " + ProxySelector.getDefault());
      ProxySelector.setDefault(new MyProxySelector());
      System.out.println("New ProxySelector: " + ProxySelector.getDefault());
          
      URL url = new URL(args[0]);
      URLConnection connection = url.openConnection();
 
      connection.setConnectTimeout(5000);
      connection.connect();
   }
}

class MyProxySelector extends ProxySelector
{
   public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
      System.out.println("connectFailed: " + ioe.getMessage());
   }
   
   public List<Proxy> select(URI uri) {
      ArrayList<Proxy> list = new ArrayList<Proxy>();
      Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy.esus.com", 8080));
      list.add(proxy);

      return list;
   }
}

Setting the a connect timeout on an URLConnection

JDK1.5 allows you to set connect and read timeouts on URLConnection (HttpURLConnection, etc.).

Here is an example:

Main.java:

import java.net.*;

public class Main
{
   public static void main(String []args) throws Exception {
      if (args.length != 1) {
         System.err.println("Usage: java Main <URL>");
         System.exit(0);
      }
          
      URL url = new URL(args[0]);
      URLConnection connection = url.openConnection();
 
      connection.setConnectTimeout(5000);
      connection.connect();
   }
}