Publishing a Websphere MQ ConnectionFactory in an LDAP

The following working code sample allows you to create a QueueConnectionFactory (MQQueueConnectionFactory) and register it as an administered object in an LDAP tree.

I used iPlanet Directory Server 5.0 to test it out.

RegisterWebsphereMQ.java:

import  com.ibm.mq.jms.MQQueueConnectionFactory;
import  javax.naming.*;
import  javax.jms.*;
 
import  java.util.*;
 
public class RegisterWebsphereMQ
{
   public static void main(String args[])
   {
      if (args.length != 5) {
         System.err.println("Usage: RegisterWebsphereMQ LDAP-url base queue-manager username password");
         System.err.println("  eg.:      ldapurl        ldap://127.0.0.1:389");
         System.err.println("            providername   ou=dev,ou=test,o=esus.com");
         System.err.println("            queue-manager  name of the queue manager, eg. MQS1");
         System.err.println("            username       uid=user,ou=People,o=esus.com");
         System.err.println("            password       pw");
         System.exit(1);
      }
      String ldapurl=args[0];
      String base=args[1];
      String queuemgr=args[2];
      String username=args[3];
      String password=args[4];
 
      try {
         Context context = getInitialContext(ldapurl, username, password);
 
         createLDAPObject(context, base, "QueueConnectionFactory");
         createQueueConnectionFactory(context, base, queuemgr);
 
         System.out.println("Registration successful");
      } catch(Exception e) {
         System.out.println("Registration failed: " + e);
         e.printStackTrace();
      }
   }
 
   public static Context getInitialContext(String ldapurl, String username, String password)
                            throws NamingException
   {
      Properties env=System.getProperties();
      env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
      env.put(Context.PROVIDER_URL, ldapurl);
      env.put(Context.SECURITY_PRINCIPAL, username);
      env.put(Context.SECURITY_CREDENTIALS, password);
 
      // Retrieve the initial context
      return new InitialContext(env);
   }
 
   public static void createLDAPObject(Context context, String base, String ouName)
                        throws NamingException
   {
      try {
         context.bind("ou=" + ouName + "," + base, new LDAPObject(ouName));
         System.out.println("Created OU [" + ouName + "]");
      }
      catch(NameAlreadyBoundException e) {
         System.out.println("Name " + ouName + " is already bound under " + base);
      }
   }
 
   public static void createQueueConnectionFactory(Context context, String base, String queuemgr)
                         throws NamingException, JMSException
   {
      QueueConnectionFactory qcf = new MQQueueConnectionFactory();
      ((MQQueueConnectionFactory) qcf).setQueueManager(queuemgr);
 
      // Bind the connection factory into the JNDI repository
      context.rebind("cn=queuefactory,ou=QueueConnectionFactory,"+base, qcf);
   }   
}

LDAPObject.java:

import javax.naming.*;
import javax.naming.directory.*;
import java.util.*;
 
class LDAPObject implements DirContext {
   Attributes attributes;
   String name;
    
   public LDAPObject(String name) {
      this.name = name;
 
      attributes = new BasicAttributes(true);
      // case ignore
      Attribute oc = new BasicAttribute("objectclass");
      oc.add("organizationalunit");
      oc.add("top");
 
      attributes.put(oc);
   }
 
   public Attributes getAttributes(String name) throws NamingException {
      if (!name.equals("")) {
         throw new NameNotFoundException();
      }
      return (Attributes) attributes.clone();
   }
 
   public Attributes getAttributes(Name name) throws NamingException {
      return getAttributes(name.toString());
   }
 
   public Attributes getAttributes(String name, String[] ids)
          throws NamingException {
      if (!name.equals("")) {
         throw new NameNotFoundException();
      }
 
      Attributes answer = new BasicAttributes(true);
      Attribute target;
      for (int i = 0; i < ids.length; i++) {
         target = attributes.get(ids[i]);
         if (target != null) {
            answer.put(target);
         }
      }
      return answer;
   }
 
