alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.openide.util.io;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import java.io.ObjectInput;
import java.io.ByteArrayInputStream;
import java.lang.reflect.InvocationTargetException;

import org.openide.ErrorManager;
import org.openide.util.Utilities;
import org.openide.util.Lookup;

// note: keep method resolveObject consistent with NbObjectOutputStream.replaceObject

/** Controlled deserialization stream using the system class loader.
* Employs the classloader available from lookup (currently that used for modules).
* Also contains static methods to safely read objects that might have problems
* during deserialization that should not corrupt the stream. The stream also provides 
* support for changing name of stored classes.
*
* @see #readClassDescriptor
*/
public class NbObjectInputStream extends ObjectInputStream {
    /** Create a new object input.
    * @param is underlying input stream
    * @throws IOException for the usual reasons
    */
    public NbObjectInputStream(InputStream is) throws IOException {
        super (is);
        try {
            enableResolveObject (true);
        } catch (SecurityException ex) {
            throw new IOException (ex.toString ());
        }
    }

    /* Uses NetBeans module classloader to load the class.
     * @param v description of the class to load
     */
    protected Class resolveClass(ObjectStreamClass v) throws IOException, ClassNotFoundException {
        ClassLoader cl = getNBClassLoader();
        try {
            return Class.forName(v.getName(), false, cl);
        } catch (ClassNotFoundException cnfe) {
            String msg = "Offending classloader: " + cl; // NOI18N
            ErrorManager.getDefault ().annotate(cnfe, ErrorManager.INFORMATIONAL, msg, null, null, null);
            throw cnfe;
        }
    }

    /** Lazy create default NB classloader for use during deserialization. */
    private static ClassLoader getNBClassLoader() {
        ClassLoader c = (ClassLoader)Lookup.getDefault ().lookup (ClassLoader.class);
        return c != null ? c : ClassLoader.getSystemClassLoader ();
    }

    /** Provides a special handling for renaming of serialized classes.
     * 

* Often, as the time goes the serialized classes evolve. They can be moved * to new packages, renamed or changed (by a mistake) to not reflect the * version of class stored in previous sessions. *

* This method deals with some of this incompatibilites and provides the * module owners a way how to fix some of them. *

* When a class is read, the Utilities.translate is consulted * to find out what whether the name of the class is listed there and * what new value is assigned to it. This allows complete rename of the * serialized class. For example: * org.netbeans.core.NbMainExplorer * can be renamed to * org.netbeans.core.ui.NbExp - of course supposing that * the new class is able to read the serialized fields of the old one. *

* Another useful feature of this method is the ability to supress wrong * serialVersionUID. This was causing us a lot of problems, * because people were forgetting to specify the serialVersionUID * field in their sources and then it was hard to recover from it. Right * now we have a solution: Just use Utilities.translate framework * to assing your class org.yourpackage.YourClass the same * name as it had e.g. org.yourpackage.YourClass. This will * be interpreted by this method as a hit to suppress serialVersionUID * and the NbObjectInputStream will ignore its value. *

* Please see Utilities.translate to learn how your module * can provide list of classes that changed name or want to suppress serialVersionUID. * */ protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException { ObjectStreamClass ose = super.readClassDescriptor(); String name = ose.getName (); String newN = Utilities.translate (name); if (name == newN) { // no translation return ose; } // otherwise reload the ObjectStreamClass to contain the local copy ClassLoader cl = getNBClassLoader(); Class clazz = Class.forName(newN, false, cl); ObjectStreamClass newOse = ObjectStreamClass.lookup(clazz); // #28021 - it is possible that lookup return null. In that case the conversion // table contains class which is not Serializable or Externalizable. if (newOse == null) { throw new java.io.NotSerializableException(newN); } return newOse; } /** Reads an object from the given object input. * The object had to be saved by the {@link NbObjectOutputStream#writeSafely} method. * * @param oi object input * @return the read object * @exception IOException if IO error occured * @exception SafeException if the operation failed but the stream is ok * for further reading */ public static Object readSafely (ObjectInput oi) throws IOException { int size = oi.readInt (); byte[] byteArray = new byte [size]; oi.readFully (byteArray, 0, size); try { ByteArrayInputStream bis = new ByteArrayInputStream (byteArray); NbObjectInputStream ois = new NbObjectInputStream (bis); Object obj = ois.readObject (); bis.close (); return obj; } catch (Exception exc) { // encapsulate all exceptions into safe exception throw new SafeException (exc); } catch (LinkageError le) { throw new SafeException (new InvocationTargetException (le)); } } /** Skips an object from the given object input without loading it. * The object had to be saved by the {@link NbObjectOutputStream#writeSafely} method. * * @param oi object input * @exception IOException if an I/O error occurred */ public static void skipSafely (ObjectInput oi) throws IOException { int size = oi.readInt (); oi.skip (size); } }

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.