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!

Waiting for an image to be loaded

Using javax.swing.ImageIcon

Main.java:

import javax.swing.*;
import java.awt.*;
import java.net.*;
 
public class Main extends JFrame {
   public static void main(String []args) throws Exception {
      Main main = new Main();
      main.loadImage(new URL("http://www.esus.com/images/space.jpg"));
      System.exit(0);
   }
 
   public Image loadImage(URL url) throws Exception {
      System.out.print("Loading image... ");   
      Image image = new javax.swing.ImageIcon(url).getImage(); 
      System.out.println("done!");
      return image;
   }
}

Using MediaTracker

Main.java:

import javax.swing.*;
import java.awt.*;
import java.net.*;
 
public class Main extends JFrame {
   public static void main(String []args) throws Exception {
      Main main = new Main();
      main.loadImage(new URL("http://www.esus.com/images/space.jpg"));
      System.exit(0);
   }
 
   public Image loadImage(URL url) throws Exception {
      MediaTracker mt = new MediaTracker(this);
 
      Image image = Toolkit.getDefaultToolkit().getImage(url);
  
      // add image to MediaTracker registry and give it an ID
      mt.addImage(image, 1); 
 
      System.out.print("Loading image... "); 
      // wait for that ID to be completed
      boolean status = false;
      try { 
         mt.waitForID(1); 
         
         status = mt.checkID(1, true); 
      } 
      catch (InterruptedException e) { }
      System.out.println("done! (status = " + status + ")");
 
      return image;
   }
}

Tracking the progress of reading from an InputStream

You can use the class ProgressMonitorInputStream as described
on Sun’s page How to Monitor Progress.

Main.java:

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import java.io.*; 
 
public class Main extends JFrame implements ActionListener {
   JTextField fileTextField;
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      }); 
       
      JPanel panel = new JPanel();
      panel.setLayout(new FlowLayout(FlowLayout.LEFT));
      panel.add(new JLabel("File:"));
      fileTextField = new JTextField(20);
      panel.add(fileTextField);
      JButton loadButton = new JButton("Load!");
      panel.add(loadButton);
      loadButton.addActionListener(this);
 
      fileTextField.setText("c:\jdk1.2.2\lib\tools.jar");
 
      getContentPane().setLayout(new BorderLayout());
      getContentPane().add(BorderLayout.NORTH, panel);
      pack();
   } 
 
   public void actionPerformed(ActionEvent ae) {
      FileLoader worker = new FileLoader(this, fileTextField.getText());
      worker.start();
   }
 
   class FileLoader extends Thread {
      Component parentComponent;
      String fileName; 
      ProgressMonitor progressMonitor;
 
      public FileLoader(Component parentComponent, String fileName) {
         this.parentComponent = parentComponent;
         this.fileName = fileName;
      }
 
      public void run() {
         try {
            ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(
                                                parentComponent,
                                                "Reading " + fileName,
                                                new FileInputStream(fileName));
            progressMonitor = pmis.getProgressMonitor();
            BufferedInputStream bis = new BufferedInputStream(pmis);
            
            byte b[] = new byte[1024];
            int bytes = bis.read(b, 0, b.length);
            while (bytes > 0) {
               try {
                  Thread.sleep(10);
               }
               catch(InterruptedException e) { } 
               bytes = bis.read(b, 0, b.length);
            }
 
            System.out.println("Loaded!");
         }
         catch(InterruptedIOException e) {
            if (progressMonitor.isCanceled()) {
               System.out.println("Loading of " + fileName + " has been cancelled!");
            }
            else {
               System.out.println(e);
            }
         }
         catch(IOException e) {
            System.out.println(e);
         }
      }
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setVisible(true);
      main.setSize(350, 150);
   }
}

Making a file read-only

Use the method setReadOnly in the File class. Notice that there is no method to determine whether a file is read-only or not, neither is there a method to undo the setReadOnly operation:

Main.java:

import java.io.*;
   
public class Main {
   public static void main(String[] args) {
      File file = new File("Main.java");
      boolean status = file.setReadOnly(); 
      System.out.println(file + " " + (status ? "":"un") + "successfully set to read-only");
   }
}

When you execute (Windows DOS-prompt) attrib main.java, you’ll see:

  A    R     MAIN~1.JAV    C:Main.java

Reading a specific region of an image file with the ImageIO APIs

With the class ImageReadParam, you have control over the decoding of the image and the region. Specify the region with a Rectangle instance and pass this to the ImageReadParam instance with setSourceRegion. Then, when you execute BufferedImage bi = reader.read(imageindex, param), the resulting BufferedImage will only contain that region. (imageindex specifies the number of the image in the image file, possible in some image formats).