   public Attributes getAttributes(Name name, String[] ids)
          throws NamingException {
      return getAttributes(name.toString(), ids);
   }
 
   public String toString() {
      return name;
   }
 
   public Object lookup(Name name) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public Object lookup(String name) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public void bind(Name name, Object obj) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public void bind(String name, Object obj) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public void rebind(Name name, Object obj) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public void rebind(String name, Object obj) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public void unbind(Name name) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public void unbind(String name) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public void rename(Name oldName, Name newName) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public void rename(String oldName, String newName) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public NamingEnumeration list(Name name) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public NamingEnumeration list(String name) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public NamingEnumeration listBindings(Name name) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public NamingEnumeration listBindings(String name) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public void destroySubcontext(Name name) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public void destroySubcontext(String name) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public Context createSubcontext(Name name) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public Context createSubcontext(String name) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public Object lookupLink(Name name) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public Object lookupLink(String name) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public NameParser getNameParser(Name name) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public NameParser getNameParser(String name) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public String composeName(String name, String prefix)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public Name composeName(Name name, Name prefix)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public Object addToEnvironment(String propName, Object propVal)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public Object removeFromEnvironment(String propName)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public Hashtable getEnvironment() throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public void close() throws NamingException {
      throw new OperationNotSupportedException();
   }
 
// -- DirContext
   public void modifyAttributes(Name name, int mod_op, Attributes attrs)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public void modifyAttributes(String name, int mod_op, Attributes attrs)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public void modifyAttributes(Name name, ModificationItem[] mods)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public void modifyAttributes(String name, ModificationItem[] mods)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public void bind(Name name, Object obj, Attributes attrs)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public void bind(String name, Object obj, Attributes attrs)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public void rebind(Name name, Object obj, Attributes attrs)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public void rebind(String name, Object obj, Attributes attrs)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public DirContext createSubcontext(Name name, Attributes attrs)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public DirContext createSubcontext(String name, Attributes attrs)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public DirContext getSchema(Name name) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public DirContext getSchema(String name) throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public DirContext getSchemaClassDefinition(Name name)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public DirContext getSchemaClassDefinition(String name)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public NamingEnumeration search(Name name,
         Attributes matchingAttributes,
         String[] attributesToReturn)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public NamingEnumeration search(String name,
         Attributes matchingAttributes,
         String[] attributesToReturn)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public NamingEnumeration search(Name name,
         Attributes matchingAttributes)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public NamingEnumeration search(String name,
         Attributes matchingAttributes)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public NamingEnumeration search(Name name,
         String filter,
         SearchControls cons)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public NamingEnumeration search(String name,
         String filter,
         SearchControls cons)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public NamingEnumeration search(Name name,
         String filterExpr,
         Object[] filterArgs,
         SearchControls cons)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public NamingEnumeration search(String name,
         String filterExpr,
         Object[] filterArgs,
         SearchControls cons)
          throws NamingException {
      throw new OperationNotSupportedException();
   }
 
   public String getNameInNamespace() throws NamingException {
      throw new OperationNotSupportedException();
   }
}

Sample run:

C:myldap>java RegisterWebsphereMQ ldap://localhost:2000 ou=dev,ou=epais,o=philips.com MQS1 uid=user,ou=People,o=esus.com pw
Created OU [QueueConnectionFactory]
Registration successful

A Swing drag and drop code example

Drag and Drop is a powerful feature you should consider adding to your Java applications. When you check out the available tutorials on Java dnd, it may look fairly complex to you. Though it’s not all that hard, the hard part is remembering all the steps, objects and listeners involved. Here is a small example that shows you a basic drag and drop application (implemented with Swing).

A custom Drag and Drop (source) JList appears to the right and contains a file list of your root directory. Files with .txt extensions can be dragged upon our Drag and Drop JTextArea (target). The object transferred (Transferable) is a filename. When the drop occurs (you release the mouse button) the public void drop(DropTargetDropEvent event) is called. You can extract the filename from the Transferable object and go from there.

Main.java

import javax.swing.event.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import java.io.*;
 
