[ 
https://issues.apache.org/jira/browse/OPENJPA-540?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12580577#action_12580577
 ] 

Kevin Sutter commented on OPENJPA-540:
--------------------------------------

The classloading issue for this environment seems to be related to the loader 
returned by this invocation:

            ClassLoader loader = _conf.getClassResolverInstance()
                  .getClassLoader(getClass(), null);

The loader returned by the ClassResolverImpl (and there are no external 
ClassResolvers configured) is a Spring classloader:

[3/18/08 14:36:26:281 PDT] 00000013 SystemOut     O   BJK: [EMAIL PROTECTED]

I'm not an expert with Spring, but it seems that this 
SimpleInstrumentableClassLoader uses OverridingClassLoader which calls 
getResourceAsStream, instruments the bytecodes, and then defines the class.

Unfortunately, this returned Class along with the associated Method classes do 
not seem to be compatible with the eventual Reflective Method invocations 
(reference the IllegalArgumentException in the Issue description).

All other classloaders that are available to us during this processing (this 
WASManagedRuntime classloader, the context classloader, and the jndi object's 
classloader) all seem to return a more "reasonable" classloader:

[3/18/08 14:36:26:281 PDT] 00000013 SystemOut     O   BJK: this loader=
[EMAIL PROTECTED]

The WebSphere compound classloader works much better and provides us with the 
appropriate Class and Method objects to complete this WAS, Spring, and OpenJPA 
scenario.

I, personally, do not quite understand the logic in the ClassResolver code for 
obtaining or creating the appropriate classloader.  There's a comment in this 
Impl that says we need to do this to be compliant with section 12.5 of the 
spec.  The JPA spec only has 11 chapters, so this must be referring to some 
other spec.  JDO, maybe?  Since this part of the kernel, that very well could 
be.

But, even a more basic question is why do we need to get the loader from this 
ClassResolver instance?  It seems that if we are in the WASManagedRuntime class 
and we have found the WAS ExtendedJTATransaction object in JNDI, then why are 
we concerned about this ClassResolver?  It would seem that a simple call to to 
getClass().getClassLoader() would suffice for the WebSphere interfaces.

Since this WASManagedRuntime class is only used in the non-EJB3 environments 
(where the TransactionSynchronizationRegistry doesn't exist yet), making this 
type of change seems benign.  And, the various test scenarios that we have for 
WebSphere, Spring, and OpenJPA seem to work (again), it seems like a safe path. 
 I will post the proposed patch shortly.  Any comments or suggestions will be 
appreciated.

Thanks,
Kevin


> Classloading issue with WAS, Spring, and OpenJPA
> ------------------------------------------------
>
>                 Key: OPENJPA-540
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-540
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: kernel
>    Affects Versions: 1.0.0, 1.0.1, 1.0.2, 1.0.3, 1.1.0
>            Reporter: Kevin Sutter
>            Assignee: Kevin Sutter
>             Fix For: 1.0.3, 1.1.0
>
>
> The WASManagedRuntime class needs to dynamically load and process a couple of 
> WebSphere-specific classes in order to interact with the WebSphere 
> Transaction Manager.  Currently, when these classes are loaded 
> (ExtendedJTATransaction and SynchronizationCallback), there is some problem 
> with the Method invocations that are invoked against the JNDI object that is 
> looked up (java:comp/websphere/ExtendedJTATransaction).  There seems to be a 
> mismatch between the Interface classes that are loaded to obtain the Method 
> objects and the actual object that is returned by the JNDI lookup.  The 
> callstack is similar to the following:
> Caused by: <openjpa-1.0.1-r420667:592145 nonfatal user error> 
> org.apache.openjpa.persistence.InvalidStateException: An error occured 
> reflecting WebSphere proprietary interfaces. Please ensure that you are 
> running the application from within WebSphere Application Server (version 
> 5.0.2 or newer).
>       at 
> org.apache.openjpa.ee.WASManagedRuntime$WASTransaction.getGlobalId(WASManagedRuntime.java:157)
>       at 
> org.apache.openjpa.ee.WASManagedRuntime$WASTransaction.getStatus(WASManagedRuntime.java:104)
>       ... 49 more
> Caused by: java.lang.IllegalArgumentException
>       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>       at 
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
>       at 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>       at java.lang.reflect.Method.invoke(Method.java:615)
>       at 
> org.apache.openjpa.ee.WASManagedRuntime$WASTransaction.getGlobalId(WASManagedRuntime.java:155)
>       ... 50 more
> The call to getGlobalId in WASManagedRuntime is like this:
>                 byte[] rval = (byte[]) 
> _getGlobalId.invoke(_extendedTransaction, null);
> Debugging this problem has narrowed it down to a classloading issue for this 
> scenario of using WAS v6.1.0.13, Spring 2.5.2, and OpenJPA 1.0.x.  I'll post 
> more on the proposed solution shortly.
> Kevin

-- 
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