[hibernate-commits] Hibernate SVN: r17978 - in core/trunk: annotations/src/test/java/org/hibernate/test/annotations/lob and 2 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Fri Nov 13 14:04:09 EST 2009


Author: steve.ebersole at jboss.com
Date: 2009-11-13 14:04:09 -0500 (Fri, 13 Nov 2009)
New Revision: 17978

Modified:
   core/trunk/annotations/src/main/java/org/hibernate/type/SerializableToBlobType.java
   core/trunk/annotations/src/test/java/org/hibernate/test/annotations/lob/SerializableToImageType.java
   core/trunk/core/src/main/java/org/hibernate/type/SerializableType.java
   core/trunk/core/src/main/java/org/hibernate/util/SerializationHelper.java
Log:
HHH-2990 - Bad usage of ClassLoader.loadClass() for Java6 in SerializationHelper$CustomObjectInputStream - deserialization bottleneck for arrays


Modified: core/trunk/annotations/src/main/java/org/hibernate/type/SerializableToBlobType.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/type/SerializableToBlobType.java	2009-11-13 18:15:10 UTC (rev 17977)
+++ core/trunk/annotations/src/main/java/org/hibernate/type/SerializableToBlobType.java	2009-11-13 19:04:09 UTC (rev 17978)
@@ -87,8 +87,8 @@
 		return SerializationHelper.serialize( (Serializable) object );
 	}
 
