1717
1818package org .jboss .weld .bean .proxy ;
1919
20- import static org .jboss .classfilewriter .util .DescriptorUtils .isPrimitive ;
21- import static org .jboss .classfilewriter .util .DescriptorUtils .isWide ;
22- import static org .jboss .weld .util .reflection .Reflections .cast ;
23-
2420import java .io .File ;
2521import java .io .IOException ;
2622import java .io .Serializable ;
2723import java .lang .reflect .Constructor ;
24+ import java .lang .reflect .InvocationTargetException ;
2825import java .lang .reflect .Method ;
2926import java .lang .reflect .Modifier ;
3027import java .lang .reflect .Type ;
4542import java .util .concurrent .ConcurrentHashMap ;
4643
4744import jakarta .enterprise .inject .spi .Bean ;
48-
4945import org .jboss .classfilewriter .AccessFlag ;
5046import org .jboss .classfilewriter .ClassFile ;
5147import org .jboss .classfilewriter .ClassMethod ;
5551import org .jboss .classfilewriter .util .Boxing ;
5652import org .jboss .classfilewriter .util .DescriptorUtils ;
5753import org .jboss .weld .Container ;
54+ import org .jboss .weld .annotated .enhanced .MethodSignature ;
55+ import org .jboss .weld .annotated .enhanced .jlr .MethodSignatureImpl ;
5856import org .jboss .weld .bean .AbstractProducerBean ;
59- import org .jboss .weld .bean .builtin .AbstractBuiltInBean ;
6057import org .jboss .weld .config .WeldConfiguration ;
6158import org .jboss .weld .exceptions .DefinitionException ;
6259import org .jboss .weld .exceptions .WeldException ;
6764import org .jboss .weld .security .GetDeclaredConstructorsAction ;
6865import org .jboss .weld .security .GetDeclaredMethodsAction ;
6966import org .jboss .weld .security .GetProtectionDomainAction ;
70- import org .jboss .weld .serialization .spi .BeanIdentifier ;
71- import org .jboss .weld .serialization .spi .ContextualStore ;
7267import org .jboss .weld .serialization .spi .ProxyServices ;
7368import org .jboss .weld .util .Proxies ;
7469import org .jboss .weld .util .Proxies .TypeInfo ;
8176import org .jboss .weld .util .collections .Sets ;
8277import org .jboss .weld .util .reflection .Reflections ;
8378
79+ import static org .jboss .classfilewriter .util .DescriptorUtils .isPrimitive ;
80+ import static org .jboss .classfilewriter .util .DescriptorUtils .isWide ;
81+ import static org .jboss .weld .util .reflection .Reflections .cast ;
82+
8483/*
8584 * This class is copied from Weld sources.
8685 * Modified methods:
124123 * @author Marius Bogoevici
125124 * @author Ales Justin
126125 */
126+ @ SuppressWarnings ("removal" )
127127public class ProxyFactory <T > implements PrivilegedAction <T > {
128128
129129 // Default proxy class name suffix
@@ -186,8 +186,10 @@ public ProxyFactory(String contextId, Class<?> proxiedBeanType, Set<? extends Ty
186186 this (contextId , proxiedBeanType , typeClosure , bean , false );
187187 }
188188
189- public ProxyFactory (String contextId , Class <?> proxiedBeanType , Set <? extends Type > typeClosure , Bean <?> bean , boolean forceSuperClass ) {
190- this (contextId , proxiedBeanType , typeClosure , getProxyName (contextId , proxiedBeanType , typeClosure , bean ), bean , forceSuperClass );
189+ public ProxyFactory (String contextId , Class <?> proxiedBeanType , Set <? extends Type > typeClosure , Bean <?> bean ,
190+ boolean forceSuperClass ) {
191+ this (contextId , proxiedBeanType , typeClosure , getProxyName (contextId , proxiedBeanType , typeClosure , bean ), bean ,
192+ forceSuperClass );
191193 }
192194
193195 /**
@@ -198,11 +200,13 @@ public ProxyFactory(String contextId, Class<?> proxiedBeanType, Set<? extends Ty
198200 * @param typeClosure the bean types of the bean
199201 * @param proxyName the name of the proxy class
200202 */
201- public ProxyFactory (String contextId , Class <?> proxiedBeanType , Set <? extends Type > typeClosure , String proxyName , Bean <?> bean ) {
203+ public ProxyFactory (String contextId , Class <?> proxiedBeanType , Set <? extends Type > typeClosure , String proxyName ,
204+ Bean <?> bean ) {
202205 this (contextId , proxiedBeanType , typeClosure , proxyName , bean , false );
203206 }
204207
205- public ProxyFactory (String contextId , Class <?> proxiedBeanType , Set <? extends Type > typeClosure , String proxyName , Bean <?> bean , boolean forceSuperClass ) {
208+ public ProxyFactory (String contextId , Class <?> proxiedBeanType , Set <? extends Type > typeClosure , String proxyName ,
209+ Bean <?> bean , boolean forceSuperClass ) {
206210 this .bean = bean ;
207211 this .contextId = contextId ;
208212 this .proxiedBeanType = proxiedBeanType ;
@@ -410,7 +414,7 @@ public T run() {
410414 return newInstantiator .newInstance (proxyClass );
411415 }
412416 return proxyInstantiator .newInstance (proxyClass );
413- } catch (InstantiationException e ) {
417+ } catch (InstantiationException | NoSuchMethodException | InvocationTargetException e ) {
414418 throw new DefinitionException (BeanLogger .LOG .proxyInstantiationFailed (this ), e .getCause ());
415419 } catch (IllegalAccessException e ) {
416420 throw new DefinitionException (BeanLogger .LOG .proxyInstantiationBeanAccessFailed (this ), e .getCause ());
@@ -601,7 +605,8 @@ private Class<T> createProxyClass(Class<?> originalClass, String proxyClassName)
601605 List <DeferredBytecode > initialValueBytecode = new ArrayList <DeferredBytecode >();
602606
603607 // Workaround for IBM JVM - the ACC_STATIC flag should only be required for class file with version number 51.0 or above
604- ClassMethod staticConstructor = proxyClassType .addMethod (AccessFlag .of (AccessFlag .PUBLIC , AccessFlag .STATIC ), "<clinit>" , "V" );
608+ ClassMethod staticConstructor = proxyClassType .addMethod (AccessFlag .of (AccessFlag .PUBLIC , AccessFlag .STATIC ),
609+ "<clinit>" , "V" );
605610
606611 addFields (proxyClassType , initialValueBytecode );
607612 addConstructors (proxyClassType , initialValueBytecode );
@@ -619,7 +624,8 @@ private Class<T> createProxyClass(Class<?> originalClass, String proxyClassName)
619624
620625 ProtectionDomain domain = AccessController .doPrivileged (new GetProtectionDomainAction (proxiedBeanType ));
621626
622- if (proxiedBeanType .getPackage () == null || proxiedBeanType .getPackage ().getName ().isEmpty () || proxiedBeanType .equals (Object .class )) {
627+ if (proxiedBeanType .getPackage () == null || proxiedBeanType .getPackage ().getName ().isEmpty ()
628+ || proxiedBeanType .equals (Object .class )) {
623629 domain = ProxyFactory .class .getProtectionDomain ();
624630 } else if (System .getSecurityManager () != null ) {
625631 ProtectionDomainCache cache = Container .instance (contextId ).services ().get (ProtectionDomainCache .class );
@@ -635,7 +641,8 @@ private ClassFile newClassFile(String name, int accessFlags, String superclass,
635641 // We need to use a (non-deprecated) method that avoids instantiating DefaultClassFactory.INSTANCE
636642 // If that happens, we will have module accessibility issues and the need to use --add-opens clausules
637643 // NOTE: the CL and ClassFactory are never really used to define the class, see WeldDefaultProxyServices
638- return new ClassFile (name , accessFlags , superclass , ProxyFactory .class .getClassLoader (), DummyClassFactoryImpl .INSTANCE , interfaces );
644+ return new ClassFile (name , accessFlags , superclass , ProxyFactory .class .getClassLoader (),
645+ DummyClassFactoryImpl .INSTANCE , interfaces );
639646 } catch (Exception e ) {
640647 throw BeanLogger .LOG .unableToCreateClassFile (name , e .getCause ());
641648 }
@@ -667,14 +674,17 @@ protected void addConstructors(ClassFile proxyClassType, List<DeferredBytecode>
667674 ConstructorUtils .addDefaultConstructor (proxyClassType , initialValueBytecode , !useConstructedFlag ());
668675 } else {
669676 boolean constructorFound = false ;
670- for (Constructor <?> constructor : AccessController .doPrivileged (new GetDeclaredConstructorsAction (getBeanType ()))) {
677+ for (Constructor <?> constructor : AccessController
678+ .doPrivileged (new GetDeclaredConstructorsAction (getBeanType ()))) {
671679 if ((constructor .getModifiers () & Modifier .PRIVATE ) == 0 ) {
672680 constructorFound = true ;
673681 String [] exceptions = new String [constructor .getExceptionTypes ().length ];
674682 for (int i = 0 ; i < exceptions .length ; ++i ) {
675683 exceptions [i ] = constructor .getExceptionTypes ()[i ].getName ();
676684 }
677- ConstructorUtils .addConstructor (BytecodeUtils .VOID_CLASS_DESCRIPTOR , DescriptorUtils .parameterDescriptors (constructor .getParameterTypes ()), exceptions , proxyClassType , initialValueBytecode , !useConstructedFlag ());
685+ ConstructorUtils .addConstructor (BytecodeUtils .VOID_CLASS_DESCRIPTOR ,
686+ DescriptorUtils .parameterDescriptors (constructor .getParameterTypes ()), exceptions ,
687+ proxyClassType , initialValueBytecode , !useConstructedFlag ());
678688 }
679689 }
680690 if (!constructorFound ) {
@@ -734,13 +744,16 @@ protected void addMethodsFromClass(ClassFile proxyClassType, ClassMethod staticC
734744 // In rare cases, the bean class may be abstract - in this case we have to add methods from all interfaces implemented by any abstract class
735745 // from the hierarchy
736746 boolean isBeanClassAbstract = Modifier .isAbstract (cls .getModifiers ());
747+ // a final method might have a non-final declaration in abstract superclass
748+ // hence we need to remember which we saw and skip those in superclasses
749+ Set <MethodSignature > foundFinalMethods = new HashSet <>();
737750
738751 while (cls != null ) {
739- addMethods (cls , proxyClassType , staticConstructor );
752+ addMethods (cls , proxyClassType , staticConstructor , foundFinalMethods );
740753 if (isBeanClassAbstract && Modifier .isAbstract (cls .getModifiers ())) {
741754 for (Class <?> implementedInterface : Reflections .getInterfaceClosure (cls )) {
742755 if (!additionalInterfaces .contains (implementedInterface )) {
743- addMethods (implementedInterface , proxyClassType , staticConstructor );
756+ addMethods (implementedInterface , proxyClassType , staticConstructor , foundFinalMethods );
744757 }
745758 }
746759 }
@@ -769,9 +782,14 @@ protected void addMethodsFromClass(ClassFile proxyClassType, ClassMethod staticC
769782 }
770783 }
771784
772- private void addMethods (Class <?> cls , ClassFile proxyClassType , ClassMethod staticConstructor ) {
785+ private void addMethods (Class <?> cls , ClassFile proxyClassType , ClassMethod staticConstructor ,
786+ Set <MethodSignature > foundFinalmethods ) {
773787 for (Method method : AccessController .doPrivileged (new GetDeclaredMethodsAction (cls ))) {
774- if (isMethodAccepted (method , getProxySuperclass ())) {
788+ MethodSignature methodSignature = new MethodSignatureImpl (method );
789+ if (Modifier .isFinal (method .getModifiers ())) {
790+ foundFinalmethods .add (methodSignature );
791+ }
792+ if (isMethodAccepted (method , getProxySuperclass ()) && !foundFinalmethods .contains (methodSignature )) {
775793 try {
776794 MethodInformation methodInfo = new RuntimeMethodInformation (method );
777795 ClassMethod classMethod = proxyClassType .addMethod (method );
@@ -818,7 +836,8 @@ protected void generateEqualsMethod(ClassFile proxyClassType) {
818836
819837 }
820838
821- protected void createSpecialMethodBody (ClassMethod proxyClassType , MethodInformation method , ClassMethod staticConstructor ) {
839+ protected void createSpecialMethodBody (ClassMethod proxyClassType , MethodInformation method ,
840+ ClassMethod staticConstructor ) {
822841 createInterceptorBody (proxyClassType , method , staticConstructor );
823842 }
824843
@@ -856,7 +875,8 @@ protected void addConstructedGuardToMethodBody(final ClassMethod classMethod, St
856875 cond .branchEnd (jumpMarker );
857876 }
858877
859- protected void createForwardingMethodBody (ClassMethod classMethod , MethodInformation method , ClassMethod staticConstructor ) {
878+ protected void createForwardingMethodBody (ClassMethod classMethod , MethodInformation method ,
879+ ClassMethod staticConstructor ) {
860880 createInterceptorBody (classMethod , method , staticConstructor );
861881 }
862882
@@ -884,7 +904,8 @@ protected void createInterceptorBody(ClassMethod classMethod, MethodInformation
884904 * the method invocation
885905 * @param bytecodeMethodResolver The resolver that returns the method to invoke
886906 */
887- protected void invokeMethodHandler (ClassMethod classMethod , MethodInformation method , boolean addReturnInstruction , BytecodeMethodResolver bytecodeMethodResolver , ClassMethod staticConstructor ) {
907+ protected void invokeMethodHandler (ClassMethod classMethod , MethodInformation method , boolean addReturnInstruction ,
908+ BytecodeMethodResolver bytecodeMethodResolver , ClassMethod staticConstructor ) {
888909 // now we need to build the bytecode. The order we do this in is as
889910 // follows:
890911 // load methodHandler
@@ -901,7 +922,8 @@ protected void invokeMethodHandler(ClassMethod classMethod, MethodInformation me
901922 b .aload (0 );
902923 getMethodHandlerField (classMethod .getClassFile (), b );
903924 b .aload (0 );
904- bytecodeMethodResolver .getDeclaredMethod (classMethod , method .getDeclaringClass (), method .getName (), method .getParameterTypes (), staticConstructor );
925+ bytecodeMethodResolver .getDeclaredMethod (classMethod , method .getDeclaringClass (), method .getName (),
926+ method .getParameterTypes (), staticConstructor );
905927 b .aconstNull ();
906928
907929 b .iconst (method .getParameterTypes ().length );
@@ -927,7 +949,8 @@ protected void invokeMethodHandler(ClassMethod classMethod, MethodInformation me
927949 }
928950 // now we have all our arguments on the stack
929951 // lets invoke the method
930- b .invokeinterface (MethodHandler .class .getName (), INVOKE_METHOD_NAME , LJAVA_LANG_OBJECT , new String []{LJAVA_LANG_OBJECT ,
952+ b .invokeinterface (MethodHandler .class .getName (), INVOKE_METHOD_NAME , LJAVA_LANG_OBJECT ,
953+ new String [] { LJAVA_LANG_OBJECT ,
931954 LJAVA_LANG_REFLECT_METHOD , LJAVA_LANG_REFLECT_METHOD , "[" + LJAVA_LANG_OBJECT });
932955 if (addReturnInstruction ) {
933956 // now we need to return the appropriate type
@@ -964,9 +987,9 @@ protected void addSpecialMethods(ClassFile proxyClassType, ClassMethod staticCon
964987 MethodInformation getInstanceMethodInfo = new RuntimeMethodInformation (getInstanceMethod );
965988 createInterceptorBody (proxyClassType .addMethod (getInstanceMethod ), getInstanceMethodInfo , staticConstructor );
966989
967-
968990 MethodInformation getInstanceClassMethodInfo = new RuntimeMethodInformation (getInstanceClassMethod );
969- createInterceptorBody (proxyClassType .addMethod (getInstanceClassMethod ), getInstanceClassMethodInfo , staticConstructor );
991+ createInterceptorBody (proxyClassType .addMethod (getInstanceClassMethod ), getInstanceClassMethodInfo ,
992+ staticConstructor );
970993
971994 Method setMethodHandlerMethod = ProxyObject .class .getMethod ("weld_setHandler" , MethodHandler .class );
972995 generateSetMethodHandlerBody (proxyClassType .addMethod (setMethodHandlerMethod ));
@@ -983,7 +1006,8 @@ protected void generateSetMethodHandlerBody(ClassMethod method) {
9831006 b .aload (0 );
9841007 b .aload (1 );
9851008 b .checkcast (getMethodHandlerType ());
986- b .putfield (method .getClassFile ().getName (), METHOD_HANDLER_FIELD_NAME , DescriptorUtils .makeDescriptor (getMethodHandlerType ()));
1009+ b .putfield (method .getClassFile ().getName (), METHOD_HANDLER_FIELD_NAME ,
1010+ DescriptorUtils .makeDescriptor (getMethodHandlerType ()));
9871011 b .returnInstruction ();
9881012 }
9891013
@@ -1002,19 +1026,23 @@ protected void generateGetMethodHandlerBody(ClassMethod method) {
10021026 * however the proxy is directly created without calling the constructor
10031027 */
10041028 private void addConstructorsForBeanWithPrivateConstructors (ClassFile proxyClassType ) {
1005- ClassMethod ctor = proxyClassType .addMethod (AccessFlag .PUBLIC , INIT_METHOD_NAME , BytecodeUtils .VOID_CLASS_DESCRIPTOR , LJAVA_LANG_BYTE );
1029+ ClassMethod ctor = proxyClassType .addMethod (AccessFlag .PUBLIC , INIT_METHOD_NAME , BytecodeUtils .VOID_CLASS_DESCRIPTOR ,
1030+ LJAVA_LANG_BYTE );
10061031 CodeAttribute b = ctor .getCodeAttribute ();
10071032 b .aload (0 );
10081033 b .aconstNull ();
10091034 b .aconstNull ();
1010- b .invokespecial (proxyClassType .getName (), INIT_METHOD_NAME , "(" + LJAVA_LANG_BYTE + LJAVA_LANG_BYTE + ")" + BytecodeUtils .VOID_CLASS_DESCRIPTOR );
1035+ b .invokespecial (proxyClassType .getName (), INIT_METHOD_NAME ,
1036+ "(" + LJAVA_LANG_BYTE + LJAVA_LANG_BYTE + ")" + BytecodeUtils .VOID_CLASS_DESCRIPTOR );
10111037 b .returnInstruction ();
10121038
1013- ctor = proxyClassType .addMethod (AccessFlag .PUBLIC , INIT_METHOD_NAME , BytecodeUtils .VOID_CLASS_DESCRIPTOR , LJAVA_LANG_BYTE , LJAVA_LANG_BYTE );
1039+ ctor = proxyClassType .addMethod (AccessFlag .PUBLIC , INIT_METHOD_NAME , BytecodeUtils .VOID_CLASS_DESCRIPTOR ,
1040+ LJAVA_LANG_BYTE , LJAVA_LANG_BYTE );
10141041 b = ctor .getCodeAttribute ();
10151042 b .aload (0 );
10161043 b .aconstNull ();
1017- b .invokespecial (proxyClassType .getName (), INIT_METHOD_NAME , "(" + LJAVA_LANG_BYTE + ")" + BytecodeUtils .VOID_CLASS_DESCRIPTOR );
1044+ b .invokespecial (proxyClassType .getName (), INIT_METHOD_NAME ,
1045+ "(" + LJAVA_LANG_BYTE + ")" + BytecodeUtils .VOID_CLASS_DESCRIPTOR );
10181046 b .returnInstruction ();
10191047 }
10201048
@@ -1097,6 +1125,7 @@ private ProxyNameHolder(String packageName, String className, Bean<?> bean) {
10971125
10981126 /**
10991127 * Class name, never null
1128+ *
11001129 * @return class name, never null
11011130 */
11021131 public String getClassName () {
@@ -1105,6 +1134,7 @@ public String getClassName() {
11051134
11061135 /**
11071136 * Package name, can be null
1137+ *
11081138 * @return package name or null
11091139 */
11101140 public String getPackageName () {
0 commit comments