[jboss-dev] Small boottime improvement

Carlo de Wolf cdewolf at redhat.com
Wed Feb 17 06:25:30 EST 2010


It's this piece of code:

package org.jboss.hack;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
* Fast method finder.
*
* @author <a href="mailto:cdewolf at redhat.com">Carlo de Wolf</a>
*/
public class ClassHack
{
private static Method COPY;

private static Method PRIVATE_GET_DECLARED_METHODS;

private static Method SEARCH_METHODS;

static
{
try
{
COPY = Method.class.getDeclaredMethod("copy");
COPY.setAccessible(true);

PRIVATE_GET_DECLARED_METHODS = 
Class.class.getDeclaredMethod("privateGetDeclaredMethods", Boolean.TYPE);
PRIVATE_GET_DECLARED_METHODS.setAccessible(true);

SEARCH_METHODS = Class.class.getDeclaredMethod("searchMethods", 
Method[].class, String.class, Class[].class);
SEARCH_METHODS.setAccessible(true);
}
catch (SecurityException e)
{
throw new RuntimeException(e);
}
catch (NoSuchMethodException e)
{
throw new RuntimeException(e);
}
}

/**
* Returns a safe copy of the method.
*
* @param unsafeMethod
* @return
*/
private static Method copy(Method unsafeMethod)
{
// TODO: should really use ReflectAccess / LangReflectAccess
try
{
return (Method) COPY.invoke(unsafeMethod);
}
catch (IllegalArgumentException e)
{
throw new RuntimeException(e);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
catch (InvocationTargetException e)
{
throw new RuntimeException(e);
}
}

public static Method findMethod(Class<?> cls, String name, Class<?>... 
parameterTypes)
{
if(cls == null)
return null;

Method unsafeMethods[] = getDeclaredMethods(cls, false);
Method unsafeMethod = searchMethods(unsafeMethods, name, parameterTypes);
if(unsafeMethod != null)
return copy(unsafeMethod);
return findMethod(cls.getSuperclass(), name, parameterTypes);
}

/**
* Very unsafe, returns references to the cache.
*
* @param publicOnly
* @return
*/
private static Method[] getDeclaredMethods(Class<?> cls, boolean publicOnly)
{
try
{
return (Method[]) PRIVATE_GET_DECLARED_METHODS.invoke(cls, publicOnly);
}
catch (IllegalArgumentException e)
{
throw new RuntimeException(e);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
catch (InvocationTargetException e)
{
throw new RuntimeException(e);
}
}

public static Method searchMethods(Method[] methods, String name, 
Class<?>[] parameterTypes)
{
try
{
return (Method) SEARCH_METHODS.invoke(null, methods, name, parameterTypes);
}
catch (IllegalArgumentException e)
{
throw new RuntimeException(e);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
catch (InvocationTargetException e)
{
throw new RuntimeException(e);
}
}
}

I never committed it, because as Bill says it's a Bad Thing. Not only 
does it abuse internal methods it also exposes Methods from a cache that 
lead to huge security holes. So don't commit it, ever. :-)

The important bit is that scanning annotations using reflection is 
extremely slow, so never do that either.

Carlo

On 02/16/2010 02:20 PM, Kabir Khan wrote:
> On 16 Feb 2010, at 12:12, Jaikiran Pai wrote:
>
>    
>> Kabir Khan wrote:
>>      
>>> On 15 Feb 2010, at 15:35, Bill Burke wrote:
>>>
>>>        
>>>> is probably BeanInfo creation (all the reflection stuff).  I personally
>>>>          
>>> Yeah, I have seen that they take a fair amount of time, but when digging in most of the time is taken in java.lang.reflect.getDeclaredMethods/Constructors. BeanInfo does not seem to add anything significant on top
>>>        
>> I haven't looked in the latest profiler snapshots, but the last time i
>> checked, we noticed this http://community.jboss.org/message/434125#434125
>>      
> Are these the "Reflection hacks" Bill was mentioning earlier?
>
>
> _______________________________________________
> jboss-development mailing list
> jboss-development at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/jboss-development
>    




More information about the jboss-development mailing list