Skip to content

Commit

Permalink
WELD-56
Browse files Browse the repository at this point in the history
  • Loading branch information
nickarls committed Mar 24, 2010
1 parent 29fbf4f commit 0f3d1f2
Show file tree
Hide file tree
Showing 12 changed files with 413 additions and 51 deletions.
Expand Up @@ -66,6 +66,7 @@
import org.jboss.weld.persistence.PersistenceApiAbstraction;
import org.jboss.weld.servlet.ServletApiAbstraction;
import org.jboss.weld.util.reflection.Reflections;
import org.jboss.weld.util.reflection.instantiation.InstantiatorFactory;
import org.jboss.weld.ws.WSApiAbstraction;
import org.slf4j.cal10n.LocLogger;

Expand Down Expand Up @@ -302,7 +303,7 @@ protected boolean isTypeManagedBeanOrDecoratorOrInterceptor(WeldClass<?> clazz)
!servletApiAbstraction.SERVLET_REQUEST_LISTENER_CLASS.isAssignableFrom(javaClass) &&
!ejbApiAbstraction.ENTERPRISE_BEAN_CLASS.isAssignableFrom(javaClass) &&
!jsfApiAbstraction.UICOMPONENT_CLASS.isAssignableFrom(javaClass) &&
hasSimpleWebBeanConstructor(clazz);
(hasSimpleWebBeanConstructor(clazz) || InstantiatorFactory.useInstantiators());
}

protected boolean isEEResourceProducerField(WeldField<?, ?> field)
Expand Down
Expand Up @@ -50,6 +50,9 @@ public enum ReflectionMessage
@MessageId("000612") UNABLE_TO_GET_FIELD_ON_DESERIALIZATION,
@MessageId("000613") UNABLE_TO_GET_PARAMETER_ON_DESERIALIZATION,
@MessageId("000614") INCORRECT_NUMBER_OF_ANNOTATED_PARAMETERS_METHOD,
@MessageId("000615") INCORRECT_NUMBER_OF_ANNOTATED_PARAMETERS_CONSTRUCTOR;
@MessageId("000615") INCORRECT_NUMBER_OF_ANNOTATED_PARAMETERS_CONSTRUCTOR,
@MessageId("000616") REFLECTIONFACTORY_INSTANTIATION_FAILED,
@MessageId("000617") UNSAFE_INSTANTIATION_FAILED,
@MessageId("000618") METHODHANDLER_SET_FAILED;

}
123 changes: 75 additions & 48 deletions impl/src/main/java/org/jboss/weld/util/Proxies.java
Expand Up @@ -17,6 +17,7 @@
package org.jboss.weld.util;

import static org.jboss.weld.logging.messages.UtilMessage.CANNOT_PROXY_NON_CLASS_TYPE;
import static org.jboss.weld.logging.messages.ReflectionMessage.METHODHANDLER_SET_FAILED;
import static org.jboss.weld.logging.messages.UtilMessage.INSTANCE_NOT_A_PROXY;
import static org.jboss.weld.logging.messages.ValidatorMessage.NOT_PROXYABLE_ARRAY_TYPE;
import static org.jboss.weld.logging.messages.ValidatorMessage.NOT_PROXYABLE_FINAL_TYPE_OR_METHOD;
Expand All @@ -43,8 +44,10 @@

import org.jboss.weld.exceptions.ForbiddenArgumentException;
import org.jboss.weld.exceptions.UnproxyableResolutionException;
import org.jboss.weld.exceptions.WeldException;
import org.jboss.weld.util.reflection.Reflections;
import org.jboss.weld.util.reflection.SecureReflections;
import org.jboss.weld.util.reflection.instantiation.InstantiatorFactory;

