Get a private key from a keystore

This example extracts a private key from a keystore and prints it out in PEM format.

Main.java:

import sun.misc.BASE64Encoder;
import java.security.cert.Certificate;
import java.security.*;
import java.io.File;
import java.io.FileInputStream;
 
class Main {
   public static void main(String args[]) throws Exception{
      if (args.length != 3) {
         System.out.println("Extracts private key in PEM format from a JKS keystore");
         System.out.println("Usage: java Main <keystore> <alias> <passphrase>");
         System.exit(1);
      }
 
      String keystore = args[0];
      String alias = args[1];
      String password = args[2];      
 
      KeyStore ks = KeyStore.getInstance("JKS");
      char[] passphrase = password.toCharArray();
      BASE64Encoder base64Encoder = new BASE64Encoder();
 
      ks.load(new FileInputStream(keystore), passphrase);
 
      PrivateKey privateKey = getPrivateKey(ks, alias, passphrase);
 
      String sPrivateKey = base64Encoder.encode(privateKey.getEncoded());
 
      System.out.println("-----BEGIN PRIVATE KEY-----");
      System.out.println(sPrivateKey);
      System.out.println("-----END PRIVATE KEY-----");
   }
 
   public static PrivateKey getPrivateKey(KeyStore keystore, String alias, char[] password) {
      try {
         Key key = keystore.getKey(alias, password);
         if (key instanceof PrivateKey) {
            Certificate cert = keystore.getCertificate(alias);
            PublicKey publicKey = cert.getPublicKey();
 
            KeyPair kp = new KeyPair(publicKey, (PrivateKey)key);
 
            return kp.getPrivate();
         }
      } catch (UnrecoverableKeyException e) {
         e.printStackTrace();
      } catch (NoSuchAlgorithmException e) {
         e.printStackTrace();
      } catch (KeyStoreException e) {
         e.printStackTrace();
      }
 
      return null;
   }
}

Pinging a host in JDK1.5

JDK1.5 provides the functionality to test the reachability of a host. Before JDK 1.5, you had to implement this yourself (for example by sending UDP packets to the echo port (7) of the target machine).

Actually, the strategy of the implementation of isReachable is to try to use ICMP if it is available, or else to try to connect to the echo port.

This example shows you how the test the reachability of a host:

import java.net.*;

public class Main
{
   public static void main(String []args) throws Exception {
      if (args.length != 1) {
         System.out.println("Usage: java Main <host or ipaddress>");
         System.exit(1);
      }
      
      InetAddress inetAddress = InetAddress.getByName(args[0]);
      System.out.println(inetAddress);
      
      System.out.println(args[0] + " is reachable? " + inetAddress.isReachable(5000));
   }  
}

Using the ClassFileTransformer in JDK 1.5

The package java.lang.instrument allows you to modify class classfiles as they are loaded. On the command line, you register your own implementation of the ClassFileTransformer and this will be called by the VM every time a class is loaded.

On this page, you’ll find a working example of a ClassFileTransformer that will add a log statement to every method of every class that is about to be loaded. To perform the bytecode manipulation, I used the well-known Jakarta BCEL library.

Two related Q&A’s to achieve this kind of functionality are
How do I get started with writing a dynamic proxy class?
How do I get started with AspectJ?

MethodInstrument.java:

import java.lang.instrument.Instrumentation;
import java.security.*;
  
import org.apache.bcel.Constants;
import org.apache.bcel.Repository;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.InstructionConstants;
import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.MethodGen;
import org.apache.bcel.generic.ObjectType;
import org.apache.bcel.generic.PUSH;
import org.apache.bcel.generic.Type;
 
import java.io.*;
import java.lang.reflect.*;
 
public class MethodInstrument 
{
   public static void premain(String options, Instrumentation instrumentation) {
      instrumentation.addTransformer(new EntryExitMethodTransformer());
   }
   
