### Eclipse Workspace Patch 1.0 #P weld-core Index: src/main/java/org/jboss/weld/bean/proxy/DecoratorProxyMethodHandler.java =================================================================== --- src/main/java/org/jboss/weld/bean/proxy/DecoratorProxyMethodHandler.java (revision 5362) +++ src/main/java/org/jboss/weld/bean/proxy/DecoratorProxyMethodHandler.java (working copy) @@ -30,7 +30,7 @@ import org.jboss.weld.introspector.WeldMethod; import org.jboss.weld.introspector.jlr.MethodSignatureImpl; import org.jboss.weld.serialization.spi.helpers.SerializableContextualInstance; -import org.jboss.weld.util.reflection.Reflections; +import org.jboss.weld.util.reflection.SecureReflections; /** * Method handler for decorated beans @@ -97,6 +97,6 @@ throw new ForbiddenStateException(UNEXPECTED_UNWRAPPED_CUSTOM_DECORATOR, beanInstance.getContextual().get()); } } - return Reflections.invoke(method, getTargetInstance(), args); + return SecureReflections.invoke(getTargetInstance(), method, args); } } Index: src/main/java/org/jboss/weld/introspector/jlr/WeldAnnotationImpl.java =================================================================== --- src/main/java/org/jboss/weld/introspector/jlr/WeldAnnotationImpl.java (revision 5362) +++ src/main/java/org/jboss/weld/introspector/jlr/WeldAnnotationImpl.java (working copy) @@ -32,6 +32,7 @@ import org.jboss.weld.resources.ClassTransformer; import org.jboss.weld.util.Names; import org.jboss.weld.util.reflection.HierarchyDiscovery; +import org.jboss.weld.util.reflection.SecureReflections; import com.google.common.base.Supplier; import com.google.common.collect.Multimaps; @@ -89,7 +90,7 @@ }); this.namedMembers = new HashMap>(); - for (Method member : clazz.getDeclaredMethods()) + for (Method member : SecureReflections.getDeclaredMethods(clazz)) { WeldMethod annotatedMethod = WeldMethodImpl.of(member, this, classTransformer); members.add(annotatedMethod); Index: src/main/java/org/jboss/weld/util/Proxies.java =================================================================== --- src/main/java/org/jboss/weld/util/Proxies.java (revision 5362) +++ src/main/java/org/jboss/weld/util/Proxies.java (working copy) @@ -33,6 +33,7 @@ import org.jboss.weld.ForbiddenArgumentException; import org.jboss.weld.util.reflection.Reflections; +import org.jboss.weld.util.reflection.SecureReflections; /** * Utilties for working with Javassist proxies @@ -139,7 +140,7 @@ public static T createProxy(MethodHandler methodHandler, TypeInfo typeInfo) throws IllegalAccessException, InstantiationException { - return Proxies.createProxyClass(methodHandler, typeInfo).newInstance(); + return SecureReflections.newInstance(Proxies.createProxyClass(methodHandler, typeInfo)); } public static Class createProxyClass(TypeInfo typeInfo) @@ -215,7 +216,15 @@ } else { - Constructor constructor = Reflections.getDeclaredConstructor(clazz); + Constructor constructor = null; + try + { + constructor = SecureReflections.getDeclaredConstructor(clazz); + } + catch (NoSuchMethodException e) + { + return false; + } if (constructor == null) { return false; Index: src/main/java/org/jboss/weld/bean/proxy/ClientProxyMethodHandler.java =================================================================== --- src/main/java/org/jboss/weld/bean/proxy/ClientProxyMethodHandler.java (revision 5362) +++ src/main/java/org/jboss/weld/bean/proxy/ClientProxyMethodHandler.java (working copy) @@ -34,6 +34,7 @@ import org.jboss.weld.context.WeldCreationalContext; import org.jboss.weld.serialization.spi.ContextualStore; import org.jboss.weld.util.reflection.Reflections; +import org.jboss.weld.util.reflection.SecureReflections; import org.slf4j.cal10n.LocLogger; /** @@ -110,8 +111,8 @@ } try { - Method method = Reflections.lookupMethod(proxiedMethod, proxiedInstance); - Object returnValue = Reflections.invoke(method, proxiedInstance, args); + Method method = SecureReflections.lookupMethod(proxiedInstance, proxiedMethod); + Object returnValue = SecureReflections.invoke(proxiedInstance, method, args); log.trace(CALL_PROXIED_METHOD, proxiedMethod, proxiedInstance, args, returnValue == null ? null : returnValue); return returnValue; } Index: src/main/java/org/jboss/weld/logging/WeldMessageConveyor.java =================================================================== --- src/main/java/org/jboss/weld/logging/WeldMessageConveyor.java (revision 5362) +++ src/main/java/org/jboss/weld/logging/WeldMessageConveyor.java (working copy) @@ -5,6 +5,7 @@ import java.util.concurrent.Callable; import org.jboss.weld.util.collections.ConcurrentCache; +import org.jboss.weld.util.reflection.SecureReflections; import ch.qos.cal10n.MessageConveyor; import ch.qos.cal10n.MessageConveyorException; @@ -37,7 +38,7 @@ public String call() throws Exception { - Field field = key.getClass().getField(key.name()); + Field field = SecureReflections.getField(key.getClass(), key.name()); if (!field.isAnnotationPresent(MessageId.class)) { throw new IllegalArgumentException("@MessageId must be present. Key: " + key + "; Key Type: " + key.getClass()); Index: src/main/java/org/jboss/weld/bean/interceptor/ClassInterceptionHandlerFactory.java =================================================================== --- src/main/java/org/jboss/weld/bean/interceptor/ClassInterceptionHandlerFactory.java (revision 5362) +++ src/main/java/org/jboss/weld/bean/interceptor/ClassInterceptionHandlerFactory.java (working copy) @@ -21,12 +21,12 @@ import javax.enterprise.context.spi.CreationalContext; -import org.jboss.interceptor.proxy.InterceptionHandlerFactory; -import org.jboss.interceptor.proxy.InterceptionHandler; import org.jboss.interceptor.proxy.DirectClassInterceptionHandler; +import org.jboss.interceptor.proxy.InterceptionHandler; +import org.jboss.interceptor.proxy.InterceptionHandlerFactory; import org.jboss.weld.BeanManagerImpl; import org.jboss.weld.DeploymentException; -import org.jboss.weld.util.reflection.Reflections; +import org.jboss.weld.util.reflection.SecureReflections; /** * @author Marius Bogoevici @@ -47,8 +47,7 @@ try { // this is not a managed instance - assume no-argument constructor exists - Constructor constructor = clazz.getDeclaredConstructor(); - Reflections.ensureAccessible(constructor); + Constructor constructor = SecureReflections.getDeclaredConstructor(clazz); Object interceptorInstance = constructor.newInstance(); // inject manager.createInjectionTarget(manager.createAnnotatedType(clazz)).inject(interceptorInstance, creationalContext); Index: src/main/java/org/jboss/weld/util/serviceProvider/DefaultServiceLoader.java =================================================================== --- src/main/java/org/jboss/weld/util/serviceProvider/DefaultServiceLoader.java (revision 5362) +++ src/main/java/org/jboss/weld/util/serviceProvider/DefaultServiceLoader.java (working copy) @@ -32,6 +32,7 @@ import org.jboss.weld.ForbiddenStateException; import org.jboss.weld.InvalidOperationException; import org.jboss.weld.util.reflection.Reflections; +import org.jboss.weld.util.reflection.SecureReflections; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.ext.XLogger; @@ -212,7 +213,7 @@ { throw new ForbiddenStateException(DECLARED_EXTENSION_DOES_NOT_IMPLEMENT_EXTENSION, line); } - Constructor constructor = Reflections.ensureAccessible(serviceClass.getConstructor()); + Constructor constructor = (Constructor) SecureReflections.getConstructor(serviceClass); S instance = constructor.newInstance(); providers.add(instance); } Index: src/main/java/org/jboss/weld/util/reflection/SecureReflectionAccess.java =================================================================== --- src/main/java/org/jboss/weld/util/reflection/SecureReflectionAccess.java (revision 0) +++ src/main/java/org/jboss/weld/util/reflection/SecureReflectionAccess.java (revision 0) @@ -0,0 +1,283 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2008, Red Hat Middleware LLC, 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; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.InvocationTargetException; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; + +/** + * Helper class for doing work in a privileged context under the + * "weld.reflection" permission + */ +abstract class SecureReflectionAccess +{ + /** + * Performs the work and returns the result + * + * @return The value of the operation + * @throws Exception If the operation failed + */ + @SuppressWarnings("unchecked") + public Object run() throws Exception + { + SecurityManager securityManager = System.getSecurityManager(); + if (securityManager != null) + { + securityManager.checkPermission(new RuntimePermission("weld.reflection")); + return AccessController.doPrivileged(new PrivilegedExceptionAction() + { + public Object run() throws Exception + { + return work(); + } + }); + } + else + { + return work(); + } + } + + /** + * Runs the work and wraps the exception in a RuntimeException + * + * @return The result of the work + */ + public Object runAndWrap() + { + try + { + return run(); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + + /** + * Runs the work and unwraps and NoSuchFieldException from a possible + * PrivilegedActionException. Wraps any other exceptions in + * RuntimeException + * + * @return The result of the work (usually a Field) + * @throws NoSuchFieldException If a field with the specified name is not + * found. + */ + public Object runAsFieldAccess() throws NoSuchFieldException + { + try + { + return run(); + } + catch (PrivilegedActionException e) + { + if (e.getCause() instanceof NoSuchFieldException) + { + throw (NoSuchFieldException) e.getCause(); + } + throw new RuntimeException(e); + } + catch (NoSuchFieldException e) + { + throw e; + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + + /** + * Runs the work and unwraps and NoSuchMethodException from a possible + * PrivilegedActionException. Wraps any other exceptions in + * RuntimeException + * + * @return The result of the work (usually a Method) + * @throws NoSuchMethodException If a method with the specified name is + * not found. + */ + public Object runAsMethodAccess() throws NoSuchMethodException + { + try + { + return run(); + } + catch (PrivilegedActionException e) + { + if (e.getCause() instanceof NoSuchMethodException) + { + throw (NoSuchMethodException) e.getCause(); + } + throw new RuntimeException(e); + } + catch (NoSuchMethodException e) + { + throw e; + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + + /** + * Runs the work and unwraps any IllegalAccessException, + * IllegalArgumentException or InvocationTargetException from a possible + * PrivilegedActionException. Wraps any other exceptions in + * RuntimeException + * + * @return The return value of the method invoked + * @throws IllegalAccessException If this Method object enforces Java + * language access control and the underlying method is + * inaccessible. + * @throws IllegalArgumentException If the method is an instance method + * and the specified object argument is not an instance of the + * class or interface declaring the underlying method (or of a + * subclass or implementor thereof); if the number of actual + * and formal parameters differ; if an unwrapping conversion + * for primitive arguments fails; or if, after possible + * unwrapping, a parameter value cannot be converted to the + * corresponding formal parameter type by a method invocation + * conversion. + * @throws InvocationTargetException I the underlying method throws an + * exception. + */ + public Object runAsInvocation() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException + { + try + { + return run(); + } + catch (PrivilegedActionException e) + { + if (e.getCause() instanceof IllegalAccessException) + { + throw (IllegalAccessException) e.getCause(); + } + else if (e.getCause() instanceof IllegalArgumentException) + { + throw (IllegalArgumentException) e.getCause(); + } + else if (e.getCause() instanceof InvocationTargetException) + { + throw (InvocationTargetException) e.getCause(); + } + throw new RuntimeException(e); + } + catch (IllegalAccessException e) + { + throw (IllegalAccessException) e; + } + catch (IllegalArgumentException e) + { + throw (IllegalArgumentException) e; + } + catch (InvocationTargetException e) + { + throw (InvocationTargetException) e; + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + + /** + * Runs the work and unwraps any IllegalAccessException, + * InstantiationException or IllegalAccessException from a possible + * PrivilegedActionException. Wraps any other exceptions in + * RuntimeException + * + * @return The result of the work (usually a new instance) + * @throws InstantiationException If the class or its nullary constructor + * is not accessible. + * @throws IllegalAccessException If this Class represents an abstract + * class, an interface, an array class, a primitive type, or + * void; or if the class has no nullary constructor; or if the + * instantiation fails for some other reason. + */ + public Object runAsInstantiation() throws InstantiationException, IllegalAccessException + { + try + { + return run(); + } + catch (PrivilegedActionException e) + { + if (e.getCause() instanceof InstantiationException) + { + throw (InstantiationException) e.getCause(); + } + else if (e.getCause() instanceof IllegalAccessException) + { + throw (IllegalAccessException) e.getCause(); + } + throw new RuntimeException(e); + } + catch (InstantiationException e) + { + throw (InstantiationException) e; + } + catch (IllegalAccessException e) + { + throw (IllegalAccessException) e; + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + + /** + * Makes an list of objects accessible. Must be run from within work() or + * another privileged location + * + * @param accessibleObjects The objects to manipulate + * @return The accessible objects + */ + protected AccessibleObject[] ensureAccessible(AccessibleObject[] accessibleObjects) + { + for (AccessibleObject accessibleObject : accessibleObjects) + { + ensureAccessible(accessibleObject); + } + return accessibleObjects; + } + + /** + * Makes an object accessible. Must be run from within work() or another + * privileged location + * + * @param accessibleObjects The object to manipulate + * @return The accessible object + */ + protected AccessibleObject ensureAccessible(AccessibleObject accessibleObject) + { + if (!accessibleObject.isAccessible()) + { + accessibleObject.setAccessible(true); + } + return accessibleObject; + } + + protected abstract Object work() throws Exception; + +} Index: src/main/java/org/jboss/weld/introspector/jlr/WeldMethodImpl.java =================================================================== --- src/main/java/org/jboss/weld/introspector/jlr/WeldMethodImpl.java (revision 5362) +++ src/main/java/org/jboss/weld/introspector/jlr/WeldMethodImpl.java (working copy) @@ -16,8 +16,6 @@ */ package org.jboss.weld.introspector.jlr; -import static org.jboss.weld.util.reflection.Reflections.ensureAccessible; - import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -42,6 +40,7 @@ import org.jboss.weld.resources.ClassTransformer; import org.jboss.weld.util.reflection.HierarchyDiscovery; import org.jboss.weld.util.reflection.Reflections; +import org.jboss.weld.util.reflection.SecureReflections; import com.google.common.base.Supplier; import com.google.common.collect.ListMultimap; @@ -79,13 +78,13 @@ public static WeldMethodImpl of(Method method, WeldClass declaringClass, ClassTransformer classTransformer) { AnnotationStore annotationStore = AnnotationStore.of(method, classTransformer.getTypeStore()); - return new WeldMethodImpl(ensureAccessible(method), (Class) method.getReturnType(), method.getGenericReturnType(), new HierarchyDiscovery(method.getGenericReturnType()).getTypeClosure(), null, annotationStore, declaringClass, classTransformer); + return new WeldMethodImpl(method, (Class) method.getReturnType(), method.getGenericReturnType(), new HierarchyDiscovery(method.getGenericReturnType()).getTypeClosure(), null, annotationStore, declaringClass, classTransformer); } - + public static WeldMethodImpl of(AnnotatedMethod method, WeldClass declaringClass, ClassTransformer classTransformer) { AnnotationStore annotationStore = AnnotationStore.of(method.getAnnotations(), method.getAnnotations(), classTransformer.getTypeStore()); - return new WeldMethodImpl(ensureAccessible(method.getJavaMember()), (Class) method.getJavaMember().getReturnType(), method.getBaseType(), method.getTypeClosure(), method, annotationStore, declaringClass, classTransformer); + return new WeldMethodImpl(method.getJavaMember(), (Class) method.getJavaMember().getReturnType(), method.getBaseType(), method.getTypeClosure(), method, annotationStore, declaringClass, classTransformer); } /** @@ -106,16 +105,16 @@ this.parameters = new ArrayList>(); this.annotatedParameters = Multimaps.newListMultimap(new HashMap, Collection>>(), new Supplier>>() { - + public List> get() { return new ArrayList>(); } - + }); - + Map> annotatedTypeParameters = new HashMap>(); - + if (annotatedMethod != null) { for (AnnotatedParameter annotated : annotatedMethod.getParameters()) @@ -134,7 +133,7 @@ if (annotatedTypeParameters.containsKey(i)) { AnnotatedParameter annotatedParameter = annotatedTypeParameters.get(i); - parameter = WeldParameterImpl.of(annotatedParameter.getAnnotations(), clazz, parametertype, this, i, classTransformer); + parameter = WeldParameterImpl.of(annotatedParameter.getAnnotations(), clazz, parametertype, this, i, classTransformer); } else { @@ -155,7 +154,7 @@ Type parameterType = method.getGenericParameterTypes()[i]; WeldParameter parameter = WeldParameterImpl.of(new Annotation[0], (Class) clazz, parameterType, this, i, classTransformer); this.parameters.add(parameter); - } + } } String propertyName = Reflections.getPropertyName(getDelegate()); @@ -168,7 +167,7 @@ this.propertyName = propertyName; } this.signature = new MethodSignatureImpl(this); - + } public Method getAnnotatedMethod() @@ -222,18 +221,18 @@ return getDelegate().hashCode(); } - public T invokeOnInstance(Object instance, Object...parameters) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException + public T invokeOnInstance(Object instance, Object... parameters) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { - Method method = Reflections.lookupMethod(getName(), getParameterTypesAsArray(), instance); + Method method = SecureReflections.lookupMethod(instance.getClass(), getName(), getParameterTypesAsArray()); @SuppressWarnings("unchecked") - T result = (T) method.invoke(instance, parameters); + T result = (T) SecureReflections.invoke(instance, method, parameters); return result; } public T invoke(Object instance, Object... parameters) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { @SuppressWarnings("unchecked") - T result = (T) method.invoke(instance, parameters); + T result = (T) SecureReflections.invoke(instance, method, parameters); return result; } Index: src/main/java/org/jboss/weld/bean/ProducerMethod.java =================================================================== --- src/main/java/org/jboss/weld/bean/ProducerMethod.java (revision 5362) +++ src/main/java/org/jboss/weld/bean/ProducerMethod.java (working copy) @@ -43,6 +43,7 @@ import org.jboss.weld.introspector.WeldMethod; import org.jboss.weld.introspector.WeldParameter; import org.jboss.weld.util.Names; +import org.jboss.weld.util.reflection.SecureReflections; /** * Represents a producer method bean @@ -166,16 +167,11 @@ { if (type instanceof Class) { - Class clazz = (Class) type; - try + if (SecureReflections.methodExists((Class) type, getAnnotatedItem().getName(), getAnnotatedItem().getParameterTypesAsArray())) { - clazz.getDeclaredMethod(getAnnotatedItem().getName(), getAnnotatedItem().getParameterTypesAsArray()); methodDeclaredOnTypes = true; + continue; } - catch (NoSuchMethodException nsme) - { - // No - op - } } } if (!methodDeclaredOnTypes) Index: src/main/java/org/jboss/weld/jsf/JsfApiAbstraction.java =================================================================== --- src/main/java/org/jboss/weld/jsf/JsfApiAbstraction.java (revision 5362) +++ src/main/java/org/jboss/weld/jsf/JsfApiAbstraction.java (working copy) @@ -19,6 +19,7 @@ import org.jboss.weld.bootstrap.api.Service; import org.jboss.weld.resources.spi.ResourceLoader; import org.jboss.weld.util.ApiAbstraction; +import org.jboss.weld.util.reflection.SecureReflections; /** * Utility class for JSF related components, concepts etc. It can also @@ -45,14 +46,7 @@ double version = 2.0; if (this.FACES_CONTEXT != null) { - try - { - this.FACES_CONTEXT.getMethod("isPostback", new Class[] {}); - } - catch (NoSuchMethodException e) - { - version = 1.2; - } + version = SecureReflections.methodExists(FACES_CONTEXT, "isPostback") ? 2.0 : 1.2; } MINIMUM_API_VERSION = version; } Index: src/main/java/org/jboss/weld/introspector/jlr/WeldConstructorImpl.java =================================================================== --- src/main/java/org/jboss/weld/introspector/jlr/WeldConstructorImpl.java (revision 5362) +++ src/main/java/org/jboss/weld/introspector/jlr/WeldConstructorImpl.java (working copy) @@ -16,8 +16,6 @@ */ package org.jboss.weld.introspector.jlr; -import static org.jboss.weld.util.reflection.Reflections.ensureAccessible; - import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; @@ -75,13 +73,13 @@ public static WeldConstructor of(Constructor constructor, WeldClass declaringClass, ClassTransformer classTransformer) { AnnotationStore annotationStore = AnnotationStore.of(constructor, classTransformer.getTypeStore()); - return new WeldConstructorImpl(ensureAccessible(constructor), constructor.getDeclaringClass(), constructor.getDeclaringClass(), null, new HierarchyDiscovery(constructor.getDeclaringClass()).getTypeClosure(), annotationStore, declaringClass, classTransformer); + return new WeldConstructorImpl(constructor, constructor.getDeclaringClass(), constructor.getDeclaringClass(), null, new HierarchyDiscovery(constructor.getDeclaringClass()).getTypeClosure(), annotationStore, declaringClass, classTransformer); } public static WeldConstructor of(AnnotatedConstructor annotatedConstructor, WeldClass declaringClass, ClassTransformer classTransformer) { AnnotationStore annotationStore = AnnotationStore.of(annotatedConstructor.getAnnotations(), annotatedConstructor.getAnnotations(), classTransformer.getTypeStore()); - return new WeldConstructorImpl(ensureAccessible(annotatedConstructor.getJavaMember()), annotatedConstructor.getJavaMember().getDeclaringClass(), annotatedConstructor.getBaseType(), annotatedConstructor, annotatedConstructor.getTypeClosure(), annotationStore, declaringClass, classTransformer); + return new WeldConstructorImpl(annotatedConstructor.getJavaMember(), annotatedConstructor.getJavaMember().getDeclaringClass(), annotatedConstructor.getBaseType(), annotatedConstructor, annotatedConstructor.getTypeClosure(), annotationStore, declaringClass, classTransformer); } /** Index: src/main/java/org/jboss/weld/jsf/JsfHelper.java =================================================================== --- src/main/java/org/jboss/weld/jsf/JsfHelper.java (revision 5362) +++ src/main/java/org/jboss/weld/jsf/JsfHelper.java (working copy) @@ -35,6 +35,7 @@ import org.jboss.weld.conversation.ConversationIdName; import org.jboss.weld.servlet.ServletHelper; import org.jboss.weld.util.reflection.Reflections; +import org.jboss.weld.util.reflection.SecureReflections; import org.slf4j.cal10n.LocLogger; /** @@ -62,7 +63,7 @@ { try { - return (Boolean) Reflections.invoke("isPostback", facesContext); + return (Boolean) SecureReflections.invoke(facesContext, "isPostback"); } catch (Exception e) { Index: src/main/java/org/jboss/weld/bean/proxy/AbstractDecoratorMethodHandler.java =================================================================== --- src/main/java/org/jboss/weld/bean/proxy/AbstractDecoratorMethodHandler.java (revision 5362) +++ src/main/java/org/jboss/weld/bean/proxy/AbstractDecoratorMethodHandler.java (working copy) @@ -27,6 +27,7 @@ import org.jboss.weld.introspector.WeldClass; import org.jboss.weld.introspector.jlr.MethodSignatureImpl; import org.jboss.weld.util.reflection.Reflections; +import org.jboss.weld.util.reflection.SecureReflections; /** * {@link MethodHandler} for Abstract decorators. @@ -74,7 +75,7 @@ if (Reflections.isAbstract(thisMethod)) { Method method = ((AnnotatedMethod) delegateClass.getWeldMethod(new MethodSignatureImpl(thisMethod))).getJavaMember(); - return Reflections.invoke(method, delegate, args); + return SecureReflections.invoke(delegate, method, args); } return proceed.invoke(self, args); Index: src/main/java/org/jboss/weld/introspector/jlr/WeldFieldImpl.java =================================================================== --- src/main/java/org/jboss/weld/introspector/jlr/WeldFieldImpl.java (revision 5362) +++ src/main/java/org/jboss/weld/introspector/jlr/WeldFieldImpl.java (working copy) @@ -16,20 +16,19 @@ */ package org.jboss.weld.introspector.jlr; -import static org.jboss.weld.util.reflection.Reflections.ensureAccessible; - import java.lang.reflect.Field; import java.lang.reflect.Type; import java.util.Set; - +import static org.jboss.weld.logging.messages.UtilMessage.ACCESS_ERROR_ON_FIELD; import javax.enterprise.inject.spi.AnnotatedField; +import org.jboss.weld.WeldException; import org.jboss.weld.introspector.AnnotationStore; import org.jboss.weld.introspector.WeldClass; import org.jboss.weld.introspector.WeldField; import org.jboss.weld.resources.ClassTransformer; import org.jboss.weld.util.reflection.HierarchyDiscovery; -import org.jboss.weld.util.reflection.Reflections; +import org.jboss.weld.util.reflection.SecureReflections; /** * Represents an annotated field @@ -52,15 +51,15 @@ public static WeldFieldImpl of(Field field, WeldClass declaringClass, ClassTransformer classTransformer) { AnnotationStore annotationStore = AnnotationStore.of(field, classTransformer.getTypeStore()); - return new WeldFieldImpl(ensureAccessible(field), (Class) field.getType(), field.getGenericType(), new HierarchyDiscovery(field.getGenericType()).getTypeClosure(), annotationStore, declaringClass, classTransformer); + return new WeldFieldImpl(field, (Class) field.getType(), field.getGenericType(), new HierarchyDiscovery(field.getGenericType()).getTypeClosure(), annotationStore, declaringClass, classTransformer); } - + public static WeldFieldImpl of(AnnotatedField annotatedField, WeldClass declaringClass, ClassTransformer classTransformer) { AnnotationStore annotationStore = AnnotationStore.of(annotatedField.getAnnotations(), annotatedField.getAnnotations(), classTransformer.getTypeStore()); - return new WeldFieldImpl(ensureAccessible(annotatedField.getJavaMember()), (Class) annotatedField.getJavaMember().getType(), annotatedField.getBaseType(), annotatedField.getTypeClosure(), annotationStore, declaringClass, classTransformer); + return new WeldFieldImpl(annotatedField.getJavaMember(), (Class) annotatedField.getJavaMember().getType(), annotatedField.getBaseType(), annotatedField.getTypeClosure(), annotationStore, declaringClass, classTransformer); } - + /** * Constructor * @@ -100,13 +99,20 @@ public void setOnInstance(Object instance, Object value) throws IllegalArgumentException, SecurityException, IllegalAccessException, NoSuchFieldException { - instance.getClass().getField(getName()).set(instance, value); + SecureReflections.getField(instance.getClass(), getName()).set(instance, value); } @SuppressWarnings("unchecked") public T get(Object instance) { - return (T) Reflections.getAndWrap(getDelegate(), instance); + try + { + return (T) getDelegate().get(instance); + } + catch (Exception e) + { + throw new WeldException(ACCESS_ERROR_ON_FIELD, e, getDelegate().getName(), getDelegate().getDeclaringClass()); + } } /** @@ -146,7 +152,6 @@ } } - @Override public int hashCode() { Index: src/main/java/org/jboss/weld/util/ApiAbstraction.java =================================================================== --- src/main/java/org/jboss/weld/util/ApiAbstraction.java (revision 5362) +++ src/main/java/org/jboss/weld/util/ApiAbstraction.java (working copy) @@ -23,6 +23,7 @@ import org.jboss.weld.ForbiddenArgumentException; import org.jboss.weld.resources.spi.ResourceLoader; import org.jboss.weld.resources.spi.ResourceLoadingException; +import org.jboss.weld.util.reflection.SecureReflections; /** * A base class for utility classes that represent annotations, classes etc @@ -119,7 +120,7 @@ } try { - return clazz.getField(memberName); + return SecureReflections.getField(clazz, memberName); } catch (SecurityException e) { Index: src/main/java/org/jboss/weld/bean/proxy/EnterpriseBeanProxyMethodHandler.java =================================================================== --- src/main/java/org/jboss/weld/bean/proxy/EnterpriseBeanProxyMethodHandler.java (revision 5362) +++ src/main/java/org/jboss/weld/bean/proxy/EnterpriseBeanProxyMethodHandler.java (working copy) @@ -37,6 +37,7 @@ import org.jboss.weld.introspector.MethodSignature; import org.jboss.weld.introspector.jlr.MethodSignatureImpl; import org.jboss.weld.util.reflection.Reflections; +import org.jboss.weld.util.reflection.SecureReflections; import org.slf4j.cal10n.LocLogger; /** @@ -120,10 +121,10 @@ } Class businessInterface = getBusinessInterface(method); Object proxiedInstance = reference.getBusinessObject(businessInterface); - Method proxiedMethod = Reflections.lookupMethod(method, proxiedInstance); + Method proxiedMethod = SecureReflections.lookupMethod(proxiedInstance, method); try { - Object returnValue = Reflections.invoke(proxiedMethod, proxiedInstance, args); + Object returnValue = SecureReflections.invoke(proxiedInstance, proxiedMethod, args); log.trace(CALL_PROXIED_METHOD, method, proxiedInstance, args, returnValue); return returnValue; } Index: src/main/java/org/jboss/weld/util/Names.java =================================================================== --- src/main/java/org/jboss/weld/util/Names.java (revision 5362) +++ src/main/java/org/jboss/weld/util/Names.java (working copy) @@ -30,6 +30,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.jboss.weld.util.reflection.SecureReflections; + /** * Utility class to produce friendly names e.g. for debugging * @@ -173,10 +175,6 @@ */ public static String fieldToString(Field field) { - if (!field.isAccessible()) - { - field.setAccessible(true); - } return " Field " + annotationsToString(field.getAnnotations()) + listToString(parseModifiers(field.getModifiers()), " ") + field.getName(); } @@ -188,10 +186,6 @@ */ public static String methodToString(Method method) { - if (!method.isAccessible()) - { - method.setAccessible(true); - } return " Method " + method.getReturnType().getSimpleName() + " " + annotationsToString(method.getAnnotations()) + listToString(parseModifiers(method.getModifiers()), " ") + method.getName() + "(" + parametersToString(method.getParameterTypes(), method.getParameterAnnotations(), false) + ");\n"; } @@ -261,15 +255,15 @@ { StringBuilder buffer = new StringBuilder(); buffer.append("Class " + typeToString(clazz) + "\n"); - for (Field field : clazz.getFields()) + for (Field field : SecureReflections.getFields(clazz)) { buffer.append(fieldToString(field)); } - for (Constructor constructor : clazz.getConstructors()) + for (Constructor constructor : SecureReflections.getConstructors(clazz)) { buffer.append(constructorToString(constructor)); } - for (Method method : clazz.getMethods()) + for (Method method : SecureReflections.getMethods(clazz)) { buffer.append(methodToString(method)); } Index: src/main/java/org/jboss/weld/introspector/jlr/WeldClassImpl.java =================================================================== --- src/main/java/org/jboss/weld/introspector/jlr/WeldClassImpl.java (revision 5362) +++ src/main/java/org/jboss/weld/introspector/jlr/WeldClassImpl.java (working copy) @@ -48,6 +48,7 @@ import org.jboss.weld.util.Names; import org.jboss.weld.util.reflection.HierarchyDiscovery; import org.jboss.weld.util.reflection.Reflections; +import org.jboss.weld.util.reflection.SecureReflections; import com.google.common.base.Supplier; import com.google.common.collect.Multimaps; @@ -222,12 +223,8 @@ for (Class c = rawType; c != Object.class && c != null; c = c.getSuperclass()) { - for (Field field : c.getDeclaredFields()) + for (Field field : SecureReflections.getDeclaredFields(c)) { - if (!field.isAccessible()) - { - field.setAccessible(true); - } WeldField annotatedField = null; if (annotatedTypeFields.containsKey(field)) { @@ -295,7 +292,7 @@ } this.declaredConstructorsBySignature = new HashMap>(); - for (Constructor constructor : rawType.getDeclaredConstructors()) + for (Constructor constructor : SecureReflections.getDeclaredConstructors(rawType)) { WeldConstructor annotatedConstructor = null; if (annotatedTypeConstructors.containsKey(constructor)) @@ -310,10 +307,6 @@ annotatedConstructor = WeldConstructorImpl.of(c, this.getDeclaringWBClass(c, classTransformer), classTransformer); } - if (!constructor.isAccessible()) - { - constructor.setAccessible(true); - } this.constructors.add(annotatedConstructor); this.constructorsByArgumentMap.put(Arrays.asList(constructor.getParameterTypes()), annotatedConstructor); @@ -389,13 +382,8 @@ for (Class c = rawType; c != Object.class && c != null; c = c.getSuperclass()) { - for (Method method : c.getDeclaredMethods()) + for (Method method : SecureReflections.getDeclaredMethods(c)) { - if (!method.isAccessible()) - { - method.setAccessible(true); - } - WeldMethod annotatedMethod = null; if (annotatedTypeMethods.containsKey(method)) { Index: src/main/java/org/jboss/weld/bean/AbstractClassBean.java =================================================================== --- src/main/java/org/jboss/weld/bean/AbstractClassBean.java (revision 5362) +++ src/main/java/org/jboss/weld/bean/AbstractClassBean.java (working copy) @@ -75,6 +75,7 @@ import org.jboss.weld.util.Strings; import org.jboss.weld.util.Proxies.TypeInfo; import org.jboss.weld.util.reflection.Reflections; +import org.jboss.weld.util.reflection.SecureReflections; import org.slf4j.cal10n.LocLogger; /** @@ -220,7 +221,7 @@ } try { - T proxy = proxyClassForDecorators.newInstance(); + T proxy = SecureReflections.newInstance(proxyClassForDecorators); // temporary fix for decorators - make sure that the instance wrapped by the decorators // is the contextual instance // TODO - correct the decoration algorithm to avoid the creation of new target class instances @@ -579,7 +580,7 @@ if (getAnnotatedItem().isAnnotationPresent(InterceptionUtils.getInterceptorsAnnotationClass())) { Annotation interceptorsAnnotation = getType().getAnnotation(InterceptionUtils.getInterceptorsAnnotationClass()); - classDeclaredInterceptors = Reflections.extractValues(interceptorsAnnotation); + classDeclaredInterceptors = SecureReflections.extractValues(interceptorsAnnotation); } if (classDeclaredInterceptors != null) @@ -594,7 +595,7 @@ Class[] methodDeclaredInterceptors = null; if (method.isAnnotationPresent(InterceptionUtils.getInterceptorsAnnotationClass())) { - methodDeclaredInterceptors = Reflections.extractValues(method.getAnnotation(InterceptionUtils.getInterceptorsAnnotationClass())); + methodDeclaredInterceptors = SecureReflections.extractValues(method.getAnnotation(InterceptionUtils.getInterceptorsAnnotationClass())); } if (excludeClassInterceptors) { Index: src/main/java/org/jboss/weld/bean/SessionBean.java =================================================================== --- src/main/java/org/jboss/weld/bean/SessionBean.java (revision 5362) +++ src/main/java/org/jboss/weld/bean/SessionBean.java (working copy) @@ -74,6 +74,7 @@ import org.jboss.weld.util.Proxies; import org.jboss.weld.util.Proxies.TypeInfo; import org.jboss.weld.util.reflection.HierarchyDiscovery; +import org.jboss.weld.util.reflection.SecureReflections; /** * An enterprise bean representation @@ -181,7 +182,7 @@ { try { - T instance = proxyClass.newInstance(); + T instance = SecureReflections.newInstance(proxyClass); ctx.push(instance); return Proxies.attachMethodHandler(instance, new EnterpriseBeanProxyMethodHandler(SessionBean.this, ctx)); } @@ -409,7 +410,7 @@ { if (type instanceof Class) { - for (Method m : ((Class) type).getMethods()) + for (Method m : SecureReflections.getMethods((Class) type)) { if (method.getName().equals(m.getName()) && Arrays.equals(method.getParameterTypesAsArray(), m.getParameterTypes())) { Index: src/main/java/org/jboss/weld/util/reflection/SecureReflections.java =================================================================== --- src/main/java/org/jboss/weld/util/reflection/SecureReflections.java (revision 0) +++ src/main/java/org/jboss/weld/util/reflection/SecureReflections.java (revision 0) @@ -0,0 +1,431 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2008, Red Hat Middleware LLC, 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; + +import static org.jboss.weld.logging.messages.UtilMessage.ANNOTATION_VALUES_INACCESSIBLE; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.jboss.weld.DeploymentException; + +/** + * + * @author Nicklas Karlsson + * + * Utility class for SecurityManager aware reflection operations with + * the "weld.reflection" permission + */ +public class SecureReflections +{ + + /** + * Return a named field from a class + * + * @param clazz The class to operate on + * @param fieldName The name of the field + * @return The field + * @throws NoSuchFieldException If the field cannot be found + * @see java.lang.Class#getField(String)) + */ + public static Field getField(final Class clazz, final String fieldName) throws NoSuchFieldException + { + return (Field) new SecureReflectionAccess() + { + @Override + protected Object work() throws Exception + { + return clazz.getField(fieldName); + } + }.runAsFieldAccess(); + } + + /** + * Returns a named, declared field from a class + * + * @param clazz The class to operate on + * @param fieldName The name of the field + * @return The field + * @throws NoSuchFieldException If the field cannot be found + * @see java.lang.Class#getDeclaredField(String) + */ + public static Field getDeclaredField(final Class clazz, final String fieldName) throws NoSuchFieldException + { + return (Field) new SecureReflectionAccess() + { + @Override + protected Object work() throws Exception + { + return ensureAccessible(clazz.getDeclaredField(fieldName)); + } + }.runAsFieldAccess(); + } + + /** + * Returns all fields of a class + * + * @param clazz The class to operate on + * @return The fields + * @see java.lang.Class#getFields() + */ + public static Field[] getFields(final Class clazz) + { + return (Field[]) new SecureReflectionAccess() + { + @Override + protected Object work() throws Exception + { + return clazz.getFields(); + } + }.runAndWrap(); + } + + /** + * Returns all declared fields of a class + * + * @param clazz The class to operate on + * @return The fields + * @see java.lang.Class#getDeclaredFields() + */ + public static Field[] getDeclaredFields(final Class clazz) + { + return (Field[]) new SecureReflectionAccess() + { + @Override + protected Object work() throws Exception + { + return ensureAccessible(clazz.getDeclaredFields()); + } + }.runAndWrap(); + } + + /** + * Returns a named method of a class + * + * @param clazz The class to operate on + * @param methodName The name of the method + * @param parameterTypes The method parameter types + * @return The method + * @throws NoSuchMethodException If the method cannot be found + * @see java.lang.Class#getMethod(String, Class...) + */ + public static Method getMethod(final Class clazz, final String methodName, final Class... parameterTypes) throws NoSuchMethodException + { + return (Method) new SecureReflectionAccess() + { + @Override + protected Object work() throws Exception + { + return clazz.getMethod(methodName, parameterTypes); + } + }.runAsMethodAccess(); + } + + /** + * Returns a named, declared method of a class + * + * @param clazz The class to operate on + * @param methodName The name of the method + * @param parameterTypes The method parameter types + * @return The method + * @throws NoSuchMethodException If the method cannot be found + * @see java.lang.Class#getDeclaredMethods() + */ + public static Method getDeclaredMethod(final Class clazz, final String methodName, final Class... parameterTypes) throws NoSuchMethodException + { + return (Method) new SecureReflectionAccess() + { + @Override + protected Object work() throws Exception + { + return ensureAccessible(clazz.getDeclaredMethod(methodName, parameterTypes)); + } + }.runAsMethodAccess(); + } + + /** + * Returns all methods of a class + * + * @param clazz The class to operate on + * @return The methods + * @see java.lang.Class#getMethods() + */ + public static Method[] getMethods(final Class clazz) + { + return (Method[]) new SecureReflectionAccess() + { + @Override + protected Object work() throws Exception + { + return clazz.getMethods(); + } + }.runAndWrap(); + } + + /** + * Returns all declared methods of a class + * + * @param clazz The class to operate on + * @return The methods + * @see java.lang.Class#getDeclaredMethods() + */ + public static Method[] getDeclaredMethods(final Class clazz) + { + return (Method[]) new SecureReflectionAccess() + { + @Override + protected Object work() throws Exception + { + return ensureAccessible(clazz.getDeclaredMethods()); + } + }.runAndWrap(); + } + + /** + * Gets a constructor from a class + * + * @param clazz The class to operate on + * @param parameterTypes The constructor parameter types + * @return The constructor + * @throws NoSuchMethodException If the constructor cannot be found + * @see java.lang.Class#getConstructor(Class...) + */ + public static Constructor getConstructor(final Class clazz, final Class... parameterTypes) throws NoSuchMethodException + { + return (Constructor) new SecureReflectionAccess() + { + @Override + protected Object work() throws Exception + { + return clazz.getConstructor(parameterTypes); + } + }.runAsMethodAccess(); + } + + /** + * Gets a declared constructor from a class + * + * @param clazz The class to operate on + * @param parameterTypes The constructor parameter types + * @return The constructor + * @throws NoSuchMethodException If the constructor cannot be found + * @see java.lang.Class#getDeclaredConstructor(Class...) + */ + public static Constructor getDeclaredConstructor(final Class clazz, final Class... parameterTypes) throws NoSuchMethodException + { + return (Constructor) new SecureReflectionAccess() + { + @Override + protected Object work() throws Exception + { + Constructor constructor = clazz.getDeclaredConstructor(parameterTypes); + return clazz == Class.class ? constructor : ensureAccessible(constructor); + } + }.runAsMethodAccess(); + } + + /** + * Gets all constructors from a class + * + * @param clazz The class to operate on + * @return The constructors + * @see java.lang.Class#getConstructors() + */ + public static Constructor[] getConstructors(final Class clazz) + { + return (Constructor[]) new SecureReflectionAccess() + { + @Override + protected Object work() throws Exception + { + return clazz.getConstructors(); + } + }.runAndWrap(); + } + + /** + * Gets all declared constructors from a class + * + * @param clazz The class to operate on + * @return The constructors + * @see java.lang.Class#getDeclaredConstructor(Class...) + */ + public static Constructor[] getDeclaredConstructors(final Class clazz) + { + return (Constructor[]) new SecureReflectionAccess() + { + @Override + protected Object work() throws Exception + { + Constructor[] constructors = clazz.getDeclaredConstructors(); + return clazz == Class.class ? constructors : ensureAccessible(constructors); + + } + }.runAndWrap(); + } + + /** + * Invokes a given method with given parameters on an instance + * + * @param instance The instance to invoke on + * @param method The method to invoke + * @param parameters The method parameters + * @return The return value of the method + * @throws IllegalArgumentException If there was an illegal argument passed + * @throws IllegalAccessException If there was an illegal access attempt + * @throws InvocationTargetException If there was another error invoking the + * method + * @see java.lang.reflect.Method#invoke(Object, Object...) + */ + public static Object invoke(final Object instance, final Method method, final Object... parameters) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException + { + return new SecureReflectionAccess() + { + @Override + protected Object work() throws Exception + { + return ((Method) ensureAccessible(method)).invoke(instance, parameters); + } + }.runAsInvocation(); + } + + public static Object invoke(final Object instance, final String methodName, final Object... parameters) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException + { + return new SecureReflectionAccess() + { + @Override + protected Object work() throws Exception + { + Class[] parameterTypes = new Class[parameters.length]; + for (int i = 0; i < parameters.length; i++) + { + parameterTypes[i] = parameters[i].getClass(); + } + Method method = getMethod(instance.getClass(), methodName, parameterTypes); + return method.invoke(instance, parameters); + } + }.runAsInvocation(); + } + + /** + * Creates a new instance of a class + * + * @param 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 newInstance(final Class clazz) throws InstantiationException, IllegalAccessException + { + return (T) new SecureReflectionAccess() + { + @Override + protected Object work() throws Exception + { + return clazz.newInstance(); + } + }.runAsInstantiation(); + } + + public static Method lookupMethod(Object instance, Method method) throws NoSuchMethodException + { + return lookupMethod(instance.getClass(), method.getName(), method.getParameterTypes()); + } + + /** + * Returns a method from the class or any class/interface in the inheritance + * hierarchy + * + * @param clazz The class to search + * @param methodName The method name + * @param parameterTypes The method parameter types + * @return The method + * @throws NoSuchMethodException If the method could not be found + */ + public static Method lookupMethod(final Class clazz, final String methodName, final Class... parameterTypes) throws NoSuchMethodException + { + return (Method) new SecureReflectionAccess() + { + + private Method lookupMethod(final Class currentClass) throws NoSuchMethodException + { + for (Class inspectedClass = currentClass; inspectedClass != null; inspectedClass = inspectedClass.getSuperclass()) + { + for (Class inspectedInterface : inspectedClass.getInterfaces()) + { + try + { + return lookupMethod(inspectedInterface); + } + catch (NoSuchMethodException e) + { + // Expected, nothing to see here. + } + } + try + { + return getDeclaredMethod(inspectedClass, methodName, parameterTypes); + } + catch (NoSuchMethodException nsme) + { + // Expected, nothing to see here. + } + } + throw new NoSuchMethodException(); + } + + @Override + protected Object work() throws Exception + { + return lookupMethod(clazz); + } + }.runAsMethodAccess(); + } + + public static Class[] extractValues(Annotation annotation) + { + try + { + Class[] valueClasses = (Class[]) invoke(annotation, "value"); + return valueClasses; + } + catch (Exception e) + { + throw new DeploymentException(ANNOTATION_VALUES_INACCESSIBLE, e); + } + } + + public static boolean methodExists(Class clazz, String methodName, Class... parameterTypes) + { + try + { + getMethod(clazz, methodName, parameterTypes); + } + catch (NoSuchMethodException e) + { + return false; + } + return true; + } + +} Index: src/main/java/org/jboss/weld/util/reflection/Reflections.java =================================================================== --- src/main/java/org/jboss/weld/util/reflection/Reflections.java (revision 5362) +++ src/main/java/org/jboss/weld/util/reflection/Reflections.java (working copy) @@ -18,19 +18,12 @@ import static org.jboss.weld.logging.Category.UTIL; import static org.jboss.weld.logging.LoggerFactory.loggerFactory; -import static org.jboss.weld.logging.messages.UtilMessage.ACCESS_ERROR_ON_CONSTRUCTOR; -import static org.jboss.weld.logging.messages.UtilMessage.ACCESS_ERROR_ON_FIELD; -import static org.jboss.weld.logging.messages.UtilMessage.ANNOTATION_VALUES_INACCESSIBLE; -import static org.jboss.weld.logging.messages.UtilMessage.NO_SUCH_METHOD; import java.beans.Introspector; import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -38,23 +31,18 @@ import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.lang.reflect.WildcardType; -import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Set; import javax.inject.Qualifier; -import org.jboss.weld.DeploymentException; -import org.jboss.weld.ForbiddenArgumentException; -import org.jboss.weld.WeldException; import org.jboss.weld.util.Types; import org.slf4j.cal10n.LocLogger; import org.slf4j.ext.XLogger; import ch.qos.cal10n.IMessageConveyor; - /** * Utility class for static reflection-type operations * @@ -129,7 +117,7 @@ { return Modifier.isFinal(clazz.getModifiers()); } - + public static int getNesting(Class clazz) { if (clazz.isMemberClass() && !isStatic(clazz)) @@ -231,7 +219,7 @@ /** * Checks if a method is abstract - * + * * @param method * @return */ @@ -241,30 +229,6 @@ } /** - * Gets a constructor with matching parameter types - * - * @param The type - * @param clazz The class - * @param parameterTypes The parameter types - * @return The matching constructor. Null is returned if none is found - */ - public static Constructor getDeclaredConstructor(Class clazz, Class... parameterTypes) - { - try - { - return clazz.getDeclaredConstructor(parameterTypes); - } - catch (NoSuchMethodException e) - { - return null; - } - catch (Exception e) - { - throw new WeldException(ACCESS_ERROR_ON_CONSTRUCTOR, e, clazz); - } - } - - /** * Gets the actual type arguments of a class * * @param clazz The class to examine @@ -329,129 +293,7 @@ return false; } - public static Object invoke(Method method, Object instance, Object... parameters) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException - { - ensureAccessible(method); - return method.invoke(instance, parameters); - } - - public static Object invoke(String methodName, Object instance, Object... parameters) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException - { - Class[] parameterTypes = new Class[parameters.length]; - for (int i = 0; i < parameters.length; i++) - { - parameterTypes[i] = parameters[i].getClass(); - } - Method method = instance.getClass().getMethod(methodName, parameterTypes); - return invoke(method, instance, parameters); - } - - /** - * Gets value of a field and wraps exceptions - * - * @param field The field to set on - * @param target The instance to set on - * @return The value to set - */ - public static Object getAndWrap(Field field, Object target) - { - try - { - return field.get(target); - } - catch (IllegalArgumentException e) - { - throw new WeldException(ACCESS_ERROR_ON_FIELD, e, field.getName(), field.getDeclaringClass()); - } - catch (IllegalAccessException e) - { - throw new WeldException(ACCESS_ERROR_ON_FIELD, e, field.getName(), field.getDeclaringClass()); - } - } - - public static Object getAndWrap(String fieldName, Object target) - { - try - { - return getAndWrap(target.getClass().getField(fieldName), target); - } - catch (SecurityException e) - { - throw new WeldException(ACCESS_ERROR_ON_FIELD, e, fieldName, target.getClass()); - } - catch (NoSuchFieldException e) - { - throw new WeldException(ACCESS_ERROR_ON_FIELD, e, fieldName, target.getClass()); - } - } - - /** - * Looks up a method in the type hierarchy of an instance - * - * @param method The method to look for - * @param instance The instance to start from - * @return The method found - * @throws IllegalArgumentException if the method is not found - */ - public static Method lookupMethod(Method method, Object instance) - { - try - { - return lookupMethod(method.getName(), method.getParameterTypes(), instance); - } - catch (NoSuchMethodException e) - { - throw new ForbiddenArgumentException(e); - } - } - - /** - * Looks up a method in the type hierarchy of an instance - * - * @param method The method to look for - * @param instance The instance to start from - * @return the method - * @throws NoSuchMethodException if the method is not found - */ - public static Method lookupMethod(String methodName, Class[] parameterTypes, Object instance) throws NoSuchMethodException - { - return lookupMethod(methodName, parameterTypes, instance.getClass()); - } - - private static Method lookupMethod(String methodName, Class[] parameterTypes, Class c) throws NoSuchMethodException - { - for (Class clazz = c; clazz != null; clazz = clazz.getSuperclass()) - { - for (Class intf : clazz.getInterfaces()) - { - try - { - return lookupMethod(methodName, parameterTypes, intf); - } - catch (NoSuchMethodException e) - { - // Expected - } - } - try - { - Method targetMethod = clazz.getDeclaredMethod(methodName, parameterTypes); - if (!targetMethod.isAccessible()) - { - targetMethod.setAccessible(true); - } - return targetMethod; - } - catch (NoSuchMethodException nsme) - { - // Expected, nothing to see here. - } - } - throw new NoSuchMethodException(messageConveyer.getMessage(NO_SUCH_METHOD, methodName + Arrays.asList(parameterTypes).toString().replace("[", "(").replace("]", ")"), c.getName())); - } - - /** * Checks the bindingType to make sure the annotation was declared properly * as a binding type (annotated with @BindingType) and that it has a runtime * retention policy. @@ -487,7 +329,7 @@ { return Types.boxedClass(rawType1).isAssignableFrom(Types.boxedClass(rawType2)) && isAssignableFrom(actualTypeArguments1, actualTypeArguments2); } - + public static boolean matches(Class rawType1, Type[] actualTypeArguments1, Class rawType2, Type[] actualTypeArguments2) { return Types.boxedClass(rawType1).equals(Types.boxedClass(rawType2)) && isAssignableFrom(actualTypeArguments1, actualTypeArguments2); @@ -522,7 +364,7 @@ } return false; } - + public static boolean matches(Type type1, Set types2) { for (Type type2 : types2) @@ -602,7 +444,7 @@ } return false; } - + public static boolean matches(Type type1, Type type2) { if (type1 instanceof Class) @@ -709,7 +551,7 @@ } return false; } - + public static boolean matches(Class rawType1, Type[] actualTypeArguments1, Type type2) { if (type2 instanceof ParameterizedType) @@ -753,7 +595,7 @@ } return false; } - + /** * Check whether whether any of the types1 matches a type in types2 * @@ -810,58 +652,4 @@ return clazz.isPrimitive() || Serializable.class.isAssignableFrom(clazz); } - public static Field ensureAccessible(Field field) - { - if (!field.isAccessible() && !isIgnorePackage(field.getDeclaringClass().getPackage())) - { - field.setAccessible(true); - } - return field; - } - - public static Method ensureAccessible(Method method) - { - if (!method.isAccessible() && !isIgnorePackage(method.getDeclaringClass().getPackage())) - { - method.setAccessible(true); - } - return method; - } - - public static Constructor ensureAccessible(Constructor constructor) - { - Class c = constructor.getDeclaringClass(); - Package p = c.getPackage(); - if (!constructor.isAccessible() && !isIgnorePackage(p)) - { - constructor.setAccessible(true); - } - return constructor; - } - - private static boolean isIgnorePackage(Package pkg) - { - if (pkg != null) - { - return pkg.getName().startsWith("java.lang"); - } - else - { - return false; - } - } - - public static Class[] extractValues(Annotation annotation) - { - try - { - Class[] valueClasses = (Class[]) annotation.annotationType().getMethod("value").invoke(annotation); - return valueClasses; - } - catch (Exception e) - { - throw new DeploymentException(ANNOTATION_VALUES_INACCESSIBLE, e); - } - } - } Index: src/main/java/org/jboss/weld/injection/Exceptions.java =================================================================== --- src/main/java/org/jboss/weld/injection/Exceptions.java (revision 5362) +++ src/main/java/org/jboss/weld/injection/Exceptions.java (working copy) @@ -21,6 +21,7 @@ import javax.enterprise.inject.CreationException; import org.jboss.weld.WeldException; +import org.jboss.weld.util.reflection.SecureReflections; class Exceptions { @@ -36,7 +37,7 @@ RuntimeException e; try { - e = exceptionToThrow.newInstance(); + e = SecureReflections.newInstance(exceptionToThrow); } catch (InstantiationException e1) { Index: src/main/java/org/jboss/weld/bean/builtin/CallableMethodHandler.java =================================================================== --- src/main/java/org/jboss/weld/bean/builtin/CallableMethodHandler.java (revision 5362) +++ src/main/java/org/jboss/weld/bean/builtin/CallableMethodHandler.java (working copy) @@ -19,6 +19,7 @@ import org.jboss.weld.NullInstanceException; import org.jboss.weld.bootstrap.api.Service; import org.jboss.weld.util.reflection.Reflections; +import org.jboss.weld.util.reflection.SecureReflections; import org.slf4j.cal10n.LocLogger; public class CallableMethodHandler implements MethodHandler, Serializable @@ -77,7 +78,7 @@ } try { - Object returnValue = Reflections.invoke(proxiedMethod, instance, args); + Object returnValue = SecureReflections.invoke(instance, proxiedMethod, args); log.trace(CALL_PROXIED_METHOD, proxiedMethod, instance, args, returnValue == null ? null : returnValue); return returnValue; } Index: src/main/java/org/jboss/weld/bean/DisposalMethod.java =================================================================== --- src/main/java/org/jboss/weld/bean/DisposalMethod.java (revision 5362) +++ src/main/java/org/jboss/weld/bean/DisposalMethod.java (working copy) @@ -41,6 +41,7 @@ import org.jboss.weld.introspector.WeldMethod; import org.jboss.weld.introspector.WeldParameter; import org.jboss.weld.util.Beans; +import org.jboss.weld.util.reflection.SecureReflections; public class DisposalMethod extends AbstractReceiverBean { @@ -219,15 +220,11 @@ if (type instanceof Class) { Class clazz = (Class) type; - try + if (SecureReflections.methodExists(clazz, disposalMethodInjectionPoint.getName(), disposalMethodInjectionPoint.getParameterTypesAsArray())) { - clazz.getDeclaredMethod(disposalMethodInjectionPoint.getName(), disposalMethodInjectionPoint.getParameterTypesAsArray()); methodDeclaredOnTypes = true; + continue; } - catch (NoSuchMethodException nsme) - { - // No - op - } } } if (!methodDeclaredOnTypes)