/**
* Utilties for working with Javassist proxies
Expand All @@ -55,17 +58,18 @@
*/
public class Proxies
{

private static class IgnoreFinalizeMethodFilter implements MethodFilter, Serializable
{
private static final long serialVersionUID = 1L;

public boolean isHandled(Method m)
{
return !m.getName().equals("finalize");
}

}

public static class TypeInfo
{

Expand Down Expand Up @@ -109,10 +113,10 @@ private Class<?>[] getInterfaces()
public ProxyFactory createProxyFactory()
{
ProxyFactory proxyFactory = new ProxyFactory();
ProxyFactory.useCache = false;
ProxyFactory.useCache = false;
proxyFactory.setFilter(new IgnoreFinalizeMethodFilter());
Class<?> superClass = getSuperClass();
if(superClass != null && superClass != Object.class)
if (superClass != null && superClass != Object.class)
{
proxyFactory.setSuperclass(superClass);
}
Expand All @@ -136,7 +140,7 @@ public TypeInfo add(Type type)
}
else if (type instanceof ParameterizedType)
{
add(((ParameterizedType)type).getRawType());
add(((ParameterizedType) type).getRawType());
}
else
{
Expand All @@ -154,16 +158,14 @@ public static TypeInfo of(Set<? extends Type> types)
}
return typeInfo;
}

public static TypeInfo create()
{
return new TypeInfo();
}

}

private static final String DEFAULT_INTERCEPTOR = "default_interceptor";


/**
* Create a proxy with a handler, registering the proxy for cleanup
*
Expand All @@ -176,9 +178,32 @@ public static TypeInfo create()
*/
public static <T> T createProxy(MethodHandler methodHandler, TypeInfo typeInfo) throws IllegalAccessException, InstantiationException
{
return SecureReflections.newInstance(Proxies.<T>createProxyClass(methodHandler, typeInfo));
if (InstantiatorFactory.useInstantiators())
{
Class<T> proxyClass = Proxies.<T> createProxyClass(methodHandler, typeInfo);
T instance = SecureReflections.newUnsafeInstance(proxyClass);
setMethodHandler(proxyClass, instance, methodHandler);
return instance;
}
else
{
return SecureReflections.newInstance(Proxies.<T> createProxyClass(methodHandler, typeInfo));
}
}


private static <T> void setMethodHandler(Class<T> clazz, T instance, MethodHandler methodHandler)
{
try
{
Method setter = SecureReflections.getDeclaredMethod(clazz, "setHandler", MethodHandler.class);
SecureReflections.invoke(instance, setter, methodHandler);
}
catch (Exception e)
{
throw new WeldException(METHODHANDLER_SET_FAILED, e, clazz);
}
}