public class Main extends JFrame
{
   private DNDJList list;
   private DNDJTextArea textarea;
 
   public static void main(String []args) {
      Main frame = new Main();
      frame.show();
   }
 
   public Main() {
      getContentPane().setLayout(new BorderLayout());
      list = new DNDJList(new DefaultListModel());
      getContentPane().add(BorderLayout.EAST, new JScrollPane(list));
      textarea = new DNDJTextArea();
      getContentPane().add(BorderLayout.CENTER, new JScrollPane(textarea));
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            System.exit(0);
         }
      });
 
      fillUpList(&quot;c:\&quot;);
 
      setSize(700, 300);
   }

   /**
    *  Fills up the JList with the entries in the specified directory
    */
   private void fillUpList(String directory) {
      File dir = new File(directory);
      File []files = dir.listFiles();
 
      DefaultListModel dlm = (DefaultListModel) list.getModel();
      for (int i=0; i&lt;files.length; i++) {
         dlm.addElement(directory + files[i].getName());
      }
   }
}

Our drag and drop JTextArea: DNDJTextArea.java

import java.awt.*;
import java.awt.dnd.*;
import java.awt.datatransfer.*;

import java.io.*;
import java.io.IOException;
 
import javax.swing.JTextArea;
 
public class DNDJTextArea extends JTextArea implements DropTargetListener
{
   DropTarget dropTarget = null;
  
   public DNDJTextArea() {
      // create a drop target
      dropTarget = new DropTarget(this, this);
   }
 
   public void dragEnter(DropTargetDragEvent event) { 
      event.acceptDrag(DnDConstants.ACTION_MOVE);
   }
 
   public void drop (DropTargetDropEvent event) {
      try {
         // get the object that is being transferred
         Transferable transferable = event.getTransferable();
       
         // DNDJTextArea accepts only Strings
         if (transferable.isDataFlavorSupported(DataFlavor.stringFlavor)) {
            event.acceptDrop(DnDConstants.ACTION_MOVE);
 
            String filename = (String) transferable.getTransferData(DataFlavor.stringFlavor);
            setText(readFile(filename));

            event.getDropTargetContext().dropComplete(true);
         } 
         else {
            event.rejectDrop();
         }
      }
      catch (UnsupportedFlavorException e) {
         setText(&quot;&quot;+e);
         event.rejectDrop();
      }
      catch (Exception e) {
         setText(&quot;&quot;+e);
         event.rejectDrop();
      } 
   }
 
   public void dragExit (DropTargetEvent event) { }
   public void dragOver (DropTargetDragEvent event) { }
   public void dropActionChanged (DropTargetDragEvent event) { }
 
   public String readFile(String filename) throws Exception {
      String LINEEND = System.getProperties().getProperty(&quot;line.separator&quot;);      
      StringBuffer sb = new StringBuffer();
      BufferedReader br = new BufferedReader(new FileReader(filename));
 
      String line;
      while ((line = br.readLine()) != null) {
         sb.append(line + LINEEND);
      }         
 
      return sb.toString();
   }
}

A drag and drop JList:DNDJList.java

import java.awt.dnd.*;
import java.awt.datatransfer.*;
import java.io.IOException;
import java.io.*;
 
import javax.swing.*;
 
public class DNDJList extends JList implements DragSourceListener, DragGestureListener    
{
   DragSource dragSource = null;
 