   public static class EntryExitMethodTransformer implements ClassFileTransformer 
   {
      public byte[] transform(ClassLoader loader, String cn, Class classBeingRedefined, 
                              ProtectionDomain protectionDomain, byte[] classfileBuffer) 
                                  throws IllegalClassFormatException
      {
         //System.out.println("Transforming class " + cn);
         if (cn.startsWith("java") || cn.startsWith("javax") || cn.startsWith("sun")) {
            return classfileBuffer;
         }
         try {
            ByteArrayInputStream bais = new ByteArrayInputStream(classfileBuffer);
             
            ClassParser parser = new ClassParser(bais, cn);
            JavaClass clazz = parser.parse();
        
            ClassGen classGen = new ClassGen(clazz);
        
            Method[] methods = clazz.getMethods();
            for (int i=0; i<methods.length; i++) {
               InstructionFactory instructionFactory = new InstructionFactory(classGen);
               InstructionList instructionList = new InstructionList();
               ConstantPoolGen constantPoolGen = classGen.getConstantPool();
               String className = classGen.getClassName();            
  
               Method method = methods[i];
               MethodGen wrapGen = new MethodGen(method, className, constantPoolGen);
               instructionList = wrapGen.getInstructionList();
                
               String text = "Call to method " + cn + "." + method.getName();
               instructionList.insert(instructionFactory.createInvoke(
                        "java.io.PrintStream", "println"
                        , Type.VOID, new Type[] { Type.STRING }
                        , Constants.INVOKEVIRTUAL
                      ));
               instructionList.insert(new PUSH(constantPoolGen, text));
               instructionList.insert(instructionFactory.createFieldAccess(
                        "java.lang.System", "out", new ObjectType("java.io.PrintStream")
                        , Constants.GETSTATIC
                      ));
   
               wrapGen.stripAttributes(true);
               wrapGen.setMaxStack();
               wrapGen.setMaxLocals();
      
               classGen.removeMethod(method);
               classGen.addMethod(wrapGen.getMethod());
            }
    
            return classGen.getJavaClass().getBytes();
         }
         catch(Exception e) {
            throw new IllegalClassFormatException(e.getMessage());
         }
      }
   }
}

Be sure to include the BCEL library in your classpath (eg. bcel-5.1.jar).

A simple program to test our EntryMethodTransformer:

Test.java:

public class Test
{
   public static void main(String []args) {
      a();
   }
   
   public static void a() {
      b();
   }
   
   public static void b() {
      c();
   }
   
   public static void c() {
      System.out.println("C reached!");
   }
}

Now run Test, but provide the MethodInstrument agent on the command line:

java -javaagent:MethodInstrument Test

outputs:

Call to method Test.main
Call to method Test.a
Call to method Test.b
Call to method Test.c
C reached!

Error message “Bad Magic Number”

Each class file starts with special 4 bytes equal to the hexadecimal value of 0xCAFEBABE – this number identifies the class file format and is humorously named “Magic Number”. When you get an error from the JVM saying “Bad Magic Number”, it simply means the class file it is trying to load is corrupt.

The solution is usually to recompile all your classes.

Drawing a rotated image

Work directly on the class Graphics2D or use the class AffineTransform that allows you to create your own transformation matrixes.

Directly on Graphics2D

Main.java:

import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame {
   private Image image;
   private boolean firstTime = true;
   private int degrees = 0;
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      image = Toolkit.getDefaultToolkit().getImage("c:\djkrush.jpg");
      waitForImage(image);
 
      getContentPane().setLayout(new BorderLayout());
      JButton button = new JButton("rotate by 10 degrees");
      button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            degrees += 10;
            repaint();
         }
      });
 
      getContentPane().add(BorderLayout.SOUTH, button);
   }
 
   public void paint(Graphics g) {
      super.paint(g);
 
      Graphics2D g2d = (Graphics2D) g;
 
      double radians = degrees * (Math.PI / 180);
      g2d.translate(getSize().width/2, getSize().height/2);
      g2d.rotate(radians); 
      g2d.drawImage(image, 0, 0, this);
   }
 
   public void waitForImage(Image image) {
      MediaTracker mt = new MediaTracker(this);
 
      int id = 0;
      mt.addImage(image, id);
 
      try {
         mt.waitForID(id);
      }
      catch(InterruptedException e) {
         System.out.println("Image loading interrupted : " + e);
      }
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(400, 400);
      main.setVisible(true);
   }
}

Using AffineTransform

Main.java:

import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame {
   private Image image;
   private boolean firstTime = true;
   private int degrees = 0;
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      image = Toolkit.getDefaultToolkit().getImage("c:\djkrush.jpg");
      waitForImage(image);
 
      getContentPane().setLayout(new BorderLayout());
      JButton button = new JButton("rotate by 10 degrees");
      button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            degrees += 10;
            repaint();
         }
      });
 
      getContentPane().add(BorderLayout.SOUTH, button);
   }
 
   public void paint(Graphics g) {
      super.paint(g);
 
      if (degrees == 0) {
         g.drawImage(image, getSize().width/2, getSize().height/2, this);
      }
      else {  
         Graphics2D g2d = (Graphics2D) g;
 
         double radians = degrees * (Math.PI / 180);
         AffineTransform at = new AffineTransform();
         at.translate(getSize().width/2, getSize().height/2);
         at.rotate(radians);
         g2d.drawImage(image, at, this);
      }
   }
 
   public void waitForImage(Image image) {
      MediaTracker mt = new MediaTracker(this);
 
      int id = 0;
      mt.addImage(image, id);
 
      try {
         mt.waitForID(id);
      }
      catch(InterruptedException e) {
         System.out.println("Image loading interrupted : " + e);
      }
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(400, 400);
      main.setVisible(true);
   }
}

