Create a proxy for the given {@link Class} type, {@link Object} instance, and {@link ForgeProxy} handler. If
instance is <code>null</code>, this will return <code>null</code>.
965396
@SuppressWarnings("unchecked")
   public static <T> T enhance(final ClassLoader loader, Object instance, ForgeProxy handler)
   {
      Assert.notNull(loader, "ClassLoader must not be null");
      Assert.notNull(handler, "ForgeProxy handler must not be null");

      if (instance == null)
         return null;

      Class<?> type = Proxies.unwrapProxyTypes(instance.getClass(), loader);

      Object result = null;

      Class<?> proxyType = getCachedProxyType(loader, type);
      if (proxyType == null)
      {
         Class<?>[] hierarchy = null;
         Class<?> superclass = null;

         hierarchy = ProxyTypeInspector.getCompatibleClassHierarchy(loader, type);
         if (hierarchy == null || hierarchy.length == 0)
            throw new IllegalArgumentException("Must specify at least one non-final type to enhance for Object: "
                     + instance + " of type " + instance.getClass());

         Class<?> first = hierarchy[0];
         if (!first.isInterface() && !isProxyType(first))
         {
            superclass = Proxies.unwrapProxyTypes(first, loader);
            hierarchy = Arrays.shiftLeft(hierarchy, new Class<?>[hierarchy.length - 1]);
         }
         else if (isProxyType(first))
            hierarchy = Arrays.shiftLeft(hierarchy, new Class<?>[hierarchy.length - 1]);

         int index = Arrays.indexOf(hierarchy, ProxyObject.class);
         if (index >= 0)
         {
            hierarchy = Arrays.removeElementAtIndex(hierarchy, index);
         }

         if (!Proxies.isProxyType(first) && !Arrays.contains(hierarchy, ForgeProxy.class))
            hierarchy = Arrays.append(hierarchy, ForgeProxy.class);

         ProxyFactory f = new ProxyFactory()
         {
            @Override
            protected ClassLoader getClassLoader()
            {
               return loader;
            }
         };

         f.setInterfaces(hierarchy);
         f.setSuperclass(superclass);
         f.setFilter(filter);

         proxyType = f.createClass();

         setCachedProxyType(loader, type, proxyType);
      }

      try
      {
         result = proxyType.getDeclaredConstructor().newInstance();
      }
      catch (InstantiationException e)
      {
         throw new IllegalStateException(
                  "Could not instantiate proxy for object [" + instance + "] of type [" + type
                           + "]. For optimal proxy compatibility, ensure " +
                           "that this type is an interface, or a class with a default constructor.",
                  e);
      }
      catch (NoSuchMethodException e)
      {
         throw new IllegalStateException(
                  "Could not instantiate proxy for object [" + instance + "] of type [" + type
                           + "] because there isn't a public default constructor. For optimal proxy compatibility, "
                           + "ensure that this type is an interface, or a class with a default constructor.",
                  e);
      }
      catch (IllegalAccessException | InvocationTargetException e)
      {
         throw new IllegalStateException(e);
      }

      if (result instanceof Proxy)
         ((Proxy) result).setHandler(handler);
      else if (result instanceof ProxyObject)
         ((ProxyObject) result).setHandler(handler);
      else
         throw new IllegalStateException("Could not set proxy handler [" + handler + "] for proxy object ["
                  + result + "] for instance object [" + instance + "] of type [" + instance.getClass() + "]");

      return (T) result;
   }
994869
@SuppressWarnings("unchecked")
    public static <T> T newInstance(String name, Class<?> objectType) {
        return (T) Proxy.newProxyInstance(
                ClassLoaderUtils.getClassLoader(),
                new Class[]{objectType},
                new LazyJndiResolver(name));
    }
27047
@Benchmark
    public ExampleInterface benchmarkJdkProxy() throws Exception {
        return (ExampleInterface) Proxy.newProxyInstance(newClassLoader(),
                new Class<?>[]{baseClass},
                new InvocationHandler() {
                    public Object invoke(Object proxy, Method method, Object[] args) {
                        Class<?> returnType = method.getReturnType();
                        if (returnType.isPrimitive()) {
                            if (returnType == boolean.class) {
                                return defaultBooleanValue;
                            } else if (returnType == byte.class) {
                                return defaultByteValue;
                            } else if (returnType == short.class) {
                                return defaultShortValue;
                            } else if (returnType == char.class) {
                                return defaultCharValue;
                            } else if (returnType == int.class) {
                                return defaultIntValue;
                            } else if (returnType == long.class) {
                                return defaultLongValue;
                            } else if (returnType == float.class) {
                                return defaultFloatValue;
                            } else {
                                return defaultDoubleValue;
                            }
                        } else {
                            return defaultReferenceValue;
                        }
                    }
                }
        );
    }