   public DNDJList(ListModel lm) {
      super(lm);
 
      // create a dragsource
      dragSource = new DragSource();
 
      // create a drag gesture recognizer
      dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_MOVE, this);
   }    
 
   public void dragGestureRecognized( DragGestureEvent event) {  
      String fileSelected = (String) getSelectedValue();
 
      if (fileSelected != null) {
         if (fileSelected.endsWith(&quot;.txt&quot;)) {
            // StringSelection implements Transferable, wraps the data into a transferable object
            StringSelection text = new StringSelection(fileSelected.toString()); 
        
            // start the dragging
            dragSource.startDrag(event, DragSource.DefaultMoveDrop, text, this);
         }
         else {
            SwingUtilities.invokeLater(new Runnable() {
               public void run() {
                  JOptionPane.showMessageDialog(SwingUtilities.getRootPane(DNDJList.this), 
                                                &quot;Only .txt files can be dragged!&quot;, &quot;Error&quot;,
                                                JOptionPane.ERROR_MESSAGE);
               } 
            });
         }
      } else {
         System.out.println( &quot;nothing was selected&quot;);   
      }
   }
 
   public void dragDropEnd (DragSourceDropEvent event) { }
   public void dragEnter (DragSourceDragEvent event) { }
   public void dragExit (DragSourceEvent event) { }
   public void dragOver (DragSourceDragEvent event) { }
   public void dropActionChanged ( DragSourceDragEvent event) { }
}

Scaling an image

You can use apply an AffineTransform object when drawing the image, or you can create a BufferedImage and perform an scaling operation on it.

Apply AffineTransform when drawing image

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 double scalex = 1.0;
   private double scaley = 1.0;
   private JButton button1;
   private JButton button2;
 
   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());
      
      button1 = new JButton("scale up by 5");
      button1.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            scalex += .1;
            scaley += .1;
            repaint();
         }
      });
 
      button2 = new JButton("scale down by 5");
      button2.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            scalex -= .1;
            scaley -= .1;
            repaint();
         }
      });
 
      JPanel panel = new JPanel(new GridLayout(1, 2));
      panel.add(button1);
      panel.add(button2);
      getContentPane().add(BorderLayout.SOUTH, panel);
   }
 
   public void paint(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
 
      AffineTransform at = new AffineTransform();
      at.scale(scalex, scaley);
      g2d.drawImage(image, at, this);
 
      button1.repaint();
      button2.repaint();
   }
 
   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);
   }
}

Creating BufferedImage and scaling afterwards

Main.java:

import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame {
   private Image image;
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      image = Toolkit.getDefaultToolkit().getImage("c:\djkrush.jpg");
      waitForImage(image);
      image = scaleImage(image, 2.0, 2.0);
   }
 
   public void paint(Graphics g) {
      g.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 Image scaleImage(Image image, double scalex, double scaley) {
      BufferedImage bi = toBufferedImage(image);
 
      AffineTransformOp op = new AffineTransformOp(
                   AffineTransform.getScaleInstance(scalex, scaley), null); 
 
      return op.filter(bi, null); 
   }
 
   public BufferedImage toBufferedImage(Image image) {
      BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), 
                                           BufferedImage.TYPE_INT_RGB); 

      // copy the original image
      Graphics g = bi.createGraphics();
    
      g.drawImage(image, 0, 0, null);
      g.dispose();
 
      return bi;
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(400, 400);
      main.setVisible(true);
   }
}

Image used:

Why static fields are not serialized

Static fields of a class are shared among objects of that class. Just imaging they would be serialized, what would happen if you have instantiated an object of a class containing an important static variable and that you would deserialize an object of the same class. The static field would be overwritten. Sometimes, however, you may want this type of behavior. The solution is simple: just customize serialization through the methods writeObject and readObject as shown in following example.

Main.java:

import java.io.*;
 
public class Main {
   public static void main(String args[]) {
      try {
         Test t1 = new Test();
         t1.create();
 
         System.out.println("State of t1: " + t1);
 
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ObjectOutputStream oos = new ObjectOutputStream(baos);
         oos.writeObject(t1);
         oos.flush();
 
         // make static variable count 0 to prove our point
         Test.count = 0;
 
         ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
         ObjectInputStream ois = new ObjectInputStream(bais);
         Test t2 = (Test) ois.readObject();
 
         System.out.println("State of t2: " + t2);  
      }
      catch(ClassNotFoundException e) {
         System.out.println(e); 
      }
      catch(IOException e) { 
         System.out.println(e); 
      }
   }
}
 
class Test implements Serializable {
   public int var = 0;
   public static int count = 0;
  
   Test() { }
 
   public void create() {
      var = 1;
      count++;
   }
 
