[jboss-cvs] JBossAS SVN: r106447 - projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Jul 6 11:09:43 EDT 2010


Author: kabir.khan at jboss.com
Date: 2010-07-06 11:09:43 -0400 (Tue, 06 Jul 2010)
New Revision: 106447

Modified:
   projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/IntrospectionTypeInfoFactoryImpl.java
   projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/ReflectConstructorInfoImpl.java
   projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/ReflectFieldInfoImpl.java
   projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/ReflectMethodInfoImpl.java
Log:
[JBREFLECT-133] Only store a reference to the underlying java.lang.reflect member in Reflect[Constructor/Field/Method]InfoImpl once someone tries to call the member. No other data is needed, and the reference wastes memory

Modified: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/IntrospectionTypeInfoFactoryImpl.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/IntrospectionTypeInfoFactoryImpl.java	2010-07-06 14:57:28 UTC (rev 106446)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/IntrospectionTypeInfoFactoryImpl.java	2010-07-06 15:09:43 UTC (rev 106447)
@@ -158,8 +158,6 @@
          Constructor<?>[] constructors = getDeclaredConstructors(clazz);
          if (constructors != null && constructors.length > 0)
          {
-            ClassLoader requesting = SecurityActions.getClassLoaderOrSystemClassLoader(clazz);
-
             infos = new ReflectConstructorInfoImpl[constructors.length];
             for (int i = 0; i < constructors.length; ++i)
             {
@@ -179,7 +177,6 @@
                      getClassInfos(constructors[i].getGenericExceptionTypes()), 
                      constructors[i].getModifiers(),
                      (ClassInfo) getTypeInfo(constructors[i].getDeclaringClass()));
-               infos[i].setConstructor(constructors[i]);
             }
          }
       }
@@ -198,8 +195,6 @@
             if (fields == null || fields.length == 0)
                return null;
             
-            ClassLoader requesting = SecurityActions.getClassLoaderOrSystemClassLoader(clazz);
-
             ReflectFieldInfoImpl[] infos = new ReflectFieldInfoImpl[fields.length];
             for (int i = 0; i < fields.length; ++i)
             {
@@ -209,7 +204,6 @@
                      getTypeInfo(fields[i].getGenericType()), 
                      fields[i].getModifiers(), 
                      (ClassInfo) getTypeInfo(fields[i].getDeclaringClass()));
-               infos[i].setField(fields[i]);
             }
 
             return infos;
@@ -229,8 +223,6 @@
             if (methods == null || methods.length == 0)
                return null;
 
-            ClassLoader requesting = SecurityActions.getClassLoaderOrSystemClassLoader(clazz);
-
             ReflectMethodInfoImpl[] infos = new ReflectMethodInfoImpl[methods.length];
             for (int i = 0; i < methods.length; ++i)
             {

Modified: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/ReflectConstructorInfoImpl.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/ReflectConstructorInfoImpl.java	2010-07-06 14:57:28 UTC (rev 106446)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/ReflectConstructorInfoImpl.java	2010-07-06 15:09:43 UTC (rev 106447)
@@ -24,6 +24,10 @@
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
 
 import org.jboss.reflect.plugins.ConstructorInfoImpl;
 import org.jboss.reflect.spi.AnnotationValue;
@@ -43,7 +47,7 @@
    private static final long serialVersionUID = 2;
    
    /** The constructor */
-   protected transient Constructor<?> constructor;
+   protected transient volatile Constructor<?> constructor;
 
    /**
     * Create a new ConstructorInfo.
@@ -82,48 +86,68 @@
    }
 
    /**
-    * Set the constructor
-    * 
-    * @param constructor the constructor
-    */
-   public void setConstructor(Constructor<?> constructor)
-   {
-      this.constructor = constructor;
-   }
-
-   /**
     * Get the constructor
     * 
     * @return the constructor
     */
    public Constructor<?> getConstructor()
    {
+      if (constructor == null)
+         initConstructor();
       return constructor;
    }
 
    @Override
    public Object newInstance(Object[] args) throws Throwable
    {
+      if (constructor == null)
+         initConstructor();
       return ReflectionUtils.newInstance(constructor, args);
    }
 
-   /**
-    * Read the object, handling constructor read.
-    *
-    * @param oistream the stream
-    * @throws IOException io error
-    * @throws ClassNotFoundException cnf error
-    * @throws NoSuchMethodException no such method error
-    */
-   @SuppressWarnings("deprecation")
-   private void readObject(ObjectInputStream oistream)
-         throws IOException, ClassNotFoundException, NoSuchMethodException
+   protected synchronized void initConstructor()
    {
-      oistream.defaultReadObject();
+      if (constructor != null)
+         return;
       int length = parameterTypes != null ? parameterTypes.length : 0;
       Class<?>[] classes = new Class<?>[length];
       for(int i = 0; i < length; i++)
          classes[i] = parameterTypes[i].getType();
-      constructor = ReflectionUtils.findExactConstructor(getDeclaringClass().getType(), classes);
+      try
+      {
+         constructor = findConstructor(classes);
+      }
+      catch (NoSuchMethodException e)
+      {
+         throw new RuntimeException(e);
+      }
    }
+   
+   private Constructor<?> findConstructor(final Class<?>[] classes) throws NoSuchMethodException
+   {
+      if (System.getSecurityManager() == null)
+         return ReflectionUtils.findExactConstructor(getDeclaringClass().getType(), classes);
+      else
+      {
+         try
+         {
+            return AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>()
+            {
+
+               public Constructor<?> run() throws Exception
+               {
+                  return ReflectionUtils.findExactConstructor(getDeclaringClass().getType(), classes);
+               }
+            });
+         }
+         catch (PrivilegedActionException e)
+         {
+            if (e.getCause() instanceof NoSuchMethodException)
+               throw (NoSuchMethodException)e.getCause();
+            if (e.getCause() instanceof RuntimeException)
+               throw (RuntimeException)e.getCause();
+            throw new RuntimeException(e.getCause());
+         }
+      }
+   }
 }