351613
@Override
  @SuppressWarnings("unchecked") // safe since the proxy implements type
  public T getFake(Class<?> type) {
    return (T) Proxy.newProxyInstance(FakeMessagesProvider.class.getClassLoader(), new Class<?>[] {type},
        new InvocationHandler() {
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
            if (method.getName().equals("ensureInjected")) {
              return true;
            } else if (method.getName().equals("hashCode")) {
              return proxy.getClass().hashCode();
            } else if (method.getName().equals("equals")) {
              return proxy.getClass().equals(args[0].getClass());
            } else if (method.getReturnType() == String.class) {
              return buildMessage(method, args);
            } else if (method.getReturnType() == SafeHtml.class) {
              return SafeHtmlUtils.fromTrustedString(buildMessage(method, args));
            } else {
              throw new IllegalArgumentException(method.getName()
                  + " must return either String or SafeHtml");
            }
          }
        });
  }
1023670
public synchronized Class getProxyClass()
    {
        if ((proxyClass == null) && (proxyClassName != null))
        {
            if (isDynamicProxy())
            {
                /**
                 * AClute: Return the same class back if it is dynamic. This signifies
                 * that this class become the base to a generated sub-class, regadless
                 * of which Proxy implementation is used
                 */
                return getClassOfObject();
            }
            else
            {
                try
                {
                    proxyClass = ClassHelper.getClass(proxyClassName);
                }
                catch (ClassNotFoundException e)
                {
                    throw new MetadataException(e);
                }
            }
        }
        return proxyClass;
    }
708413
@SuppressWarnings("unchecked")
    static <T, G extends T> Class<G> generateProxyClass(Context context, Class<T> baseClass)
            throws IOException {
        // Cache missed; generate the proxy class.
        final DexMaker dexMaker = new DexMaker();

        final String proxyClassName = getClassNameForProxyOf(baseClass);
        final TypeId<G> generatedType = TypeId.get("L" + proxyClassName + ";");
        final TypeId<T> baseType = TypeId.get(baseClass);

        generateConstructorAndFields(dexMaker, generatedType, baseType);
        generateOnMeasureMethod(dexMaker, generatedType, baseType);
        generateOnLayoutMethod(dexMaker, generatedType, baseType);
        generateDrawMethods(dexMaker, generatedType, baseType);
        generateRequestLayoutMethod(dexMaker, generatedType, baseType);
        generateForceLayoutMethod(dexMaker, generatedType, baseType);
        generateSetMeasuredDimension(dexMaker, generatedType, baseType);
        generateSetInterceptor(dexMaker, generatedType, baseType);

        dexMaker.declare(generatedType, proxyClassName + ".generated", PUBLIC, baseType,
                INTERCEPTABLE_VIEW_TYPE);

        final ClassLoader classLoader = dexMaker.generateAndLoad(context.getClassLoader(),
                context.getDir(DEX_CACHE_DIRECTORY, Context.MODE_PRIVATE));
        try {
            return (Class<G>) classLoader.loadClass(proxyClassName);
        } catch (IllegalAccessError e) {
            // Thrown when the base class is not accessible.
            throw new UnsupportedOperationException(
                    "cannot proxy inaccessible class " + baseClass, e);
        } catch (ClassNotFoundException e) {
            // Should not be thrown, we're sure to have generated this class.
            throw new AssertionError(e);
        }
    }
96084
private <T> Map<PrimitivePropertyMethodMetadata<PropertyMetadata>, Object> prepareExample(Example<T> example, Class<?> type, Class<?>... types) {
        Map<PrimitivePropertyMethodMetadata<PropertyMetadata>, Object> exampleEntity = new HashMap<>();
        ExampleProxyMethodService<T> proxyMethodService = (ExampleProxyMethodService<T>) exampleProxyMethodServices.get(type);
        if (proxyMethodService == null) {
            proxyMethodService = new ExampleProxyMethodService(type, sessionContext);
            exampleProxyMethodServices.put(type, proxyMethodService);
        }
        InstanceInvocationHandler invocationHandler = new InstanceInvocationHandler(exampleEntity, proxyMethodService);
        List<Class<?>> effectiveTypes = new ArrayList<>(types.length + 1);
        effectiveTypes.add(type);
        effectiveTypes.addAll(Arrays.asList(types));
        CompositeType compositeType = CompositeTypeBuilder.create(CompositeObject.class, type, types);
        T instance = sessionContext.getProxyFactory().createInstance(invocationHandler, compositeType);
        example.prepare(instance);
        return exampleEntity;
    }