   private void writeObject(ObjectOutputStream oos) throws IOException {
      oos.defaultWriteObject();
      // write static variable
      oos.writeInt(count);
   }
 
   private void readObject(ObjectInputStream ois) throws IOException, 
                                              ClassNotFoundException {
      ois.defaultReadObject();
      // read static variable
      count = ois.readInt();
   }
  
   public String toString() {
      return "var = " + var + "; count = " + count;
   }
}

outputs:

State of t1: var = 1; count = 1
State of t2: var = 1; count = 1

Reading an int from standard input

Wrap System.in in a BufferedReader object and call the method readLine. Then convert that string to an int.
Main.java:

import java.io.*;
 
public class Main 
{
   public static void main(String [] args) {
      BufferedReader stdin = new BufferedReader
         (new InputStreamReader(System.in));
      String number;
  
      System.out.println ("Enter a integer number:");
      try {
         number = stdin.readLine();
         int n = Integer.parseInt(number);
         System.out.println("You entered " + n);
      }
      catch(Exception e) {
         System.out.println("You did not enter a valid number!");
      }
   } 
} 

Counting the number of lines in a file

Main.java:

import java.io.*;
 
public class Main {
   public static void main(String args[]) {
      if (args.length != 1) {
         System.err.println("Usage: java Main <textfile>");
         System.exit(1);
      }
 
      try {
         BufferedReader br = new BufferedReader(new FileReader(args[0]));
         int total = 0;
         while (br.readLine() != null) total++;
         System.out.println(total);
      }
      catch(FileNotFoundException e) {
         System.err.println(e);
      }
      catch(IOException e) {
         System.err.println(e);
      }
   }
}

Displaying image metadata with ImageIO

IIOMetadata contains meta information about the image, so not the actual pixels, but stuff like for example compression, keywords, comments, … If you convert from one format to another, you don’t want to loose this information. A ImageTranscoder understands this meta data and maps it onto another format. Internally, Metadata is stored as a bunch of IIOMetadataNodes (they implement the org.w3c.dom.Element interface). The format of this DOM tree is plug-in dependent: the native format (as format features are different), but plug-ins may support the plug-in neutral format. The following example program displays (using the XSLT transformation package) the plug-in neutral format.

Main.java:

import javax.imageio.metadata.*; 
import javax.imageio.stream.*;
import javax.imageio.*;
 
import java.awt.image.*;
import java.util.*;
import java.io.*;
  
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.*;
import javax.xml.parsers.*;
  
import org.w3c.dom.*; 
  
public class Main
{
   public static void main(String []args) throws Exception {
      Iterator readers = ImageIO.getImageReadersByFormatName("png");
      ImageReader reader = (ImageReader) readers.next();
 
      ImageInputStream iis = ImageIO.createImageInputStream(new File("coverpng.png"));
      reader.setInput(iis, true);
      BufferedImage bi = reader.read(0);

      IIOMetadata metadata = reader.getImageMetadata(0);
      Node node = (Node) metadata.getAsTree(metadata.getNativeMetadataFormatName());
 
      // use the XSLT transformation package to output the DOM tree we just created
      TransformerFactory tf = TransformerFactory.newInstance();
      Transformer transformer = tf.newTransformer();
      transformer.transform(new DOMSource(node), new StreamResult(System.out));
   }
}

outputs:

<? xml version="1.0" encoding="UTF-8"?>
<javax_imageio_png_1.0>
   <IHDR width="50" height="66" bitDepth="4" colorType="Palette" 
         compressionMethod="deflate" filterMethod="adaptive" 
         interlaceMethod="none"/>
   <PLTE>
      <PLTEEntry index="0" red="0" green="0" blue="0"/>
      <PLTEEntry index="1" red="128" green="192" blue="184"/>
      <PLTEEntry index="2" red="8" green="0" blue="0"/>
      <PLTEEntry index="3" red="248" green="252" blue="248"/>
      <PLTEEntry index="4" red="176" green="176" blue="176"/>
      <PLTEEntry index="5" red="184" green="220" blue="216"/>
      <PLTEEntry index="6" red="120" green="120" blue="120"/>
      <PLTEEntry index="7" red="16" green="152" blue="136"/>
      <PLTEEntry index="8" red="88" green="168" blue="160"/>
      <PLTEEntry index="9" red="72" green="72" blue="72"/>
      <PLTEEntry index="10" red="0" green="0" blue="0"/>
      <PLTEEntry index="11" red="0" green="0" blue="0"/>
      <PLTEEntry index="12" red="0" green="0" blue="0"/>
      <PLTEEntry index="13" red="0" green="0" blue="0"/>
      <PLTEEntry index="14" red="0" green="0" blue="0"/>
      <PLTEEntry index="15" red="0" green="0" blue="0"/>
   </PLTE>
