[
https://issues.apache.org/jira/browse/OWB-306?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12838579#action_12838579
]
David Blevins commented on OWB-306:
-----------------------------------
Here is the basic code we use in OpenEJB for this. Essentially all annotated
methods we find are collected as CallbackInfo objects (that part is not
important) then we go back and find the first method of that name+params by
starting at the top of the inheritance and going backwards till we hit
something (important) then we check to see if the declaring classes are the
same, if they are not we throw the entry away as that means the method was
overridden in a subclass. We don't need to check if that method itself is
annotated with the callback annotation because if it was there will be another
CallbackInfo in the list for it, so we can just ignore that aspect and let it
be found when it comes up in the list.
{code}
public static class CallbackInfo extends InfoObject {
public String className;
public String method;
}
/**
* Used for getting the java.lang.reflect.Method objects for the following
callbacks:
*
* - @PostConstruct <any-scope> void <method-name>(InvocationContext)
* - @PreDestroy <any-scope> void <method-name>(InvocationContext)
* - @PrePassivate <any-scope> void <method-name>(InvocationContext)
* - @PostActivate <any-scope> void <method-name>(InvocationContext)
* - @AroundInvoke <any-scope> Object <method-name>(InvocationContext)
throws Exception
*
* @param clazz
* @param callbackInfos the raw CallbackInfo objects
* @param methods the collection where the created methods will be placed
*/
private void toMethods(Class clazz, List<CallbackInfo> callbackInfos,
List<Method> methods) {
for (CallbackInfo callbackInfo : callbackInfos) {
try {
Method method = getMethod(clazz, callbackInfo.method,
InvocationContext.class);
if (callbackInfo.className == null &&
method.getDeclaringClass().equals(clazz)){
methods.add(method);
}
if
(method.getDeclaringClass().getName().equals(callbackInfo.className)){
methods.add(method);
}
} catch (NoSuchMethodException e) {
logger.warning("Interceptor method not found (skipping): public
Object " + callbackInfo.method + "(InvocationContext); in class " +
clazz.getName());
}
}
// I can't remember why we sort them, think it's just for easy debugging
Collections.sort(methods, new MethodCallbackComparator());
}
/**
* Used by toMethods and toCallbacks to find the nearest
java.lang.reflect.Method with the given
* name and parameters. Callbacks can be private so class.getMethod()
cannot be used. Searching
* starts by looking in the specified class, if the method is not found
searching continues with
* the immediate parent and continues recurssively until the method is
found or java.lang.Object
* is reached. If the method is not found a NoSuchMethodException is
thrown.
*
* @param clazz
* @param methodName
* @param parameterTypes
* @return
* @throws NoSuchMethodException if the method is not found in this class
or any of its parent classes
*/
private Method getMethod(Class clazz, String methodName, Class...
parameterTypes) throws NoSuchMethodException {
NoSuchMethodException original = null;
while (clazz != null){
try {
Method method = clazz.getDeclaredMethod(methodName,
parameterTypes);
return SetAccessible.on(method);
} catch (NoSuchMethodException e) {
if (original == null) original = e;
}
clazz = clazz.getSuperclass();
}
throw original;
}
{code}
> overrridden @AroundInvoke and lifecycle interceptors are still run
> ------------------------------------------------------------------
>
> Key: OWB-306
> URL: https://issues.apache.org/jira/browse/OWB-306
> Project: OpenWebBeans
> Issue Type: Bug
> Affects Versions: M3
> Reporter: Eric Covener
> Assignee: Eric Covener
> Fix For: 1.0.0
>
> Original Estimate: 8h
> Remaining Estimate: 8h
>
> Interceptor spec says:
> ---
> If an around-invoke method is overridden by another method (regardless of
> whether that method is itself an around-invoke method), it will not be
> invoked.
> If a lifecycle callback interceptor method is overridden by another method
> (regardless of whether that
> method is itself a lifecycle callback interceptor method (of the same or
> different type)), it will not be
> invoked.
> ---
> I don't have a fix for this issue, but it is at least conceptually pretty
> easy to grok.
> It seems that we can't just check the stack or even all enabled interceptors
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.