647538
@SuppressWarnings("unchecked")
    public static <T> ThreadLocalProxy<T> createThreadLocalProxy(Class<T> type) {
        ThreadLocalProxy<?> proxy = null;
        if (UriInfo.class.isAssignableFrom(type)) {
            proxy = new ThreadLocalUriInfo();
        } else if (HttpHeaders.class.isAssignableFrom(type)) {
            proxy = new ThreadLocalHttpHeaders();
        } else if (ProtocolHeaders.class.isAssignableFrom(type)) {
            proxy = new ThreadLocalProtocolHeaders();
        } else if (SecurityContext.class.isAssignableFrom(type)) {
            proxy = new ThreadLocalSecurityContext();
        } else if (ContextResolver.class.isAssignableFrom(type)) {
            proxy = new ThreadLocalContextResolver<>();
        } else if (Request.class.isAssignableFrom(type)) {
            proxy = new ThreadLocalRequest();
        } else if (Providers.class.isAssignableFrom(type)) {
            proxy = new ThreadLocalProviders();
        } else if (MessageContext.class.isAssignableFrom(type)) {
            proxy = new ThreadLocalMessageContext();
// Liberty Change for CXF Begin
        } else if (type.getName().equals(MessageContext.class.getName())) {
            MessageContextProxyClassLoader loader = new MessageContextProxyClassLoader(getClassLoader(Proxy.class), getClassLoader(type), getClassLoader(ThreadLocalProxy.class));
            proxy = (ThreadLocalProxy<T>) Proxy.newProxyInstance(loader,
                                                                 new Class[] { type, ThreadLocalProxy.class },
                                                                 new ProxyInvocationHandler(new ThreadLocalMessageContext()));
// Liberty Change for CXF Begin
        }

        if (proxy == null && isServletApiContext(type.getName())) {
            proxy = createThreadLocalServletApiContext(type.getName());
        }
        if (proxy == null) {
            ClassLoader loader
                = proxyClassLoaderCache.getProxyClassLoader(Proxy.class.getClassLoader(), 
                                                            new Class<?>[]{Proxy.class, ThreadLocalProxy.class, type}); 
            if (!canSeeAllClasses(loader, new Class<?>[]{Proxy.class, ThreadLocalProxy.class, type})) {
                // Liberty change start - (LOG to Tr)
                if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                    Tr.debug(tc, "find a loader from ProxyClassLoader cache," 
                        + " but can't see all interfaces");
                
                    Tr.debug(tc, "create a new one with parent  " + Proxy.class.getClassLoader());
                }
                //Liberty change end
                proxyClassLoaderCache.removeStaleProxyClassLoader(type);
                proxyClassLoaderCache.getProxyClassLoader(Proxy.class.getClassLoader(), 
                                                          new Class<?>[]{Proxy.class, ThreadLocalProxy.class, type}); 
            }
            return (ThreadLocalProxy<T>)Proxy.newProxyInstance(loader,
                                                     new Class[] {type, ThreadLocalProxy.class },
                                                     new ThreadLocalInvocationHandler<T>());
        }

        return (ThreadLocalProxy<T>) proxy;
    }
1163188
public static <T extends Entity> T asType(final Entity entity, final Class<T> type) {
	return getProxyFactory().proxyOfEntity(entity, type);
    }
1292510
public <T> T getClientProxy(final Bean<T> bean, Type requestedType) {
        // let's first try to use the proxy that implements all the bean types
        T proxy = beanTypeClosureProxyPool.getCastValue(bean);
        if (proxy == BEAN_NOT_PROXYABLE_MARKER) {
            /*
             *  the bean may have a type that is not proxyable - this is not a problem as long as the unproxyable
             *  type is not in the type closure of the requested type
             *  https://issues.jboss.org/browse/WELD-1052
             */
            proxy = requestedTypeClosureProxyPool.getCastValue(new RequestedTypeHolder(requestedType, bean));
            if (proxy == BEAN_NOT_PROXYABLE_MARKER) {
                throw Proxies.getUnproxyableTypeException(requestedType, services());
            }
        }
        BeanLogger.LOG.lookedUpClientProxy(proxy.getClass(), bean);
        return proxy;
    }
655713
public static <T> T buildProxy(String proxyType, Class<T> clazz, Invoker proxyInvoker) throws Exception {
        try {
            ExtensionClass<Proxy> ext = ExtensionLoaderFactory.getExtensionLoader(Proxy.class)
                .getExtensionClass(proxyType);
            if (ext == null) {
                throw ExceptionUtils.buildRuntime("consumer.proxy", proxyType,
                    "Unsupported proxy of client!");
            }
            Proxy proxy = ext.getExtInstance();
            return proxy.getProxy(clazz, proxyInvoker);
        } catch (SofaRpcRuntimeException e) {
            throw e;
        } catch (Throwable e) {
            throw new SofaRpcRuntimeException(e.getMessage(), e);
        }
    }