-	private static Object fromBytes(byte[] bytes) throws SerializationException {
-		return SerializationHelper.deserialize( bytes );
+	private Object fromBytes(byte[] bytes) throws SerializationException {
+		return SerializationHelper.deserialize( bytes, getReturnedClass().getClassLoader() );
 	}
 
 	public void set(PreparedStatement st, Object value, int index, SessionImplementor session) throws SQLException {

Modified: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/lob/SerializableToImageType.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/lob/SerializableToImageType.java	2009-11-13 18:15:10 UTC (rev 17977)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/lob/SerializableToImageType.java	2009-11-13 19:04:09 UTC (rev 17978)
@@ -43,7 +43,7 @@
 	protected Object toExternalFormat(byte[] bytes) {
 		if (bytes == null)
 			return null;
-		return SerializationHelper.deserialize(bytes);
+		return SerializationHelper.deserialize( bytes, getReturnedClass().getClassLoader() );
 	}
 
 	protected byte[] toInternalFormat(Object bytes) {

Modified: core/trunk/core/src/main/java/org/hibernate/type/SerializableType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/SerializableType.java	2009-11-13 18:15:10 UTC (rev 17977)
+++ core/trunk/core/src/main/java/org/hibernate/type/SerializableType.java	2009-11-13 19:04:09 UTC (rev 17978)
@@ -101,8 +101,8 @@
 		return SerializationHelper.serialize( (Serializable) object );
 	}
 
-	private static Object fromBytes( byte[] bytes ) throws SerializationException {
-		return SerializationHelper.deserialize(bytes);
+	private Object fromBytes(byte[] bytes) throws SerializationException {
+		return SerializationHelper.deserialize( bytes, getReturnedClass().getClassLoader() );
 	}
 
 	public int sqlType() {

Modified: core/trunk/core/src/main/java/org/hibernate/util/SerializationHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/SerializationHelper.java	2009-11-13 18:15:10 UTC (rev 17977)
+++ core/trunk/core/src/main/java/org/hibernate/util/SerializationHelper.java	2009-11-13 19:04:09 UTC (rev 17978)
@@ -84,7 +84,10 @@
      */
     public static Object clone(Serializable object) throws SerializationException {
 	    log.trace("Starting clone through serialization");
-        return deserialize( serialize(object) );
+		if ( object == null ) {
+			return null;
+		}
+        return deserialize( serialize( object ), object.getClass().getClassLoader() );
     }
 
     // Serialize
@@ -153,62 +156,107 @@
     // Deserialize
     //-----------------------------------------------------------------------
     /**
-     * <p>Deserializes an <code>Object</code> from the specified stream.</p>
+     * Deserializes an object from the specified stream using the Thread Context
+	 * ClassLoader (TCCL).  If there is no TCCL set, the classloader of the calling
+	 * class is used.
+     * <p/>
+	 * Delegates to {@link #deserialize(java.io.InputStream, ClassLoader)}
      *
-     * <p>The stream will be closed once the object is written. This
-     * avoids the need for a finally clause, and maybe also exception
-     * handling, in the application code.</p>
+     * @param inputStream  the serialized object input stream, must not be null
+     * @return the deserialized object
+     * @throws IllegalArgumentException if <code>inputStream</code> is <code>null</code>
+     * @throws SerializationException (runtime) if the serialization fails
+     */
+    public static Object deserialize(InputStream inputStream) throws SerializationException {
+		return deserialize( inputStream, Thread.currentThread().getContextClassLoader() );
+    }
+
+    /**
+     * Deserializes an object from the specified stream using the Thread Context
+	 * ClassLoader (TCCL).  If there is no TCCL set, the classloader of the calling
+	 * class is used.
+     * <p/>
+     * The stream will be closed once the object is read. This avoids the need 
+	 * for a finally clause, and maybe also exception handling, in the application
+	 * code.
+     * <p/>
+     * The stream passed in is not buffered internally within this method.  This is
+	 * the responsibility of the caller, if desired.
      *
-     * <p>The stream passed in is not buffered internally within this method.
-     * This is the responsibility of your application if desired.</p>
-     *
      * @param inputStream  the serialized object input stream, must not be null
+	 * @param loader The classloader to use
+	 *
      * @return the deserialized object
+	 *
      * @throws IllegalArgumentException if <code>inputStream</code> is <code>null</code>
      * @throws SerializationException (runtime) if the serialization fails
      */
-    public static Object deserialize(InputStream inputStream) throws SerializationException {
+    public static Object deserialize(InputStream inputStream, ClassLoader loader) throws SerializationException {
         if (inputStream == null) {
-            throw new IllegalArgumentException("The InputStream must not be null");
+            throw new IllegalArgumentException( "The InputStream must not be null" );
         }
 
-		log.trace("Starting deserialization of object");
+		log.trace( "Starting deserialization of object" );
 
-        CustomObjectInputStream in = null;
-        try {
-            // stream closed in the finally
-            in = new CustomObjectInputStream(inputStream);
-            return in.readObject();
+		try {
+			CustomObjectInputStream in = new CustomObjectInputStream( inputStream, loader );
+			try {
+				return in.readObject();
+			}
+			catch ( ClassNotFoundException e ) {
+				throw new SerializationException( "could not deserialize", e );
+			}
+			catch ( IOException e ) {
+				throw new SerializationException( "could not deserialize", e );
+			}
+			finally {
+				try {
+					in.close();
+				}
+				catch (IOException ignore) {
+					// ignore
+				}
+			}
+		}
+		catch ( IOException e ) {
+			throw new SerializationException( "could not deserialize", e );
+		}
+	}
 
-        }
-        catch (ClassNotFoundException ex) {
-            throw new SerializationException("could not deserialize", ex);
-        }
-        catch (IOException ex) {
-            throw new SerializationException("could not deserialize", ex);
-        }
-        finally {
-            try {
-                if (in != null) in.close();
-            }
-            catch (IOException ex) {}
-        }
+    /**
+     * Deserializes an Object from an array of bytes.
+	 * <p/>
+	 * Delegates to {@link #deserialize(byte[], ClassLoader)}
+     *
+     * @param objectData  the serialized object, must not be null
+     * @return the deserialized object
+     * @throws IllegalArgumentException if <code>objectData</code> is <code>null</code>
+     * @throws SerializationException (runtime) if the serialization fails
+     */
+    public static Object deserialize(byte[] objectData) throws SerializationException {
+		return deserialize( objectData, Thread.currentThread().getContextClassLoader() );
     }
 
     /**
-     * <p>Deserializes a single <code>Object</code> from an array of bytes.</p>
+     * Deserializes an Object from an array of bytes.
+	 * <p/>
+	 * Delegates to {@link #deserialize(java.io.InputStream, ClassLoader)} using a
+	 *  {@link ByteArrayInputStream} to wrap the array.
      *
      * @param objectData  the serialized object, must not be null
+	 * @param loader The classloader to use
+	 *
      * @return the deserialized object
+	 *
      * @throws IllegalArgumentException if <code>objectData</code> is <code>null</code>
      * @throws SerializationException (runtime) if the serialization fails
      */
-    public static Object deserialize(byte[] objectData) throws SerializationException {
-        if (objectData == null) {
-            throw new IllegalArgumentException("The byte[] must not be null");
+    public static Object deserialize(byte[] objectData, ClassLoader loader) throws SerializationException {
+        if ( objectData == null ) {
+            throw new IllegalArgumentException( "The byte[] must not be null" );
         }
-        ByteArrayInputStream bais = new ByteArrayInputStream(objectData);
-        return deserialize(bais);
+        ByteArrayInputStream bais = new ByteArrayInputStream( objectData );
+        return deserialize( bais, loader );
     }
 
 
@@ -218,28 +266,27 @@
 	 * the same purpose).
 	 */
 	private static final class CustomObjectInputStream extends ObjectInputStream {
+		private final ClassLoader loader;
 
-		public CustomObjectInputStream(InputStream in) throws IOException {
-			super(in);
+		private CustomObjectInputStream(InputStream in, ClassLoader loader) throws IOException {
+			super( in );
+			this.loader = loader;
 		}
 
 		protected Class resolveClass(ObjectStreamClass v) throws IOException, ClassNotFoundException {
 			String className = v.getName();
-			Class resolvedClass = null;
-
 			log.trace("Attempting to locate class [" + className + "]");
 
-			ClassLoader loader = Thread.currentThread().getContextClassLoader();
-			try {
-				resolvedClass = loader.loadClass(className);
-				log.trace("Class resolved through context class loader");
+			if ( loader != null ) {
+				try {
+					return Class.forName( className, false, loader );
+				}
+				catch (ClassNotFoundException e) {
+					log.trace( "Unable to locate class using given classloader" );
+				}
 			}
-			catch(ClassNotFoundException e) {
-				log.trace("Asking super to resolve");
-				resolvedClass = super.resolveClass(v);
-			}
 
-			return resolvedClass;
+			return super.resolveClass( v );
 		}
 	}
 }



More information about the hibernate-commits mailing list