I don't see much difference with the reproducer you made. I've debugged the invocation of the private observer method and the exception is thrown when the proxy method created by WELD tries to invoke my private method:
private void steappe.preparation.infra.PreparationPresentationCache$Proxy$_$$_WeldSubclass.onUpdate(steappe.preparation.event.PreparationAreaPopulated)
|
invokes:
private void steappe.preparation.infra.PreparationPresentationCache.onUpdate(steappe.preparation.event.PreparationAreaPopulated)
|
The invocation is made on the method returned by the following code in WELD (class VirtualMethodInjectionPoint)
@Override |
protected Method getMethod(Object receiver) throws NoSuchMethodException { |
final Map<Class<?>, Method> methods = this.methods; |
Method method = this.methods.get(receiver.getClass()); |
if (method == null) { |
// the same method may be written to the map twice, but that is ok |
// lookupMethod is very slow |
Method delegate = getAnnotated().getJavaMember(); |
if ((hasDecorators() || MethodInjectionPointType.INITIALIZER.equals(type)) && (isPrivate(delegate) || isPackagePrivate(delegate.getModifiers()) |
&& !Objects.equals(delegate.getDeclaringClass().getPackage(), receiver.getClass().getPackage()))) { |
// Initializer methods and decorated beans - overriding does not apply to private methods and package-private methods where the subclass is in a different package |
method = accessibleMethod; |
} else { |
method = SecurityActions.lookupMethod(receiver.getClass(), delegate.getName(), delegate.getParameterTypes()); |
SecurityActions.ensureAccessible(method); |
} |
final Map<Class<?>, Method> newMethods = ImmutableMap.<Class<?>, Method>builder().putAll(methods).put(receiver.getClass(), method).build(); |
this.methods = newMethods; |
} |
return method; |
} |
|
In the code above, the else statement is executed:
method = SecurityActions.lookupMethod(receiver.getClass(), delegate.getName(), delegate.getParameterTypes()); |
SecurityActions.ensureAccessible(method);
|
During the execution of ensureAccessible:
static void ensureAccessible(AccessibleObject accessibleObject) { |
if (accessibleObject != null) { |
if (!accessibleObject.isAccessible()) { |
if (System.getSecurityManager() != null) { |
AccessController.doPrivileged(SetAccessibleAction.of(accessibleObject)); |
} else { |
accessibleObject.setAccessible(true); |
} |
} |
} |
}
|
The else statement is executed. Then the returned WELD proxy method is invoked by the NativeMethodAccessorImpl class:
public Object invoke(Object obj, Object[] args) |
throws IllegalArgumentException, InvocationTargetException |
{ |
// We can't inflate methods belonging to vm-anonymous classes because |
// that kind of class can't be referred to by name, hence can't be |
// found from the generated bytecode. |
if (++numInvocations > ReflectionFactory.inflationThreshold() |
&& !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) { |
MethodAccessorImpl acc = (MethodAccessorImpl) |
new MethodAccessorGenerator(). |
generateMethod(method.getDeclaringClass(), |
method.getName(), |
method.getParameterTypes(), |
method.getReturnType(), |
method.getExceptionTypes(), |
method.getModifiers()); |
parent.setDelegate(acc); |
} |
|
return invoke0(method, obj, args); |
}
|
During the execution of invoke0 the illegal access exception is raised, apparently because the proxy generated class cannot access my private method, despite the call to setAccessible(true). This is weird. |