881797
@Override
  public ITypeRef create( IType type )
  {
    // already a proxy? return as is then
    if( type instanceof ITypeRef )
    {
      return (ITypeRef)type;
    }

    if( type instanceof INonLoadableType )
    {
      throw new UnsupportedOperationException( "Type references are not supported for nonloadable types: " + type.getName() );
    }

    String strTypeName = TypeLord.getNameWithQualifiedTypeVariables( type, true );
    if( strTypeName == null || strTypeName.length() == 0 )
    {
      throw new IllegalStateException( "Type has no name" );
    }

    ITypeRef ref;
    if (ExecutionMode.isRuntime()) {
      ref = getRefTheFastWay(type, strTypeName);
    } else {
      ref = getRefTheSafeWay(type, strTypeName);
    }
    return ref;
  }
707642
public static <T> Conversion<T> to(final Class<T> type) {

		/**
		 * Proxies type conversion to allow for the fact that the value may
		 * provide its own conversion and other subtleties. The goal is to
		 * preserve the identical behavior as if {@link #asType(Class,Object)}
		 * were called.
		 *
		 */
		return new Conversion<T>() {

			@Override
			public Object[] getTypeKeys() {
				Conversion<?> conversion=typeConversions.get(type);
				return (conversion!=null)
					? TypeConverter.getTypeKeys(conversion)
						.toArray(new Object[0])
					: new Object[0];
			}

			@Override
			public T convert(Object value) {
				return TypeConverter.convert(type,value);
			}
		};
	}
197414
public Class<T> getProxyClass() {
        String suffix = "_$$_Weld" + getProxyNameSuffix();
        String proxyClassName = getBaseProxyName();
        if (!proxyClassName.endsWith(suffix)) {
            proxyClassName = proxyClassName + suffix;
        }
        if (proxyClassName.startsWith(JAVA)) {
            proxyClassName = proxyClassName.replaceFirst(JAVA, "org.jboss.weld");
        }
        Class<T> proxyClass = null;
        Class<?> originalClass = bean != null ? bean.getBeanClass() : proxiedBeanType;
        BeanLogger.LOG.generatingProxyClass(proxyClassName);
        try {
            // First check to see if we already have this proxy class
            proxyClass = cast(classLoader == null? proxyServices.loadClass(originalClass, proxyClassName) : classLoader.loadClass(proxyClassName));
        } catch (ClassNotFoundException e) {
            // Create the proxy class for this instance
            try {
                proxyClass = createProxyClass(originalClass, 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(classLoader == null? proxyServices.loadClass(originalClass, proxyClassName) : classLoader.loadClass(proxyClassName));
                } catch (ClassNotFoundException e2) {
                    BeanLogger.LOG.catchingDebug(e1);
                    throw BeanLogger.LOG.unableToLoadProxyClass(bean, proxiedBeanType, e1);
                }
            }
        }
        return proxyClass;
    }
733325
@SuppressWarnings("unchecked")
  public static <T> T newProxy(Class<T> ctype, T concrete, String id) {
    final InvocationHandler handler = new TimedHandler<>(ctype, concrete, id);
    final Class<?>[] types = new Class[]{ctype, CompositeMonitor.class};
    return (T) Proxy.newProxyInstance(ctype.getClassLoader(), types, handler);
  }
966729
@Override
    public Class<?> getProxyClass() {
        if (proxyClass != null) {
            return proxyClass;
        }
        try {
            if (StringUtils.isNotBlank(interfaceId)) {
                this.proxyClass = ClassUtils.forName(interfaceId);
                if (!proxyClass.isInterface()) {
                    throw ExceptionUtils.buildRuntime("service.interfaceId",
                        interfaceId, "interfaceId must set interface class, not implement class");
                }
            } else {
                throw ExceptionUtils.buildRuntime("service.interfaceId",
                    "null", "interfaceId must be not null");
            }
        } catch (SofaRpcRuntimeException e) {
            throw e;
        } catch (Throwable e) {
            throw new SofaRpcRuntimeException(e.getMessage(), e);
        }
        return proxyClass;
    }
1071874
protected <T> T create(Class<T> type, Map<String, String> config) {
        // Use #doInstantiate so inheriting classes can override it, as #instantiate is static final.
        T instance = doInstantiate(type, config);

        if (instance instanceof AsyncInitialize) {
            asyncInitializeAwaiting.incrementAndGet();
            ((AsyncInitialize) instance).initialize(initResult -> {
                asyncInitializeAwaiting.decrementAndGet();
                if (initResult.isError()) {
                    if (!failed) { // Not already failed before
                        failed = true;
                        if (handler != null)
                            handler.handle(initResult);
                    } else {
                        System.err.println("Failure occurred, but error handler was already invoked: " + initResult.getError().getCause()); //$NON-NLS-1$
                    }
                } else {
                    checkLoadingStatus();
                }
            });
        }

        checkLoadingStatus();
        return instance;
    }