</javax_imageio_png_1.0>

coverpng.png:

Compile Java contained in a String

A bit of hacking around lead to the following example. Create an instance of InMemorySourceCompiler and pass it the name of the program and the source code as a String. Any suggestions/improvements are appreciated as a comment to this answer.

The following example creates a JFrame that contains the output of the source.

Main.java:

import java.lang.reflect.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.*;
import java.util.*;
import java.io.*;
  
import sun.tools.javac.*;  
import sun.tools.java.*;
   
public class Main extends JFrame
{
   public Main(String s) {
      getContentPane().add(new JTextArea(s, 3, 50));
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
   }
  
   public static void main(String args[]) throws Exception
   {
      // Save all data written to System.out to a byte array and display in frame
      PrintStream ps = System.out;
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      System.setOut(new PrintStream(baos));
 
      InMemorySourceCompiler imsCompiler = new InMemorySourceCompiler("Test",
          "public class Test {" +
          "   public static void main(String args[]) {" +
          "      System.out.println("Output of program:");" +
          "      for (int i=0; i<10; i++) {" +
          "         System.out.println(i);" +
          "      }" +
          "      System.out.println("End of output.");" + 
          "   }" +
          "}");
      imsCompiler.executeMain();
 
      byte[] b = baos.toByteArray();
 
      System.setOut(ps);
 
      String s = new String(b);
 
      Main main = new Main(s);
      main.setSize(200, 230);
      main.setVisible(true);  
   }
}
       
class InMemorySourceCompiler {
   protected String name;
   protected String source;
   protected Class compiledClass;
  
   public InMemorySourceCompiler(String name, String source) throws Exception {
      this.name = name;
      this.source = source;
      loadClass();
   }
 
   protected void loadClass() throws Exception {
      ClassPath cp = new ClassPath(System.getProperty("java.class.path"));
      OutputStream os = System.out;
      BatchEnvironment be = new BatchEnvironment(os, cp);
      be.flags = 0x41004;
      be.majorVersion = 45;
      be.minorVersion = 3;
      be.covFile = null;
      be.setCharacterEncoding(null);
 
      be.parseFile(new InMemorySourceClassFile(name+".java", source));
 
      ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
 
      be.flushErrors();
      Vector v = new Vector();
 
      for (Enumeration enum = be.getClasses(); enum.hasMoreElements();) {
         v.addElement(enum.nextElement());
      }
 
      for (int i=0; i<v.size(); i++) {
         ClassDeclaration cd = (ClassDeclaration) v.elementAt(i);
         Object object = cd.getClassDefinition(be);
 
         if (object instanceof SourceClass) {
            SourceClass sourceclass = (SourceClass) object;
            cd.setDefinition(sourceclass, 5);
            SourceClass sourceclass1 = (SourceClass) object;
            baos.reset();
            sourceclass.compile(baos);
         }
         else if (object instanceof BinaryClass) {
            BinaryClass binaryclass = (BinaryClass) object;
            binaryclass.write(be, baos);
         }
         byte[] b = baos.toByteArray();
 
         InMemorySourceCompilerClassLoader myClassLoader = new InMemorySourceCompilerClassLoader();
         compiledClass = myClassLoader.getClassFromBytes(name, b);
      }
   }
 
