[ 
https://issues.apache.org/jira/browse/OPENJPA-133?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Kevin Sutter resolved OPENJPA-133.
----------------------------------

    Resolution: Fixed

Modified the processing of the getMethod() method to find the designated 
method, regardless if it's public, private, protected, or package.

> Can't find non-public callback methods with superclass or interface parameters
> ------------------------------------------------------------------------------
>
>                 Key: OPENJPA-133
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-133
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: jpa
>            Reporter: Kevin Sutter
>         Assigned To: Kevin Sutter
>
> Using xml to define my listener callback methods (doesn't make any difference 
> whether we're using MappedSuperclass or Entity):
>       <mapped-superclass 
> class="com.ibm.ws.persistence.tests.callbacks.CallbackSuperclass">
>                       <entity-listeners>
>                               <entity-listener 
> class="com.ibm.ws.persistence.tests.callbacks.CallbackListener">
>                                       <!--
>                                       <pre-persist  
> method-name="prePersistXML" />
>                                       -->
>                                       <post-persist 
> method-name="postPersistXML" />
>                                       <!--
>                                       <pre-remove   method-name="preRemove" />
>                                       <post-remove  method-name="postRemove" 
> />
>                                       <pre-update   method-name="preUpdate" />
>                                       <post-update  method-name="postUpdate" 
> />
>                                       <post-load    method-name="postLoad" />
>                                       -->
>                               </entity-listener>
>                       </entity-listeners>
>       </mapped-superclass>
> My Entity heirarchy is defined as follows:
> public interface CallbackMarker { }
> @MappedSuperclass
> public class CallbackSuperclass implements CallbackMarker { .. }
> @Entity
> public class CallbackEntity extends CallbackSuperclass { .. }
> My listener method is defined as follows:
> public class CallbackListener {
> :
>     private void postPersistXML(CallbackMarker cbm) {
>         System.out.println("PostPersist (ListenerXML) on CallbackMarker: " + 
> cbm);
>         ((CallbackEntity)cbm).postSuccessful = true;
>     }
> :
> }
> I'm probably clouding the issue with all of these details, but the real 
> problem is that we're not properly finding the postPersistXML(CallbackMarker 
> cbm) method.  When I run the example, I am getting the following exception.  
> The original
> call stack is huge, so I will just include the "caused by":
> Caused by: java.lang.NoSuchMethodException: 
> com.ibm.ws.persistence.tests.callbacks.CallbackListener.postPersistXML(com.ibm.ws.persistence.tests.callbacks.CallbackSuperclass)
>       at java.lang.Class.throwNoSuchMethodException(Class.java:271)
>       at java.lang.Class.getMethod(Class.java:748)
>       at 
> org.apache.openjpa.event.MethodLifecycleCallbacks.getMethod(MethodLifecycleCallbacks.java:123)
> Digging through the problem, I am finding that we're not properly reflecting 
> on the Class to find the appropriate Method.  First, we
> do a getMethods(), which only returns the public methods.  Of course, nothing 
> matches up, so we end up in the catch {} block.  Here,
> we attempt a getDeclaredMethod() passing in the specific type for the 
> argument.  This doesn't work in this case since the specific
> type (CallbackSuperclass) isn't on the Method signature (the interface 
> CallbackMarker is).  Also, calling getDeclaredMethod only looks in the 
> specific Class and does not go up the heirarchy (like getMethods() does).  
> So, we have a couple of problems with this
> method.
> My proposed change is to use the getDeclaredMethods() invocation and manually 
> go up the heirarchy (if necessary).  If we go all the way up the tree without 
> finding the method, then we throw the exception.  This seems to clear up the 
> processing and makes the code
> more readable (no try/catch is required).  You could argue that this approach 
> might take more processing since we might have to get the Superclass and make 
> additional getDeclaredMethods() invocations.  But, my guess is that most of 
> the methods being requested will be on the base class and no additional 
> invocations will be necessary.
> FYI, this problem only exists with the XML configuration since the annotated 
> version doesn't do this parameter checking.  Annotated callback methods just 
> register the method and assume that it will work.  If it doesn't, then we get 
> a runtime exception with IllegalArgumentException.  Whether we should do this 
> type checking for the annotated callbacks is a topic for a separate JIRA 
> report...

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to