/**
* Create a proxy class
*
Expand All @@ -192,7 +217,7 @@ public static <T> Class<T> createProxyClass(TypeInfo typeInfo)
{
return createProxyClass(null, typeInfo);
}

/**
* Create a proxy class
*
Expand All @@ -207,7 +232,7 @@ public static <T> Class<T> createProxyClass(MethodHandler methodHandler, TypeInf
{
ProxyFactory proxyFactory = typeInfo.createProxyFactory();
attachMethodHandler(proxyFactory, methodHandler);

@SuppressWarnings("unchecked")
Class<T> clazz = proxyFactory.createClass();
return clazz;
Expand All @@ -223,7 +248,7 @@ public static boolean isTypeProxyable(Type type)
{
return getUnproxyableTypeException(type) == null;
}

public static UnproxyableResolutionException getUnproxyableTypeException(Type type)
{
if (type instanceof Class<?>)
Expand All @@ -240,7 +265,6 @@ else if (type instanceof ParameterizedType)
}
return new UnproxyableResolutionException(NOT_PROXYABLE_UNKNOWN, type);
}


/**
* Indicates if a set of types are all proxyable
Expand Down Expand Up @@ -269,51 +293,55 @@ public static UnproxyableResolutionException getUnproxyableTypesException(Iterab
}
return null;
}

private static UnproxyableResolutionException getUnproxyableClassException(Class<?> clazz)
{
if (clazz.isInterface())
{
return null;
}
else
Constructor<?> constructor = null;
try
{
Constructor<?> constructor = null;
try
{
constructor = SecureReflections.getDeclaredConstructor(clazz);
}
catch (NoSuchMethodException e)
{
return new UnproxyableResolutionException(NOT_PROXYABLE_NO_CONSTRUCTOR, clazz);
}
if (constructor == null)
constructor = SecureReflections.getDeclaredConstructor(clazz);
}
catch (NoSuchMethodException e)
{
if (!InstantiatorFactory.useInstantiators())
{
return new UnproxyableResolutionException(NOT_PROXYABLE_NO_CONSTRUCTOR, clazz);
}
else if (Modifier.isPrivate(constructor.getModifiers()))
{
return new UnproxyableResolutionException(NOT_PROXYABLE_PRIVATE_CONSTRUCTOR, clazz, constructor);
}
else if (Reflections.isTypeOrAnyMethodFinal(clazz))
{
return new UnproxyableResolutionException(NOT_PROXYABLE_FINAL_TYPE_OR_METHOD, clazz, Reflections.getFinalMethodOrType(clazz));
}
else if (clazz.isPrimitive())
{
return new UnproxyableResolutionException(NOT_PROXYABLE_PRIMITIVE, clazz);
}
else if (Reflections.isArrayType(clazz))
{
return new UnproxyableResolutionException(NOT_PROXYABLE_ARRAY_TYPE, clazz);
}
else
{
return null;
}
}
if (constructor == null)
{
return new UnproxyableResolutionException(NOT_PROXYABLE_NO_CONSTRUCTOR, clazz);
}
else if (Modifier.isPrivate(constructor.getModifiers()))
{
return new UnproxyableResolutionException(NOT_PROXYABLE_PRIVATE_CONSTRUCTOR, clazz, constructor);
}
else if (Reflections.isTypeOrAnyMethodFinal(clazz))
{
return new UnproxyableResolutionException(NOT_PROXYABLE_FINAL_TYPE_OR_METHOD, clazz, Reflections.getFinalMethodOrType(clazz));
}
else if (clazz.isPrimitive())
{
return new UnproxyableResolutionException(NOT_PROXYABLE_PRIMITIVE, clazz);
}
else if (Reflections.isArrayType(clazz))
{
return new UnproxyableResolutionException(NOT_PROXYABLE_ARRAY_TYPE, clazz);
}
else
{
return null;
}
}

public static ProxyFactory attachMethodHandler(ProxyFactory proxyFactory, MethodHandler methodHandler)
{
if (methodHandler != null)
Expand All @@ -322,7 +350,7 @@ public static ProxyFactory attachMethodHandler(ProxyFactory proxyFactory, Method
}
return proxyFactory;
}

public static <T> T attachMethodHandler(T instance, MethodHandler methodHandler)
{
if (instance instanceof ProxyObject)
Expand All @@ -337,8 +365,7 @@ public static <T> T attachMethodHandler(T instance, MethodHandler methodHandler)
{
throw new ForbiddenArgumentException(INSTANCE_NOT_A_PROXY, instance);
}

}

}

}
Expand Up @@ -26,6 +26,7 @@
import java.lang.reflect.Method;

import org.jboss.weld.exceptions.DeploymentException;
import org.jboss.weld.util.reflection.instantiation.InstantiatorFactory;

/**
*
Expand Down Expand Up @@ -397,6 +398,29 @@ protected Object work() throws Exception
}.runAsInstantiation();
}

/**
* Creates a new instance of a class using unportable methods, if available
*
* @param <T> The type of the instance
* @param clazz The class to construct from
* @return The new instance
* @throws InstantiationException If the instance could not be create
* @throws IllegalAccessException If there was an illegal access attempt
* @see java.lang.Class#newInstance()
*/
@SuppressWarnings("unchecked")
public static <T> T newUnsafeInstance(final Class<T> clazz) throws InstantiationException, IllegalAccessException
{
return (T) new SecureReflectionAccess()
{
@Override
protected Object work() throws Exception
{
return InstantiatorFactory.getInstantiator().instantiate(clazz);
}
}.runAsInstantiation();
}

/**
* Looks up a method in an inheritance hierarchy
*
Expand Down
@@ -0,0 +1,41 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2010, Red Hat, Inc. and/or its affiliates, and individual
* contributors by the @authors tag. See the copyright.txt in the
* distribution for a full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.weld.util.reflection.instantiation;

/**
* An interface for instantiating classes using non-portable reflection methods
*
* @author Nicklas Karlsson
*
*/
public interface Instantiator
{
/**
* Create a new instance of a class
* @param <T> The type of the class
* @param clazz The class
* @return The created instance
*/
public abstract <T> T instantiate(Class<T> clazz);

/**
* Used for checking if this particular instantiation method is available in the environment
*
* @return True if available, false otherwise
*/
public abstract boolean isAvailable();
}

0 comments on commit 0f3d1f2

Please sign in to comment.