image used:

Customizing serialization with Externalizable

With serialization, you can save the current state of an object to a stream and restore it back at a later point in time. With typical serialization, the fields are written using a default mechanism that specifies, for example, the order in which the fields are written. With making an object Externalizable and implementing the methods writeExternal and readExternal, you can do the serialization and restoration of the object yourself, including version checks.

The following example shows you how to customize serialization through the readExternal and writeExternal methods. It creates an object of type Test that contains a String and an integer array. It will only serialize the odd indexes of this array.

Main.java:

import java.io.*;
 
public class Main {
   public static void main(String args[]) {
      try {
         Test t = new Test("esus", new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
         System.out.println("Serialize this object:");
         System.out.println(t);
 
         // create byte buffer containing serialized version of t 
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ObjectOutputStream oos = new ObjectOutputStream(baos);
         t.writeExternal(oos);
         // very important to flush the stream, or you'll get java.io.EOFException
         oos.flush();            
         byte[] buffer = baos.toByteArray(); 
 
         Test t2 = new Test();
         ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(buffer));
         t2.readExternal(ois);      
      
         System.out.println("nDeserialization result:"); 
         System.out.println(t2);
      }
      catch(ClassNotFoundException e) { 
         System.out.println(e);
      }
      catch(IOException e) { 
         System.out.println(e);
      }
   }
}
 
class Test implements Externalizable {
   String s;
   int[] array;
  
   Test() { }
   Test(String s, int[] array) {
      this.s = s;
      this.array = array;
   }
 
   public void writeExternal(ObjectOutput out) throws IOException {
      out.writeObject(s);
      out.writeInt(array.length);
      for (int i=0; i<array.length; i+=2) {
         out.writeInt(i);
         out.writeInt(array[i]);
      }
   }
 
   public void readExternal(ObjectInput in) throws IOException, 
                                                   ClassNotFoundException {
      s = (String) in.readObject();
      int len = in.readInt();
      array = new int[len];
      for (int i=0; i<len/2; i++) {
         int index = in.readInt();
         array[index] = in.readInt();
      }
   }
 
   public String toString() {
      String total = "s = " + s + "; array = ";
      for (int i=0; i<array.length; i++) {
         total += array[i] + " ";
      }
      return total;
   }
}

outputs:

Serialize this object:
s = esus; array = 1 2 3 4 5 6 7 8 9 10
 
Deserialization result:
s = esus; array = 1 0 3 0 5 0 7 0 9 0 

How do I read from standard input?

Standard input (stdin) is represented by System.in. System.in is an instance of the class java.io.InputStream. This means that all its methods work on bytes, not Strings.
To read from keyboard, use the Reader classes provided since JDK 1.1 They provide unicode manipulation.
Following is an example that reads in 2 Strings from stdin, converts them to integers and displays the multiplication of the two.

import java.io.*; 
 
public class Multiply { 
 
   public static void main (String[] args) { 
      int firstNum, secondNum, result;
 
      //  open up standard input 
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
 
      try { 
         System.out.print("Enter first number: "); 
         firstNum = Integer.parseInt(br.readLine());
         System.out.print("Enter second number: "); 
         secondNum = Integer.parseInt(br.readLine());
         result = firstNum * secondNum;
 
         System.out.println("The multiplication is " + result); 
      } catch (IOException e) { 
         System.out.println(e);
      } 
   } 
}  

Writing a String to a file

Typically, Create an instance of FileWriter (specify the filename) and wrap it up in a BufferedWriter.

Main.java:

import java.io.*;
 
public class Main {
   public static void main(String args[]) {
      String s = "First line" + System.getProperty("line.separator");
      s += "Second line";
 
      try {
         BufferedWriter bw = new BufferedWriter(new FileWriter("test.txt"));
         bw.write(s);
         bw.close();
      } catch(IOException e) {
         System.err.println(e);
      }
   }
}

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