use of org.jboss.classfilewriter.DuplicateMemberException in project core by weld.
the class ProxyFactory method addMethodsFromClass.
protected void addMethodsFromClass(ClassFile proxyClassType, ClassMethod staticConstructor) {
try {
// Add all methods from the class hierarchy
Class<?> cls = getBeanType();
// First add equals/hashCode methods if required
generateEqualsMethod(proxyClassType);
generateHashCodeMethod(proxyClassType);
// 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
// from the hierarchy
boolean isBeanClassAbstract = Modifier.isAbstract(cls.getModifiers());
while (cls != null) {
addMethods(cls, proxyClassType, staticConstructor);
if (isBeanClassAbstract && Modifier.isAbstract(cls.getModifiers())) {
for (Class<?> implementedInterface : Reflections.getInterfaceClosure(cls)) {
if (!additionalInterfaces.contains(implementedInterface)) {
addMethods(implementedInterface, proxyClassType, staticConstructor);
}
}
}
cls = cls.getSuperclass();
}
for (Class<?> c : additionalInterfaces) {
for (Method method : c.getMethods()) {
if (isMethodAccepted(method, getProxySuperclass())) {
try {
MethodInformation methodInfo = new RuntimeMethodInformation(method);
ClassMethod classMethod = proxyClassType.addMethod(method);
if (Reflections.isDefault(method)) {
addConstructedGuardToMethodBody(classMethod);
createForwardingMethodBody(classMethod, methodInfo, staticConstructor);
} else {
createSpecialMethodBody(classMethod, methodInfo, staticConstructor);
}
BeanLogger.LOG.addingMethodToProxy(method);
} catch (DuplicateMemberException e) {
}
}
}
}
} catch (Exception e) {
throw new WeldException(e);
}
}
use of org.jboss.classfilewriter.DuplicateMemberException in project core by weld.
the class ProxyFactory method addMethods.
private void addMethods(Class<?> cls, ClassFile proxyClassType, ClassMethod staticConstructor) {
for (Method method : AccessController.doPrivileged(new GetDeclaredMethodsAction(cls))) {
if (isMethodAccepted(method, getProxySuperclass())) {
try {
MethodInformation methodInfo = new RuntimeMethodInformation(method);
ClassMethod classMethod = proxyClassType.addMethod(method);
addConstructedGuardToMethodBody(classMethod);
createForwardingMethodBody(classMethod, methodInfo, staticConstructor);
BeanLogger.LOG.addingMethodToProxy(method);
} catch (DuplicateMemberException e) {
// do nothing. This will happen if superclass methods
// have been overridden
}
}
}
}
use of org.jboss.classfilewriter.DuplicateMemberException in project core by weld.
the class InterceptedSubclassFactory method addMethodsFromClass.
@Override
protected void addMethodsFromClass(ClassFile proxyClassType, ClassMethod staticConstructor) {
try {
final Set<MethodSignature> finalMethods = new HashSet<MethodSignature>();
final Set<BridgeMethod> processedBridgeMethods = new HashSet<BridgeMethod>();
// Add all methods from the class hierarchy
Class<?> cls = getBeanType();
while (cls != null) {
Set<BridgeMethod> declaredBridgeMethods = new HashSet<BridgeMethod>();
for (Method method : AccessController.doPrivileged(new GetDeclaredMethodsAction(cls))) {
final MethodSignatureImpl methodSignature = new MethodSignatureImpl(method);
if (!Modifier.isFinal(method.getModifiers()) && !method.isBridge() && enhancedMethodSignatures.contains(methodSignature) && !finalMethods.contains(methodSignature) && !bridgeMethodsContainsMethod(processedBridgeMethods, methodSignature, method.getGenericReturnType(), Modifier.isAbstract(method.getModifiers()))) {
try {
final MethodInformation methodInfo = new RuntimeMethodInformation(method);
if (interceptedMethodSignatures.contains(methodSignature)) {
// create delegate-to-super method
createDelegateMethod(proxyClassType, method, methodInfo);
// this method is intercepted
// override a subclass method to delegate to method handler
ClassMethod classMethod = proxyClassType.addMethod(method);
addConstructedGuardToMethodBody(classMethod);
createForwardingMethodBody(classMethod, methodInfo, staticConstructor);
BeanLogger.LOG.addingMethodToProxy(method);
} else {
// this method is not intercepted
// we still need to override and push InterceptionDecorationContext stack to prevent full interception
ClassMethod classMethod = proxyClassType.addMethod(method);
new RunWithinInterceptionDecorationContextGenerator(classMethod, this) {
@Override
void doWork(CodeAttribute b, ClassMethod classMethod) {
if (Modifier.isPrivate(classMethod.getAccessFlags())) {
// Weld cannot use invokespecial to invoke a private method from the superclass
invokePrivateMethodHandler(b, classMethod, methodInfo, staticConstructor);
} else {
// build the bytecode that invokes the super class method directly
b.aload(0);
// create the method invocation
b.loadMethodParameters();
b.invokespecial(methodInfo.getDeclaringClass(), methodInfo.getName(), methodInfo.getDescriptor());
}
// leave the result on top of the stack
}
@Override
void doReturn(CodeAttribute b, ClassMethod method) {
// assumes doWork() result is on top of the stack
b.returnInstruction();
}
}.runStartIfNotOnTop();
}
} catch (DuplicateMemberException e) {
// do nothing. This will happen if superclass methods have
// been overridden
}
} else {
if (Modifier.isFinal(method.getModifiers())) {
finalMethods.add(methodSignature);
}
if (method.isBridge()) {
declaredBridgeMethods.add(new BridgeMethod(methodSignature, method.getGenericReturnType()));
}
}
}
processedBridgeMethods.addAll(declaredBridgeMethods);
cls = cls.getSuperclass();
}
for (Class<?> c : getAdditionalInterfaces()) {
for (Method method : c.getMethods()) {
MethodSignature signature = new MethodSignatureImpl(method);
// For interfaces we do not consider return types when going through processed bridge methods
if (enhancedMethodSignatures.contains(signature) && !bridgeMethodsContainsMethod(processedBridgeMethods, signature, null, Modifier.isAbstract(method.getModifiers()))) {
try {
MethodInformation methodInfo = new RuntimeMethodInformation(method);
if (interceptedMethodSignatures.contains(signature) && Reflections.isDefault(method)) {
createDelegateMethod(proxyClassType, method, methodInfo);
// this method is intercepted
// override a subclass method to delegate to method handler
ClassMethod classMethod = proxyClassType.addMethod(method);
addConstructedGuardToMethodBody(classMethod);
createForwardingMethodBody(classMethod, methodInfo, staticConstructor);
BeanLogger.LOG.addingMethodToProxy(method);
} else {
if (Reflections.isDefault(method)) {
createDelegateMethod(proxyClassType, method, methodInfo);
} else {
final ClassMethod classMethod = proxyClassType.addMethod(method);
createSpecialMethodBody(classMethod, methodInfo, staticConstructor);
BeanLogger.LOG.addingMethodToProxy(method);
}
}
} catch (DuplicateMemberException e) {
}
}
if (method.isBridge()) {
processedBridgeMethods.add(new BridgeMethod(signature, method.getGenericReturnType()));
}
}
}
} catch (Exception e) {
throw new WeldException(e);
}
}
use of org.jboss.classfilewriter.DuplicateMemberException in project core by weld.
the class InterceptedProxyFactory method addMethodsFromClass.
@Override
protected void addMethodsFromClass(ClassFile proxyClassType, ClassMethod staticConstructor) {
try {
final Set<MethodSignature> finalMethods = new HashSet<MethodSignature>();
final Set<MethodSignature> processedBridgeMethods = new HashSet<MethodSignature>();
// Add all methods from the class hierarchy
Class<?> cls = getBeanType();
while (cls != null) {
Set<MethodSignature> declaredBridgeMethods = new HashSet<MethodSignature>();
for (Method method : AccessController.doPrivileged(new GetDeclaredMethodsAction(cls))) {
final MethodSignatureImpl methodSignature = new MethodSignatureImpl(method);
if (isMethodAccepted(method, getProxySuperclass()) && enhancedMethodSignatures.contains(methodSignature) && !finalMethods.contains(methodSignature) && !processedBridgeMethods.contains(methodSignature)) {
try {
final MethodInformation methodInfo = new RuntimeMethodInformation(method);
ClassMethod classMethod = proxyClassType.addMethod(method);
if (interceptedMethodSignatures.contains(methodSignature)) {
// this method is intercepted
final CodeAttribute b = classMethod.getCodeAttribute();
b.aload(0);
getMethodHandlerField(classMethod.getClassFile(), b);
// get the Stack
b.invokestatic(InterceptionDecorationContext.class.getName(), "getStack", "()" + DescriptorUtils.makeDescriptor(Stack.class));
b.aload(0);
DEFAULT_METHOD_RESOLVER.getDeclaredMethod(classMethod, methodInfo.getDeclaringClass(), method.getName(), methodInfo.getParameterTypes(), staticConstructor);
b.dup();
// Params
b.iconst(method.getParameterTypes().length);
b.anewarray(JAVA_LANG_OBJECT);
int localVariableCount = 1;
for (int i = 0; i < method.getParameterTypes().length; ++i) {
String typeString = methodInfo.getParameterTypes()[i];
// duplicate the array reference
b.dup();
b.iconst(i);
// load the parameter value
BytecodeUtils.addLoadInstruction(b, typeString, localVariableCount);
// box the parameter if necessary
Boxing.boxIfNessesary(b, typeString);
// and store it in the array
b.aastore();
if (isWide(typeString)) {
localVariableCount = localVariableCount + 2;
} else {
localVariableCount++;
}
}
b.invokeinterface(StackAwareMethodHandler.class.getName(), INVOKE_METHOD_NAME, LJAVA_LANG_OBJECT, InterceptedSubclassFactory.INVOKE_METHOD_PARAMETERS);
if (methodInfo.getReturnType().equals(BytecodeUtils.VOID_CLASS_DESCRIPTOR)) {
b.returnInstruction();
} else if (isPrimitive(methodInfo.getReturnType())) {
Boxing.unbox(b, classMethod.getReturnType());
b.returnInstruction();
} else {
b.checkcast(BytecodeUtils.getName(methodInfo.getReturnType()));
b.returnInstruction();
}
BeanLogger.LOG.addingMethodToProxy(method);
} else {
final CodeAttribute b = classMethod.getCodeAttribute();
b.aload(0);
getMethodHandlerField(classMethod.getClassFile(), b);
b.aload(0);
DEFAULT_METHOD_RESOLVER.getDeclaredMethod(classMethod, methodInfo.getDeclaringClass(), method.getName(), methodInfo.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 = methodInfo.getParameterTypes()[i];
// duplicate the array reference
b.dup();
b.iconst(i);
// load the parameter value
BytecodeUtils.addLoadInstruction(b, typeString, localVariableCount);
// box the parameter if necessary
Boxing.boxIfNessesary(b, typeString);
// and store it in the array
b.aastore();
if (isWide(typeString)) {
localVariableCount = localVariableCount + 2;
} else {
localVariableCount++;
}
}
b.invokeinterface(MethodHandler.class.getName(), INVOKE_METHOD_NAME, LJAVA_LANG_OBJECT, new String[] { LJAVA_LANG_OBJECT, LJAVA_LANG_REFLECT_METHOD, LJAVA_LANG_REFLECT_METHOD, "[" + LJAVA_LANG_OBJECT });
if (methodInfo.getReturnType().equals(BytecodeUtils.VOID_CLASS_DESCRIPTOR)) {
b.returnInstruction();
} else if (isPrimitive(methodInfo.getReturnType())) {
Boxing.unbox(b, classMethod.getReturnType());
b.returnInstruction();
} else {
b.checkcast(BytecodeUtils.getName(methodInfo.getReturnType()));
b.returnInstruction();
}
}
} catch (DuplicateMemberException e) {
// do nothing. This will happen if superclass methods have
// been overridden
}
} else {
if (Modifier.isFinal(method.getModifiers())) {
finalMethods.add(methodSignature);
}
if (method.isBridge()) {
declaredBridgeMethods.add(methodSignature);
}
}
}
processedBridgeMethods.addAll(declaredBridgeMethods);
cls = cls.getSuperclass();
}
} catch (Exception e) {
throw new WeldException(e);
}
}
use of org.jboss.classfilewriter.DuplicateMemberException in project core by weld.
the class ConstructorUtils method addConstructor.
/**
* Adds a constructor that delegates to a super constructor with the same
* descriptor. The bytecode in initialValueBytecode will be executed at the
* start of the constructor and can be used to initialize fields to a default
* value. As the object is not properly constructed at this point this
* bytecode may not reference this (i.e. the variable at location 0)
*
* @param returnType the constructor descriptor
* @param exceptions any exceptions that are thrown
* @param file the classfile to add the constructor to
* @param initialValueBytecode bytecode that can be used to set initial values
*/
public static void addConstructor(String returnType, String[] params, String[] exceptions, ClassFile file, List<DeferredBytecode> initialValueBytecode, final boolean useUnsafeInstantiators) {
try {
final String initMethodName = "<init>";
final ClassMethod ctor = file.addMethod(AccessFlag.PUBLIC, initMethodName, returnType, params);
ctor.addCheckedExceptions(exceptions);
final CodeAttribute b = ctor.getCodeAttribute();
for (final DeferredBytecode iv : initialValueBytecode) {
iv.apply(b);
}
// we need to generate a constructor with a single invokespecial call
// to the super constructor
// to do this we need to push all the arguments on the stack first
// local variables is the number of parameters +1 for this
// if some of the parameters are wide this may go up.
b.aload(0);
b.loadMethodParameters();
// now we have the parameters on the stack
b.invokespecial(file.getSuperclass(), initMethodName, methodDescriptor(params, returnType));
if (!useUnsafeInstantiators) {
// now set constructed to true
b.aload(0);
b.iconst(1);
b.putfield(file.getName(), ProxyFactory.CONSTRUCTED_FLAG_NAME, BytecodeUtils.BOOLEAN_CLASS_DESCRIPTOR);
}
b.returnInstruction();
} catch (DuplicateMemberException e) {
throw new RuntimeException(e);
}
}
Aggregations