Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * JBoss, Home of Professional Open Source
   * Copyright 2008, 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.bean.proxy;
 
 import static org.jboss.classfilewriter.util.DescriptorUtils.isPrimitive;
 import static org.jboss.classfilewriter.util.DescriptorUtils.isWide;
 import static org.jboss.weld.util.reflection.Reflections.cast;
 
 import java.io.File;
 import java.util.List;
 import java.util.Set;
 
 
Main factory to produce proxy classes and instances for Weld beans. This implementation creates proxies which forward non-static method invocations to a BeanInstance. All proxies implement the Proxy interface.

Author(s):
David Allen
Stuart Douglas
Marius Bogoevici
Ales Justin
 
 public class ProxyFactory<T> {
 
     // Default proxy class name suffix
     public static final String PROXY_SUFFIX = "$Proxy$";
     public static final String DEFAULT_PROXY_PACKAGE = "org.jboss.weld.proxies";
 
     private final Class<?> beanType;
     private final Set<Class<?>> additionalInterfaces = new LinkedHashSet<Class<?>>();
     private final ClassLoader classLoader;
     private final String baseProxyName;
     private final Bean<?> bean;
     private final Class<?> proxiedBeanType;
     private final String contextId;
    public static final String CONSTRUCTED_FLAG_NAME = "constructed";
    protected static final String LJAVA_LANG_REFLECT_METHOD = "Ljava/lang/reflect/Method;";
    protected static final String LJAVA_LANG_BYTE = "Ljava/lang/Byte;";
    protected static final String LJAVA_LANG_CLASS = "Ljava/lang/Class;";
    protected static final String LJAVA_LANG_OBJECT = "Ljava/lang/Object;";
    protected static final String LBEAN_IDENTIFIER = "Lorg/jboss/weld/serialization/spi/BeanIdentifier;";
    protected static final String LJAVA_LANG_STRING = "Ljava/lang/String;";
    protected static final String LJAVA_LANG_THREAD_LOCAL = "Ljava/lang/ThreadLocal;";
    protected static final String INIT_METHOD_NAME = "<init>";
    protected static final String METHOD_HANDLER_FIELD_NAME = "methodHandler";
    private static final String JAVA = "java";
    private static final Set<ProxiedMethodFilterMETHOD_FILTERS;
    static {
        GroovyMethodFilter groovy = new GroovyMethodFilter();
        if (groovy.isEnabled()) {
             = Collections.<ProxiedMethodFilter>singleton(groovy);
        } else {
             = Collections.emptySet();
        }
    }

    
created a new proxy factory from a bean instance. The proxy name is generated from the bean id
    public ProxyFactory(String contextIdClass<?> proxiedBeanTypeSet<? extends TypetypeClosureBean<?> bean) {
        this(contextIdproxiedBeanTypetypeClosurebeanfalse);
    }
    public ProxyFactory(String contextIdClass<?> proxiedBeanTypeSet<? extends TypetypeClosureBean<?> beanboolean forceSuperClass) {
        this(contextIdproxiedBeanTypetypeClosuregetProxyName(contextIdproxiedBeanTypetypeClosurebean), beanforceSuperClass);
    }

    
Creates a new proxy factory when the name of the proxy class is already known, such as during de-serialization

Parameters:
proxiedBeanType the super-class for this proxy class
typeClosure the bean types of the bean
proxyName the name of the proxy class
    public ProxyFactory(String contextIdClass<?> proxiedBeanTypeSet<? extends TypetypeClosureString proxyNameBean<?> bean) {
        this(contextIdproxiedBeanTypetypeClosureproxyNamebeanfalse);
    }
    public ProxyFactory(String contextIdClass<?> proxiedBeanTypeSet<? extends TypetypeClosureString proxyNameBean<?> beanboolean forceSuperClass) {
        this. = bean;
        this. = contextId;
        this. = proxiedBeanType;
        addInterfacesFromTypeClosure(typeClosureproxiedBeanType);
        TypeInfo typeInfo = TypeInfo.of(typeClosure);
        Class<?> superClass = typeInfo.getSuperClass();
        superClass = superClass == null ? Object.class : superClass;
        if (forceSuperClass || (superClass.equals(Object.class) && .isEmpty())) {
            // No interface beans must use the bean impl as superclass
            superClass = proxiedBeanType;
        }
        this. = superClass;
         = proxyName;
        if (bean != null) {
            /*
             * this may happen when creating an InjectionTarget for a decorator using BeanManager#createInjectionTarget()
             * which does not allow the bean to be specified
             */
            this. = resolveClassLoaderForBeanProxy(contextIdbean.getBeanClass(), typeInfo);
        } else {
            this. = resolveClassLoaderForBeanProxy(contextIdproxiedBeanTypetypeInfo);
        }
        // hierarchy order
        List<Class<?>> list = new ArrayList<Class<?>>();
        Collections.sort(list.);
        .clear();
        .addAll(list);
        InstantiatorFactory factory = Container.instance(contextId).services().get(InstantiatorFactory.class);
        if (factory != null && factory.useInstantiators() && isCreatingProxy()) {
            this. = factory;
        } else {
            this. = null;
        }
    }
    static String getProxyName(String contextIdClass<?> proxiedBeanTypeSet<? extends TypetypeClosureBean<?> bean) {
        TypeInfo typeInfo = TypeInfo.of(typeClosure);
        String proxyPackage;
        if (proxiedBeanType.equals(Object.class)) {
            Class<?> superInterface = typeInfo.getSuperInterface();
            if (superInterface == null) {
                throw new IllegalArgumentException("Proxied bean type cannot be java.lang.Object without an interface");
            } else {
                proxyPackage = ;
            }
        } else {
            if (proxiedBeanType.getPackage() == null) {
                proxyPackage = ;
            } else {
                proxyPackage = proxiedBeanType.getPackage().getName();
            }
        }
        final String className;
        if (typeInfo.getSuperClass() == Object.class) {
            final StringBuilder name = new StringBuilder();
            //interface only bean.
            className = createCompoundProxyName(contextIdbeantypeInfoname) + ;
        } else {
            boolean typeModified = false;
            for (Class<?> iface : typeInfo.getInterfaces()) {
                if (!iface.isAssignableFrom(typeInfo.getSuperClass())) {
                    typeModified = true;
                    break;
                }
            }
            if (typeModified) {
                //this bean has interfaces that the base type is not assignable to
                //which can happen with some creative use of the SPI
                //interface only bean.
                StringBuilder name = new StringBuilder(typeInfo.getSuperClass().getSimpleName() + "$");
                className = createCompoundProxyName(contextIdbeantypeInfoname) + ;
            } else {
                className = typeInfo.getSuperClass().getSimpleName() + ;
            }
        }
        return proxyPackage + '.' + getEnclosingPrefix(proxiedBeanType) + className;
    }
    public void addInterfacesFromTypeClosure(Set<? extends TypetypeClosureClass<?> proxiedBeanType) {
        for (Type type : typeClosure) {
            Class<?> c = Reflections.getRawType(type);
            // Ignore no-interface views, they are dealt with proxiedBeanType
            // (pending redesign)
            if (c.isInterface()) {
                addInterface(c);
            }
        }
    }
    private static String createCompoundProxyName(String contextIdBean<?> beanTypeInfo typeInfoStringBuilder name) {
        String className;
        final List<Stringinterfaces = new ArrayList<String>();
        for (Class<?> type : typeInfo.getInterfaces()) {
            interfaces.add(type.getSimpleName());
        }
        Collections.sort(interfaces);
        for (final String iface : interfaces) {
            name.append(iface);
            name.append('$');
        }
        //there is a remote chance that this could generate the same
        //proxy name for two interfaces with the same simple name.
        //append the hash code of the bean id to be sure
        if (bean != null) {
            final BeanIdentifier id = Container.instance(contextId).services().get(ContextualStore.class).putIfAbsent(bean);
            int idHash = id.hashCode();
            name.append(Math.abs(idHash == . ? 0 : idHash));
        }
        className = name.toString();
        return className;
    }
    private static String getEnclosingPrefix(Class<?> clazz) {
        Class<?> encl = clazz.getEnclosingClass();
        return encl == null ? "" : getEnclosingPrefix(encl) + encl.getSimpleName() + '$';
    }
    protected boolean isCreatingProxy() {
        return true;
    }

    
Adds an additional interface that the proxy should implement. The default implementation will be to forward invocations to the bean instance.

Parameters:
newInterface an interface
    public void addInterface(Class<?> newInterface) {
        if (!newInterface.isInterface()) {
            throw new IllegalArgumentException(newInterface + " is not an interface");
        }
        .add(newInterface);
    }

    
Method to create a new proxy that wraps the bean instance.

Parameters:
beanInstance the bean instance
Returns:
a new proxy object
    public T create(BeanInstance beanInstance) {
        T proxy;
        Class<T> proxyClass = getProxyClass();
        try {
            if ( != null) {
                proxy = .getInstantiator().instantiate(proxyClass);
            } else {
                proxy = AccessController.doPrivileged(NewInstanceAction.of(proxyClass));
            }
        } catch (PrivilegedActionException e) {
            if (e.getCause() instanceof InstantiationException) {
                throw new DefinitionException(..proxyInstantiationFailed(this), e.getCause());
            } else if (e.getCause() instanceof IllegalAccessException) {
                throw new DefinitionException(..proxyInstantiationBeanAccessFailed(this), e.getCause());
            } else {
                throw new WeldException(e.getCause());
            }
        }
        ((ProxyObjectproxy).setHandler(new ProxyMethodHandler(beanInstance));
        return proxy;
    }

    
Produces or returns the existing proxy class. The operation is thread-safe.

Returns:
always the class of the proxy
    public Class<T> getProxyClass() {
        String suffix = "_$$_Weld" + getProxyNameSuffix();
        String proxyClassName = getBaseProxyName();
        if (!proxyClassName.endsWith(suffix)) {
            proxyClassName = proxyClassName + suffix;
        }
        if (proxyClassName.startsWith()) {
            proxyClassName = proxyClassName.replaceFirst("org.jboss.weld");
        }
        Class<T> proxyClass = null;
        ..generatingProxyClass(proxyClassName);
        try {
            // First check to see if we already have this proxy class
            proxyClass = cast(.loadClass(proxyClassName));
        } catch (ClassNotFoundException e) {
            // Create the proxy class for this instance
            try {
                proxyClass = createProxyClass(proxyClassName);
            } catch (Throwable e1) {
                //attempt to load the class again, just in case another thread
                //defined it between the check and the create method
                try {
                    proxyClass = cast(.loadClass(proxyClassName));
                } catch (ClassNotFoundException e2) {
                    throw ..unableToLoadProxyClass(e1);
                }
            }
        }
        return proxyClass;
    }
    protected Class<T> getCachedProxyClass(String proxyClassName) {
        try {
            // Check to see if we already have this proxy class
            return cast(.loadClass(proxyClassName));
        } catch (ClassNotFoundException e) {
            return null;
        }
    }

    
Returns the package and base name for the proxy class.

Returns:
base name without suffixes
    protected String getBaseProxyName() {
        return ;
    }

    
Convenience method to determine if an object is a proxy generated by this factory or any derived factory.

Parameters:
proxySuspect the object suspected of being a proxy
Returns:
true only if it is a proxy object
    public static boolean isProxy(Object proxySuspect) {
        return proxySuspect instanceof ProxyObject;
    }

    
Convenience method to set the underlying bean instance for a proxy.

Parameters:
proxy the proxy instance
beanInstance the instance of the bean
    public static <T> void setBeanInstance(String contextId, T proxyBeanInstance beanInstanceBean<?> bean) {
        if (proxy instanceof ProxyObject) {
            ProxyObject proxyView = (ProxyObjectproxy;
            proxyView.setHandler(new ProxyMethodHandler(contextIdbeanInstancebean));
        }
    }

    
Returns a suffix to append to the name of the proxy class. The name already consists of <class-name>_$$_Weld, to which the suffix is added. This allows the creation of different types of proxies for the same class.

Returns:
a name suffix
    protected String getProxyNameSuffix() {
        return ;
    }
    private void addDefaultAdditionalInterfaces() {
        .add(Serializable.class);
    }

    
Sub classes may override to specify additional interfaces the proxy should implement
    protected void addAdditionalInterfaces(Set<Class<?>> interfaces) {
    }
    private Class<T> createProxyClass(String proxyClassNamethrows Exception {
        ArraySet<Class<?>> specialInterfaces = new ArraySet<Class<?>>(
                LifecycleMixin.classTargetInstanceProxy.classProxyObject.class);
        addAdditionalInterfaces(specialInterfaces);
        // Remove special interfaces from main set (deserialization scenario)
        .removeAll(specialInterfaces);
        ClassFile proxyClassType = null;
        if (getBeanType().isInterface()) {
            proxyClassType = new ClassFile(proxyClassNameObject.class.getName());
            proxyClassType.addInterface(getBeanType().getName());
        } else {
            proxyClassType = new ClassFile(proxyClassNamegetBeanType().getName());
        }
        // Add interfaces which require method generation
        for (Class<?> clazz : ) {
            proxyClassType.addInterface(clazz.getName());
        }
        List<DeferredBytecodeinitialValueBytecode = new ArrayList<DeferredBytecode>();
        ClassMethod staticConstructor = proxyClassType.addMethod(."<clinit>""V");
        addFields(proxyClassTypeinitialValueBytecode);
        addConstructors(proxyClassTypeinitialValueBytecode);
        addMethods(proxyClassTypestaticConstructor);
        staticConstructor.getCodeAttribute().returnInstruction();
        // Additional interfaces whose methods require special handling
        for (Class<?> specialInterface : specialInterfaces) {
            proxyClassType.addInterface(specialInterface.getName());
        }
        // TODO: change the ProxyServices SPI to allow the container to figure out
        // which PD to use
            dumpToFile(..getProxyDumpPath(), proxyClassNameproxyClassType.toBytecode());
        }
        ProtectionDomain domain = AccessController.doPrivileged(new GetProtectionDomainAction());
        if (.getPackage() == null || .equals(Object.class)) {
            domain = ProxyFactory.class.getProtectionDomain();
        } else if (System.getSecurityManager() != null) {
            ProtectionDomainCache cache = Container.instance().services().get(ProtectionDomainCache.class);
            domain = cache.getProtectionDomainForProxy(domain);
        }
        Class<T> proxyClass = cast(ClassFileUtils.toClass(proxyClassTypedomain));
        ..createdProxyClass(proxyClass, Arrays.toString(proxyClass.getInterfaces()));
        return proxyClass;
    }
    private void dumpToFile(File dumpPathString fileNamebyte[] data) {
        FileOutputStream dumpFileStream = null;
        File classFile = new File(dumpPathfileName + ".class");
        try {
            if (classFile.isFile()) {
                if (!classFile.delete()) {
                    throw new IOException("Can not to remove file: " + classFile.getName());
                }
            }
            dumpFileStream = new FileOutputStream(classFile);
            dumpFileStream.write(data);
        } catch (IOException e) {
            ..beanCannotBeDumped(fileNamee);
        } finally {
            try {
                if (dumpFileStream != null) {
                    dumpFileStream.close();
                }
            } catch (IOException e) {
                ..beanCannotBeDumped(fileNamee);
            }
        }
    }

    
Adds a constructor for the proxy for each constructor declared by the base bean type.

Parameters:
proxyClassType the Javassist class for the proxy
initialValueBytecode
    protected void addConstructors(ClassFile proxyClassTypeList<DeferredBytecodeinitialValueBytecode) {
        try {
            if (getBeanType().isInterface()) {
                ConstructorUtils.addDefaultConstructor(proxyClassTypeinitialValueBytecodeisUsingUnsafeInstantiators());
            } else {
                boolean constructorFound = false;
                for (Constructor<?> constructor : AccessController.doPrivileged(new GetDeclaredConstructorsAction(getBeanType()))) {
                    if ((constructor.getModifiers() & .) == 0) {
                        constructorFound = true;
                        String[] exceptions = new String[constructor.getExceptionTypes().length];
                        for (int i = 0; i < exceptions.length; ++i) {
                            exceptions[i] = constructor.getExceptionTypes()[i].getName();
                        }
                        ConstructorUtils.addConstructor(., DescriptorUtils.parameterDescriptors(constructor.getParameterTypes()), exceptionsproxyClassTypeinitialValueBytecodeisUsingUnsafeInstantiators());
                    }
                }
                if (!constructorFound) {
                    // the bean only has private constructors, we need to generate
                    // two fake constructors that call each other
                    addConstructorsForBeanWithPrivateConstructors(proxyClassType);
                }
            }
        } catch (Exception e) {
            throw new WeldException(e);
        }
    }
    protected void addFields(ClassFile proxyClassTypeList<DeferredBytecodeinitialValueBytecode) {
        // The field representing the underlying instance or special method
        // handling
        proxyClassType.addField(.MethodHandler.class);
        if(!isUsingUnsafeInstantiators()) {
            // field used to indicate that super() has been called
        }
    }
    protected void addMethods(ClassFile proxyClassTypeClassMethod staticConstructor) {
        // Add all class methods for interception
        addMethodsFromClass(proxyClassTypestaticConstructor);
        // Add special proxy methods
        addSpecialMethods(proxyClassTypestaticConstructor);
        // Add serialization support methods
        addSerializationSupport(proxyClassType);
    }

    
Adds special serialization code. By default this is a nop

Parameters:
proxyClassType the Javassist class for the proxy class
    protected void addSerializationSupport(ClassFile proxyClassType) {
        //noop
    }
    protected void addMethodsFromClass(ClassFile proxyClassTypeClassMethod staticConstructor) {
        try {
            // Add all methods from the class hierarchy
            Class<?> cls = getBeanType();
            // first add equals/hashCode methods if required
            generateEqualsMethod(proxyClassType);
            generateHashCodeMethod(proxyClassType);
            while (cls != null) {
                for (Method method : AccessController.doPrivileged(new GetDeclaredMethodsAction(cls))) {
                    if (!Modifier.isStatic(method.getModifiers()) &&
                            !Modifier.isFinal(method.getModifiers()) &&
                            (method.getDeclaringClass() != Object.class || method.getName().equals("toString")) &&
                            isMethodAccepted(method)) {
                        try {
                            MethodInformation methodInfo = new RuntimeMethodInformation(method);
                            ClassMethod classMethod = proxyClassType.addMethod(method);
                            addConstructedGuardToMethodBody(classMethod);
                            createForwardingMethodBody(classMethodmethodInfostaticConstructor);
                            ..addingMethodToProxy(method);
                        } catch (DuplicateMemberException e) {
                            // do nothing. This will happen if superclass methods
                            // have been overridden
                        }
                    }
                }
                cls = cls.getSuperclass();
            }
            for (Class<?> c : ) {
                for (Method method : c.getMethods()) {
                    if (!Modifier.isStatic(method.getModifiers()) && isMethodAccepted(method)) {
                        try {
                            MethodInformation methodInfo = new RuntimeMethodInformation(method);
                            ClassMethod classMethod = proxyClassType.addMethod(method);
                            createSpecialMethodBody(classMethodmethodInfostaticConstructor);
                            ..addingMethodToProxy(method);
                        } catch (DuplicateMemberException e) {
                        }
                    }
                }
            }
        } catch (Exception e) {
            throw new WeldException(e);
        }
    }
    private boolean isMethodAccepted(Method method) {
        for (ProxiedMethodFilter filter : ) {
            if (!filter.accept(method)) {
                return false;
            }
        }
        return true;
    }

    
Generate the body of the proxies hashCode method.

If this method returns null, the method will not be added, and the hashCode on the superclass will be used as per normal virtual method resolution rules

    protected void generateHashCodeMethod(ClassFile proxyClassType) {
    }

    
Generate the body of the proxies equals method.

If this method returns null, the method will not be added, and the hashCode on the superclass will be used as per normal virtual method resolution rules

Parameters:
proxyClassType The class file
    protected void generateEqualsMethod(ClassFile proxyClassType) {
    }
    protected void createSpecialMethodBody(ClassMethod proxyClassTypeMethodInformation methodClassMethod staticConstructor) {
        createInterceptorBody(proxyClassTypemethodstaticConstructor);
    }

    
Adds the following code to a delegating method:

if(!this.constructed) return super.thisMethod()

This means that the proxy will not start to delegate to the underlying bean instance until after the constructor has finished.

    protected void addConstructedGuardToMethodBody(final ClassMethod classMethod) {
        if(isUsingUnsafeInstantiators()) {
            return;
        }
        // now create the conditional
        final CodeAttribute cond = classMethod.getCodeAttribute();
        cond.aload(0);
        // jump if the proxy constructor has finished
        BranchEnd jumpMarker = cond.ifne();
        // generate the invokespecial call to the super class method
        // this is run when the proxy is being constructed
        cond.aload(0);
        cond.loadMethodParameters();
        cond.invokespecial(classMethod.getClassFile().getSuperclass(), classMethod.getName(), classMethod.getDescriptor());
        cond.returnInstruction();
        cond.branchEnd(jumpMarker);
    }
    protected void createForwardingMethodBody(ClassMethod classMethodMethodInformation methodClassMethod staticConstructor) {
        createInterceptorBody(classMethodmethodstaticConstructor);
    }

    
Creates the given method on the proxy class where the implementation forwards the call directly to the method handler.

the generated bytecode is equivalent to:

return (RetType) methodHandler.invoke(this,param1,param2);

Parameters:
classMethod the class method
method any JLR method
Returns:
the method byte code
    protected void createInterceptorBody(ClassMethod classMethodMethodInformation methodClassMethod staticConstructor) {
        invokeMethodHandler(classMethodmethodtruestaticConstructor);
    }

    
calls methodHandler.invoke for a given method

Parameters:
method The method information
addReturnInstruction set to true you want to return the result of the method invocation
bytecodeMethodResolver The resolver that returns the method to invoke
    protected static void invokeMethodHandler(ClassMethod classMethodMethodInformation methodboolean addReturnInstructionBytecodeMethodResolver bytecodeMethodResolverClassMethod staticConstructor) {
        // now we need to build the bytecode. The order we do this in is as
        // follows:
        // load methodHandler
        // load this
        // load the method object
        // load null
        // create a new array the same size as the number of parameters
        // push our parameter values into the array
        // invokeinterface the invoke method
        // add checkcast to cast the result to the return type, or unbox if
        // primitive
        // add an appropriate return instruction
        final CodeAttribute b = classMethod.getCodeAttribute();
        b.aload(0);
        b.getfield(classMethod.getClassFile().getName(), , DescriptorUtils.makeDescriptor(MethodHandler.class));
        b.aload(0);
        bytecodeMethodResolver.getDeclaredMethod(classMethodmethod.getDeclaringClass(), method.getName(), method.getParameterTypes(), staticConstructor);
        b.aconstNull();
        b.iconst(method.getParameterTypes().length);
        b.anewarray("java.lang.Object");
        int localVariableCount = 1;
        for (int i = 0; i < method.getParameterTypes().length; ++i) {
            String typeString = method.getParameterTypes()[i];
            b.dup(); // duplicate the array reference
            b.iconst(i);
            // load the parameter value
            BytecodeUtils.addLoadInstruction(btypeStringlocalVariableCount);
            // box the parameter if necessary
            Boxing.boxIfNessesary(btypeString);
            // and store it in the array
            b.aastore();
            if (isWide(typeString)) {
                localVariableCount = localVariableCount + 2;
            } else {
                localVariableCount++;
            }
        }
        // now we have all our arguments on the stack
        // lets invoke the method
        b.invokeinterface(MethodHandler.class.getName(), "invoke"new String[] { ,
        if (addReturnInstruction) {
            // now we need to return the appropriate type
            if (method.getReturnType().equals(.)) {
                b.returnInstruction();
            } else if(isPrimitive(method.getReturnType())) {
                Boxing.unbox(bmethod.getReturnType());
                b.returnInstruction();
            } else {
                String castType = method.getReturnType();
                if (!method.getReturnType().startsWith("[")) {
                    castType = method.getReturnType().substring(1).substring(0, method.getReturnType().length() - 2);
                }
                b.checkcast(castType);
                b.returnInstruction();
            }
        }
    }

    
Adds methods requiring special implementations rather than just delegation.

Parameters:
proxyClassType the Javassist class description for the proxy type
    protected void addSpecialMethods(ClassFile proxyClassTypeClassMethod staticConstructor) {
        try {
            // Add special methods for interceptors
            for (Method method : LifecycleMixin.class.getMethods()) {
                ..addingMethodToProxy(method);
                MethodInformation methodInfo = new RuntimeMethodInformation(method);
                final ClassMethod classMethod = proxyClassType.addMethod(method);
                createInterceptorBody(classMethodmethodInfostaticConstructor);
            }
            Method getInstanceMethod = TargetInstanceProxy.class.getMethod("getTargetInstance");
            Method getInstanceClassMethod = TargetInstanceProxy.class.getMethod("getTargetClass");
            MethodInformation getInstanceMethodInfo = new RuntimeMethodInformation(getInstanceMethod);
            createInterceptorBody(proxyClassType.addMethod(getInstanceMethod), getInstanceMethodInfostaticConstructor);
            MethodInformation getInstanceClassMethodInfo = new RuntimeMethodInformation(getInstanceClassMethod);
            createInterceptorBody(proxyClassType.addMethod(getInstanceClassMethod), getInstanceClassMethodInfostaticConstructor);
            Method setMethodHandlerMethod = ProxyObject.class.getMethod("setHandler"MethodHandler.class);
            generateSetMethodHandlerBody(proxyClassType.addMethod(setMethodHandlerMethod));
            Method getMethodHandlerMethod = ProxyObject.class.getMethod("getHandler");
            generateGetMethodHandlerBody(proxyClassType.addMethod(getMethodHandlerMethod));
        } catch (Exception e) {
            throw new WeldException(e);
        }
    }
    private static void generateSetMethodHandlerBody(ClassMethod method) {
        final CodeAttribute b = method.getCodeAttribute();
        b.aload(0);
        b.aload(1);
        b.putfield(method.getClassFile().getName(), , DescriptorUtils.makeDescriptor(MethodHandler.class));
        b.returnInstruction();
    }
    private static void generateGetMethodHandlerBody(ClassMethod method) {
        final CodeAttribute b = method.getCodeAttribute();
        b.aload(0);
        b.getfield(method.getClassFile().getName(), , DescriptorUtils.makeDescriptor(MethodHandler.class));
        b.returnInstruction();
    }


    
Adds two constructors to the class that call each other in order to bypass the JVM class file verifier.

This would result in a stack overflow if they were actually called, however the proxy is directly created without calling the constructor

    private void addConstructorsForBeanWithPrivateConstructors(ClassFile proxyClassType) {
        CodeAttribute b = ctor.getCodeAttribute();
        b.aload(0);
        b.aconstNull();
        b.aconstNull();
        b.invokespecial(proxyClassType.getName(), "(" +  +  + ")" + .);
        b.returnInstruction();
        b = ctor.getCodeAttribute();
        b.aload(0);
        b.aconstNull();
        b.invokespecial(proxyClassType.getName(), "(" +  + ")" + .);
        b.returnInstruction();
    }
    public Class<?> getBeanType() {
        return ;
    }
    public Set<Class<?>> getAdditionalInterfaces() {
        return ;
    }
    public Bean<?> getBean() {
        return ;
    }
    public String getContextId() {
        return ;
    }

    
Figures out the correct class loader to use for a proxy for a given bean
    public static ClassLoader resolveClassLoaderForBeanProxy(String contextIdClass<?> proxiedTypeTypeInfo typeInfo) {
        Class<?> superClass = typeInfo.getSuperClass();
        if (superClass.getName().startsWith()) {
            ClassLoader cl = Container.instance(contextId).services().get(ProxyServices.class).getClassLoader(proxiedType);
            if (cl == null) {
                cl = Thread.currentThread().getContextClassLoader();
            }
            return cl;
        }
        return Container.instance(contextId).services().get(ProxyServices.class).getClassLoader(superClass);
    }
    protected boolean isUsingUnsafeInstantiators() {
        return  != null;
    }
New to GrepCode? Check out our FAQ X