HOWTO: Use Java Serialization with VARIANT SafeArrays

Last reviewed: January 29, 1998
Article ID: Q178561
The information in this article applies to:
  • SDK for Java, versions 2.0, 2.01
  • Microsoft Win32 Virtual Machine for Java

SUMMARY

VARIANT SafeArrays are used in COM to hold Arrays of data (bytes, ints, etc). It may be useful for a Java developer to use a SafeArray to persist a Java object. In order to do so, we need a way to convert the data from ObjectOutputStream to a SafeArray and back again.

MORE INFORMATION

Serialization in Java allows you to transmit or store a Java object in a stream. If you would like to use Serialization with COM objects, you will need to convert the Java stream to some form that COM understands. The most common form of parameter in COM is a VARIANT.

Because a VARIANT has limited types that can be placed inside of it, a serialized Java object's stream must be converted to a SafeArray. A SafeArray can hold a collection of bytes which is what a serialized Java object consists of. Java's representation of a SafeArray is com.ms.com.SafeArray. We need to create a simple class to convert the OutputStream to the SafeArray and another class to convert the SafeArray back to an InputStream.

NOTE: In order to compile the following code, you MUST use the latest Virtual Machine for Java (version 2252 or 2339 or newer) included in Internet Explorer 4.0 and 4.01 and Microsoft SDK for Java 2.0 and 2.01. The following code depends on new features of the SafeArray class included in the new Virtual Machine.

The following class called SafeArrayOutputStream converts data coming from an OutputStream into a SafeArray:

   import java.io.*;
   import java.util.*;
   import com.ms.com.*;

   // SafeArrayOutputStream
   public class SafeArrayOutputStream extends ByteArrayOutputStream
   {
      public SafeArray getSafeArray()
      {
         // Allocate an array the size of the vector
         byte[] byteArray = toByteArray();

         // Create the safearray
         SafeArray array = new SafeArray(Variant.VariantByte,
            byteArray.length);

         // Fill in safearray
         array.setBytes(0, byteArray.length, byteArray, 0);

         return array;
      }
   }

The following class called SafeArrayInputStream converts data from a SafeArray into an InputStream:

   import java.io.*;
   import com.ms.com.*;

   // SafeArrayInputStream
   public class SafeArrayInputStream extends ByteArrayInputStream
   {
      public SafeArrayInputStream(SafeArray array)
      {
         super(array.toByteArray());
      }
   }

Notice that both of these classes extend classes that are in the package Java.io. The ByteArrayOutputStream and the ByteArrayInputStream already provide most of the functionality necessary for the conversion.

If you have the following Automation COM interface:

   interface IShortStorage
   {
      public void setAppData(Variant v);
      public Variant getAppData();
   }

You would be able to use them in the following manner:

   // This is our variable that contains the COM interface
   IShortStorage istor = (IShortStorage) storageCOMObject;

   // This is our Object that we want to store
   Color color = new Color(255,0,128);

   // Create our SafeArrayOutputStream
   SafeArrayOutputStream safeOutStream = new SafeArrayOutputStream();

   // Declare a ObjectOutputStream for Serialization
   ObjectOutputStream objOutStream = null;
   try
   {
      // Create the ObjectOutputStream passing in our SafeArrayOutputStream
      objOutStream = new ObjectOutputStream(safeOutStream);

      // Write our color object to the stream
      objOutStream.writeObject(color);

      // Flush the stream
      objOutStream.flush();
   }
   catch(Exception e)
   {
      // ObjectOutputStream threw an exception
   }

   // Close the stream
   safeOutStream.close();

   // Get the SafeArray from our SafeArrayOutputStream
   SafeArray bytes = safeOutStream.getSafeArray();

   // Create a new Variant to hold the SafeArray
   Variant data = new Variant();

   // Put the SafeArray inside the Variant
   data.putSafeArray ( bytes );

   // Store the Variant inside the Automation Object
   istor.setAppData(data);

When you are ready to retieve the Object, use this code to deserialize your Object from the SafeArrayInputStream:

   // Get the Variant back from the Automation Object
   Variant data = istor.getAppData();

   // Get the SafeArray out of the Variant
   SafeArray bytes = body.toSafeArray();

   // Create a new SafeArrayInputStream based on the SafeArray
   SafeArrayInputStream safeInStream = new SafeArrayInputStream(bytes);

   // Create a ObjectInputStream based on the SafeArrayInputStream
   ObjectInputStream objInStream = new ObjectInputStream(safeInStream);

   // Get the serialized object out of the ObjectInputStream
   Object obj = objInStream.readObject();

   // Check to see if the object is a color
   if(obj instanceof Color)
   {
      Color col = (Color)obj;
      // Use the color
   }

REFERENCES

SafeArrays and Variants are described in the Microsoft SDK for Java 2.0 and 2.01 documentation which is available from http://www.microsoft.com/java/sdk/.

For the latest Knowledge Base articles and other support information on Visual J++ and the SDK for Java, see the following page on the Microsoft Technical Support site:

   http://support.microsoft.com/support/visualj/
   http://support.microsoft.com/support/java/


Additional query words: SafeArray serialization

Keywords : kbcode JCOM
Technology : internet
Version : WINDOWS:2.0,2.01
Platform : WINDOWS
Issue type : kbhowto


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: January 29, 1998
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.