History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: XSTR-423
Type: Bug Bug
Status: Reopened Reopened
Priority: Minor Minor
Assignee: Joerg Schaible
Reporter: Michael Leiseca
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
XStream

CGLIBEnhancedConverter "only one CAllback is registered"

Created: 30/Aug/07 02:57 PM   Updated: 12/Sep/08 04:52 PM
Component/s: Converters
Affects Version/s: 1.2.2
Fix Version/s: None

Issue Links:
Related
 


 Description  « Hide
According to the api for CGLIBEnhancedConverter, this converter can only be used if "only one CAllback is registered". The code to check this condition is actually incorrect:

line 84:
if (callbacks.length > 1) {

it should be:

if (Arrays.asList(callbacks).size() > 1){

This makes the code break with Hibernate proxies, even though it shouldn't.



 All   Comments   Change History      Sort Order: Ascending order - Click to sort in descending order
Joerg Schaible - 31/Aug/07 01:37 AM
Sorry, but I don't see a difference. Why should the first condition break Hibernate proxies ?

Joerg Schaible - 24/Sep/07 02:54 PM
No further response, reopen if you want to answer my question.

Joerg Schaible - 25/Feb/08 04:53 PM
Closed after no further comment has been given.

Shahiduzzaman - 21/May/08 10:34 PM
Actually CGLIBEnhancedConverter does not work for lazy loaded collections. Actually when adding callbacks Hibernate (I am using Hibernate 3.2.5) two callback types are registered - the 2nd callback type is NoOp.class which is basically No Operation. (See the CGLIBLazyInitilaizer class of hibernate source for more details). In the CGLIBEnhancedConverter of xstream callbacks are retrieved in the following way -

Callback[] callbacks = hasFactory ? ((Factory)source).getCallbacks() : getCallbacks(source);

In the callbacks array the 2nd callback is always null for Hibernate lazy loaded classes. But as the callbacks.length is checked for >1, it throws an exception. I have changed the condition from -

if (Arrays.asList(callbacks).size() > 1) {

to

if (callbacks.length > 1 && (callbacks[1] !=null && callbacks.length != 2)) {

In this case this worked perfectly. I would appreciate comments on this.


Joerg Schaible - 22/May/08 02:31 PM
This is an interesting detail. Thanks!

Shahiduzzaman - 24/May/08 01:51 AM
I have tried to find out the CGLIB proxy policy of Hibernate (as I am not a Hibernate Pro, and actually there is almost no documentation or javadoc about Hibernate's use of CGLIB, I failed). Later I posted to hibernate-dev mailing list to find out the detail (http://lists.jboss.org/pipermail/hibernate-dev/2008-May/003085.html), but seems they are bit busy right now. Anyways I checked the previous versions of Hibernate and that specific code sits there for long time (so it is less likely that there is any bug in it).

Do you have plan to work on this in the next release of Xstream (If you are busy, I would be happy to submit a patch)? This will really help in this field as I have tried JDK xmlEncoder/decoder, Commons Betwixt, Castor, Simple framework, but failed to serialize Java beans to XML with simple converter or persistentDelegates. Only Xstream with the above change is able to correctly handle Hibernate lazy loaded collections (i.e. CGLIB enhanced classes) properly.


Joerg Schaible - 25/May/08 10:11 AM
Can't say. I'll have to analyze this first. The converter is for CGLIB enhanced proxies in general, not only for ones that are created by Hibernate.

Bryan Taylor - 10/Jun/08 01:25 AM
This issue biting me right now. I've got a Hibernate cglib proxy with two callbacks. 0 is a org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer and 1 is null.

Why is a null callback ever a problem? Don't we just need to exclude multiple instantiated callbacks?

Callback[] callbacks = hasFactory ? ((Factory)source).getCallbacks() : getCallbacks(source);
Callback callback = getUnique(callbacks);
boolean isInterceptor = MethodInterceptor.class.isAssignableFrom(callback.getClass());

ExtendedHierarchicalStreamWriterHelper.startNode(writer, mapper.serializedClass(callback.getClass()), callback.getClass());
context.convertAnother(callback);

and

private Callback extractUniqueCallback(Callback[] callbacks) {
Callback firstCallback = null;
for (Callback callback: callbacks) {
if ((callback != null) && (firstCallback != null)) { throw new ConversionException("Cannot handle CGLIB enhanced proxies with multiple callbacks"); } else if (callback != null) { firstCallback = callback; }
}
return firstCallback;
}


Kasra Rasaee - 22/Jul/08 08:58 AM
Any updates on this issue? my investigation brought me to the same conclusion, there are two
callbacks registered but one of them is a null, can't we simply ignore nulls?

Can't NoOp.class also be considered ignorable?

Any news on when we can expect this to be resolved?

Thanks,

Kaz-


Frank Adcock - 12/Sep/08 04:52 PM
This also affects version 1.3