It is especially useful for handling large images.

In the following example, a large image is selected as the ImageInputStream. Every 10ms, a region as small as the size of the JFrame is read, and only that region. At every step, a new window region is selected; it moves about horizontally and vertically.

Main.java:

import javax.imageio.stream.*;
import javax.swing.event.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.imageio.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
import java.io.*;
  
public class Main extends JFrame implements Runnable
{
   BufferedImage background;
   ImageReader reader;
   ImageReadParam param;
   int imageWidth, imageHeight;
   int currentx, currenty, dx, dy;
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      setResizable(false);
   }
   
   public void initImageReading() throws Exception {
      Iterator readers = ImageIO.getImageReadersByFormatName("jpg");
      reader = (ImageReader)readers.next();
 
      ImageInputStream iis = ImageIO.createImageInputStream(new File("autumn16.jpg"));
      reader.setInput(iis, true);
      param = reader.getDefaultReadParam();
 
      imageWidth = reader.getWidth(0);
      imageHeight = reader.getHeight(0);
 
      Rectangle rect = new Rectangle(0, 0, getWidth(), getHeight()); 
      param.setSourceRegion(rect);
 
      currentx = imageWidth/2;
      currenty = imageHeight/2;
      background = reader.read(0, param);
 
      dx = getWidth() / 2;
      dy = getHeight() / 2;
   }
 
   public void run() {
      while (true) {
         try {
            Thread.sleep(10);
         }
         catch(InterruptedException e) { }
 
         if (currentx+dx > imageWidth-getWidth() || currentx+dx <= 0) {
            dx *= -1;
            currenty += dy;
            if (currenty+dy > imageHeight-getHeight() || currenty+dy <= 0) {
               dy *= -1;
            }
            currenty += dy;
         }
         currentx += dx;
 
         Rectangle rect = new Rectangle(currentx, currenty, getWidth(), getHeight()); 
         param.setSourceRegion(rect);
 
         try {
            background = reader.read(0, param);
         }
         catch(IOException e) {
            e.printStackTrace();
         }
 
         repaint();
      }
   }
  
   public void paint(Graphics g) {
      if (background != null)
         g.drawImage(background, 0, 0, getWidth(), getHeight(), this);
   }
 
   public static void main(String []args) throws Exception {
      Main main = new Main();
      main.setSize(100, 100);
      main.setVisible(true);
 
      main.initImageReading();
      new Thread(main).start();
   }
}

What is a type descriptor?

It is a unique string that represents the class. For reference types, you can find out the type descriptor of a class by calling getClass on an instance and getName. Primitive types have “hard-coded” type descriptors according to the following table:

   boolean		Z
   byte			B
   char			C
   double		D
   float		F
   int			I
   long 		J
   short		S

The type descriptor of an array is [ for each dimension. So an array of int[][] will have a type descriptor [[I.

Main.java:

public class Main {
   public static void main(String args[]) throws Exception {

      int [][]array = new int[10][10];
      String s = "Hello, world!";
      A a = new A();    
      
      System.out.println(double.class.getName());
      System.out.println(array.getClass().getName());
      System.out.println(s.getClass().getName());
      System.out.println(a.getClass().getName());
      System.out.println(A.InnerA.class.getName());
      System.out.println(A.InnerA.InnerB.class.getName());
   }
}
 
class A 
{
   public class InnerA { 
      public class InnerB {
      }
   }
}

outputs:

double
[[I
java.lang.String
A
A$InnerA
A$InnerA$InnerB

Resizing an array

An array can’t be resized. You will have to create a larger temporary array,
copy the values and have the original array point to the temporary one.
Take a look at the collection classes to use as an alternative for arrays.

Following app demonstrates the use:

public class Main
{
   public static void main(String args[]) {
      int []values = { 1, 2, 3, 4, 5, 6 };
 
      System.out.println("Before:");
      printArray(values);      
 
      // double the size
      int []temp = new int[values.length * 2];
      System.arraycopy(values, 0, temp, 0, values.length);
      values = temp;
 
      System.out.println("After:");
      printArray(values);      
   }
 
   public static void printArray(int []array) {
      for (int i=0; i<array.length; i++) {
         System.out.print(array[i] + " ");
      }
      System.out.println();
   }
}

outputs:

Before:
1 2 3 4 5 6 
After:
1 2 3 4 5 6 0 0 0 0 0 0