   public void executeMain() throws Exception {
      Method m = compiledClass.getMethod("main", new Class[]{ String[].class });
      m.invoke(null, new Object[]{null});
   }
 
   static class InMemorySourceCompilerClassLoader extends ClassLoader
   {
      public Class getClassFromBytes(String name, byte[] b) {
         return defineClass(name, b, 0, b.length);
      }
   }
}
 
class InMemorySourceClassFile extends ClassFile
{
   private String filename;
   private String text;
 
   public InMemorySourceClassFile(String filename, String text) {
      super(new File(filename));
      this.filename = filename;
      this.text = text;
   }
 
   public String getAbsoluteName() {
      return filename;
   }
 
   public boolean exists() {
      return true;
   }
 
   public InputStream getInputStream() {
      return new StringBufferInputStream(text);
   }
 
   public String getName() {
      return filename;
   }
 
   public String getPath() {
      return "";
   }
 
   public boolean isDirectory() {
      return false;
   }
 
   public boolean isZipped() {
      return false;
   }
  
   public long lastModified() {
      return new Date().getTime();
   }
 
   public long length() {
      return text.length();
   }
 
   public String toString() {
      return filename;
   }
}

Binary searching 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. Before using
the binary search method, you should make sure the array is sorted. Binary searching
on an unsorted array gives undefined results. The binarySearch function is defined
for arrays of type byte[], char[], double[], float[], int[], long[], object[].

You pass the method the key you want to lookup. It returns with either
the index, if the key is found, or the insertion point defined as
(-return value)-1, as the index where the value should be inserted to keep
the array sorted.
Following example demonstrates the use:

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);
 
      int v1 = 6;
      int v2 = 34;
      int r1 = Arrays.binarySearch(values, v1);
      int r2 = Arrays.binarySearch(values, v2);
 
      printResult(v1, r1);
      printResult(v2, r2);
   }
 
   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();
   }
 
   public static void printResult(int value, int index) {
      if (index < 0) {
         int ip = -index - 1;
         System.out.println(value + " not found.  Insertion point = " + ip);
      }
      else {
         System.out.println(value + " found at index " + index);
      }
   }
}

outputs:

Unsorted array:
5 74 23 99 6 0 -2 -60 
 
Sorted array:
-60 -2 0 5 6 23 74 99 
 
6 found at index 4
34 not found.  Insertion point = 6

You can just as easily binary search on 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);
 
      Color v1 = new Color(220, 220, 220);
      Color v2 = new Color(11, 0, 0);
      int r1 = Arrays.binarySearch(colArr, v1, new RedColorComparator());
      int r2 = Arrays.binarySearch(colArr, v2, new RedColorComparator());
  
      printResult(v1, r1);
      printResult(v2, r2);
   }
 
   public static void printArray(Color colArr[]) {
      for (int i=0; i<colArr.length; i++) 
         System.out.println(colArr[i]);
      System.out.println();
   }
 
   public static void printResult(Color value, int index) {
      if (index < 0) {
         int ip = -index - 1;
         System.out.println(value + " not found.  Insertion point = " + ip);
      }
      else {
         System.out.println(value + " found at index " + index);
      }
   }
}
 
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]
 
java.awt.Color[r=220,g=220,b=220] found at index 4
java.awt.Color[r=11,g=0,b=0] not found.  Insertion point = 2

Getting the size of an object

Java does not know a sizeof operator as C++ does. But you may try something like getting the amount of free memory through the method freeMemory() in the Runtime class:

public class MyObject
{
   private int a[] = new int[1000];
  
   public static void main(String []args) {
      long fmstart = Runtime.getRuntime().freeMemory();
      Object o = new MyObject();
      long fmend = Runtime.getRuntime().freeMemory();
 
      System.out.println("Size of a MyObject object = " + (fmstart - fmend));
   }
}

You can’t rely on this code because you do not have control over the Garbage Collector thread that makes the amount of free memory fluctuate.
Another trick is to serialize the state of the object you want the size of and deduct information from that.

But think again, do you really need the capability of knowing the exact number of bytes of an Object? Probably not.