Modified: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/ReflectFieldInfoImpl.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/ReflectFieldInfoImpl.java	2010-07-06 14:57:28 UTC (rev 106446)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/ReflectFieldInfoImpl.java	2010-07-06 15:09:43 UTC (rev 106447)
@@ -21,14 +21,14 @@
 */
 package org.jboss.reflect.plugins.introspection;
 
-import java.io.IOException;
-import java.io.ObjectInputStream;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.ReflectPermission;
 import java.security.AccessController;
 import java.security.Permission;
 import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
 
 import org.jboss.reflect.plugins.FieldInfoImpl;
 import org.jboss.reflect.spi.AnnotationValue;
@@ -51,7 +51,7 @@
    private static Permission accessCheck = new ReflectPermission("suppressAccessChecks");
 
    /** The field */
-   protected transient Field field;
+   protected transient volatile Field field;
 
    /**
     * Create a new field info
@@ -89,7 +89,7 @@
       if (isPublic() == false && field != null)
          setAccessible();
    }
-
+   
    /**
     * Get the field
     *
@@ -98,6 +98,8 @@
    public Field getField()
    {
       accessCheck();
+      if (field == null)
+         initField();
       return field;
    }
 
@@ -127,6 +129,8 @@
    @Override
    public Object get(Object target) throws Throwable
    {
+      if (field == null)
+         initField();
       accessCheck();
       return ReflectionUtils.getField(field, target);
    }
@@ -134,27 +138,13 @@
    @Override
    public Object set(Object target, Object value) throws Throwable
    {
+      if (field == null)
+         initField();
       accessCheck();
       return ReflectionUtils.setField(field, target, value);
    }
 
    /**
-    * Read the object, handling field read.
-    *
-    * @param oistream the stream
-    * @throws IOException io error
-    * @throws ClassNotFoundException cnf error
-    * @throws NoSuchFieldException no such field error
-    */
-   @SuppressWarnings("deprecation")
-   private void readObject(ObjectInputStream oistream)
-         throws IOException, ClassNotFoundException, NoSuchFieldException
-   {
-      oistream.defaultReadObject();
-      setField(ReflectionUtils.findExactField(getDeclaringClass().getType(), name));
-   }
-
-   /**
     * Set field accessible to true
     */
    private void setAccessible()
@@ -177,4 +167,47 @@
          return null;
       }
    }
+   
+   private synchronized void initField()
+   {
+      if (field != null)
+         return;
+      try
+      {
+         setField(findField());
+      }
+      catch (NoSuchFieldException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+   
+   private Field findField() throws NoSuchFieldException
+   {
+      if (System.getSecurityManager() == null)
+         return ReflectionUtils.findExactField(getDeclaringClass().getType(), name);
+      else
+      {
+         try
+         {
+            return AccessController.doPrivileged(new PrivilegedExceptionAction<Field>()
+            {
+
+               public Field run() throws Exception
+               {
+                  return ReflectionUtils.findExactField(getDeclaringClass().getType(), name);
+               }
+            });
+         }
+         catch (PrivilegedActionException e)
+         {
+            if (e.getCause() instanceof NoSuchFieldException)
+               throw (NoSuchFieldException)e.getCause();
+            if (e.getCause() instanceof RuntimeException)
+               throw (RuntimeException)e.getCause();
+            throw new RuntimeException(e.getCause());
+         }
+      }
+   }
+   
 }

Modified: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/ReflectMethodInfoImpl.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/ReflectMethodInfoImpl.java	2010-07-06 14:57:28 UTC (rev 106446)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/ReflectMethodInfoImpl.java	2010-07-06 15:09:43 UTC (rev 106447)
@@ -21,18 +21,19 @@
 */
 package org.jboss.reflect.plugins.introspection;
 
-import java.io.IOException;
-import java.io.ObjectInputStream;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.ReflectPermission;
 import java.security.AccessController;
 import java.security.Permission;
 import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
 
 import org.jboss.reflect.plugins.MethodInfoImpl;
 import org.jboss.reflect.spi.AnnotationValue;
 import org.jboss.reflect.spi.ClassInfo;
+import org.jboss.reflect.spi.MethodInfo;
 import org.jboss.reflect.spi.ParameterInfo;
 import org.jboss.reflect.spi.TypeInfo;
 
@@ -51,9 +52,9 @@
    /** The permission */
    private static Permission accessCheck = new ReflectPermission("suppressAccessChecks");
 
-   /** The method */
-   protected transient Method method;
-
+   /** The method, this only gets initialized after invoke() has been called to save memory */
+   protected transient volatile Method method;
+   
    /**
     * Create a new method info
     */
@@ -109,10 +110,6 @@
          accessCheck(isDeclaringClassPublic);
       }
 
-      this.method = method;
-
-      if (method != null && (isPublic() == false || isDeclaringClassPublic == false))
-         setAccessible();
    }
 
    /**
@@ -123,6 +120,8 @@
    public Method getMethod()
    {
       accessCheck();
+      if (method == null)
+         initMethod();
       return method;
    }
 
@@ -137,7 +136,7 @@
       Class<?> owner = method.getDeclaringClass();
       return Modifier.isPublic(owner.getModifiers());
    }
-
+   
    /**
     * Check access permission.
     */
@@ -164,31 +163,13 @@
    @Override
    public Object invoke(Object target, Object[] args) throws Throwable
    {
+      if (method == null)
+         initMethod();
       accessCheck();
       return ReflectionUtils.invoke(method, target, args);
    }
 
    /**
-    * Read the object, handling method read.
-    *
-    * @param oistream the stream
-    * @throws IOException io error
-    * @throws ClassNotFoundException cnf error
-    * @throws NoSuchMethodException no such method error
-    */
-   @SuppressWarnings("deprecation")
-   private void readObject(ObjectInputStream oistream)
-         throws IOException, ClassNotFoundException, NoSuchMethodException
-   {
-      oistream.defaultReadObject();
-      int length = parameterTypes != null ? parameterTypes.length : 0;
-      Class<?>[] classes = new Class<?>[length];
-      for(int i = 0; i < length; i++)
-         classes[i] = parameterTypes[i].getType();
-      method = ReflectionUtils.findExactMethod(getDeclaringClass().getType(), name, classes);
-   }
-
-   /**
     * Set field accessible to true
     */
    private void setAccessible()
@@ -211,4 +192,51 @@
          return null;
       }
    }
+   
+   protected synchronized void initMethod()
+   {
+      int length = parameterTypes != null ? parameterTypes.length : 0;
+      Class<?>[] classes = new Class<?>[length];
+      for(int i = 0; i < length; i++)
+         classes[i] = parameterTypes[i].getType();
+      try
+      {
+         method = findMethod(classes);
+      }
+      catch (NoSuchMethodException e)
+      {
+         throw new RuntimeException(e);
+      }
+
+      if (method != null && (isPublic() == false || isDeclaringClassPublic(method) == false))
+         setAccessible();
+   }
+   
+   private Method findMethod(final Class<?>[] classes) throws NoSuchMethodException
+   {
+      if (System.getSecurityManager() == null)
+         return ReflectionUtils.findExactMethod(getDeclaringClass().getType(), name, classes);
+      else
+      {
+         try
+         {
+            return AccessController.doPrivileged(new PrivilegedExceptionAction<Method>()
+            {
+
+               public Method run() throws Exception
+               {
+                  return ReflectionUtils.findExactMethod(getDeclaringClass().getType(), name, classes);
+               }
+            });
+         }
+         catch (PrivilegedActionException e)
+         {
+            if (e.getCause() instanceof NoSuchMethodException)
+               throw (NoSuchMethodException)e.getCause();
+            if (e.getCause() instanceof RuntimeException)
+               throw (RuntimeException)e.getCause();
+            throw new RuntimeException(e.getCause());
+         }
+      }
+   }
 }



More information about the jboss-cvs-commits mailing list