Bug 1076572 - [GSS](6.4.0) StackOverflowError when unmarshalling partially known exceptions
Summary: [GSS](6.4.0) StackOverflowError when unmarshalling partially known exceptions
Keywords:
Status: CLOSED CURRENTRELEASE
Alias: None
Product: JBoss Enterprise Application Platform 6
Classification: JBoss
Component: EJB
Version: 6.1.0,6.2.0,6.2.1
Hardware: All
OS: All
unspecified
urgent
Target Milestone: DR8
: EAP 6.4.0
Assignee: jboss-set
QA Contact: Jan Martiska
URL:
Whiteboard:
Depends On: 1156109
Blocks: 1159394
TreeView+ depends on / blocked
 
Reported: 2014-03-14 14:53 UTC by Daniel Bobbert
Modified: 2019-08-19 12:42 UTC (History)
8 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
: 1159394 (view as bug list)
Environment:
Last Closed:
Type: Bug
Embargoed:


Attachments (Terms of Use)
Complete maven project to reproduce the described bug (37.11 KB, application/zip)
2014-03-14 14:55 UTC, Daniel Bobbert
no flags Details


Links
System ID Private Priority Status Summary Last Updated
Red Hat Issue Tracker JBMAR-167 0 Major Resolved StackOverflowError when unmarshalling partially known exceptions 2018-03-28 10:27:33 UTC

Description Daniel Bobbert 2014-03-14 14:53:41 UTC
Description of problem:
The JBoss Marshaller for EJB remote calls fails with a StackOverflowError if the called method throws an exception, that is not part of the public contract but an implementation-private subclass of the exception defined in the contract.

Version-Release number of selected component (if applicable):
org.jboss.marshalling 1.3.16GA

How reproducible:
Always (see test case)

Steps to Reproduce:
1. Define two WARs (separate class loaders, that's important!)
2. Module 2 defines a method with "throws Exception_A"
3. In the implementation of Module 2, instead throw an Exception_B which extends Exception_A
4. In Module 1, call this method of module 2 through EJB remoting. So module 1 knows the contract of module 2 (and thus also Exception_A) but not the implementation details (so Exception_B is completely unknown to module 1)

See the attached maven project for a complete sample with two server modules and a standalone client that calls module 1, which in turn calls module 2 as described in the above description. To reproduce, compile the sample project, deploy modules "m1" and "m2" to a local JBoss installation and then launch the standalone client. the client should report the aforementioned StackOverflowError.


Actual results:
Infinite loop, leading to StackOverflowError in
Caused by: java.lang.StackOverflowError
	at java.util.IdentityHashMap.clear(IdentityHashMap.java:613) [rt.jar:1.7.0_45]
	at org.jboss.marshalling.cloner.SerializingCloner.reset(SerializingCloner.java:126)
	at org.jboss.marshalling.cloner.SerializingCloner.clone(SerializingCloner.java:139)
	at org.jboss.marshalling.cloner.SerializingCloner.initSerializableClone(SerializingCloner.java:274)
	at org.jboss.marshalling.cloner.SerializingCloner.initSerializableClone(SerializingCloner.java:276)
	at org.jboss.marshalling.cloner.SerializingCloner.initSerializableClone(SerializingCloner.java:276)
	at org.jboss.marshalling.cloner.SerializingCloner.initSerializableClone(SerializingCloner.java:276)
	at org.jboss.marshalling.cloner.SerializingCloner.initSerializableClone(SerializingCloner.java:276)

Expected results:
Module 1 should correctly unmarshal the unknown exception subclass.

Additional info:
The problem is in method org.jboss.marshalling.cloner.SerializingCloner.initSerializableClone
Two bad things are happening here:
1. When unmarshalling the exception, SerializingCloner expects that the exception class is either completely known in the current class loader or not at all. But in our case, we have a mixture where the base class of the exception is actually known to the class loader of module 1 and module 2, but the specific subclass in defined in module 2 only and unknown to module 1. This results in a failure of line 276:
    if (cloneClass != clone(objClass))
because in this mixed case, the parent class is already known and doesn't need to be cloned, so actually cloneClass == objClass
2. If the aforementioned condition is true, then a recursive call to initSerializableClone is issued with the exact same parameters. This naturally leads to an endless recursion. A comment above suggest, that the recursive call should check a superclass instead of the class itself but it is unclear what exactly needs to be changed here.


We could solve the problem for our case by patching the aforementioned condition to
    if (cloneClass != objClass && cloneClass != clone(objClass))

This avoids going into the endless recursion and enabled module 1 to correctly unmarshal the (locally unknown) exception subclass. We aren't sure though, whether this really fixes the original problem or just the symptoms. With our fix, the exception subclass is correctly propagated to the calling client (where it fails with a ClassNotFoundException - so unmarshalling also seems to differ between EJB remote clients and remote calls inside the JBoss container, but that's another story).


The same goes for subclasses of RuntimeExeption which have an even higher propability of not being defined as part of the API contract.

Comment 1 Daniel Bobbert 2014-03-14 14:55:11 UTC
Created attachment 874463 [details]
Complete maven project to reproduce the described bug

Comment 3 David M. Lloyd 2014-09-03 15:50:14 UTC
Need an upstream JIRA for this (JBMAR project).

Comment 6 Jan Martiska 2014-11-05 13:36:17 UTC
Verified in EAP 6.4.0.DR8 / jboss-marshalling 1.4.9.Final

Comment 7 anna.ratnaningsih@aprisma.co.id 2016-02-22 04:42:10 UTC
(In reply to Jan Martiska from comment #6)
> Verified in EAP 6.4.0.DR8 / jboss-marshalling 1.4.9.Final


How can i get jar for jboss-marshalling 1.4.9.Final, because i checked in jboss patch EAP 6.4.6 but i can not find it. Thank you.

Comment 8 Jan Martiska 2016-02-22 08:56:57 UTC
(In reply to anna.ratnaningsih.id from comment #7)
> (In reply to Jan Martiska from comment #6)
> > Verified in EAP 6.4.0.DR8 / jboss-marshalling 1.4.9.Final
> 
> 
> How can i get jar for jboss-marshalling 1.4.9.Final, because i checked in
> jboss patch EAP 6.4.6 but i can not find it. Thank you.

Hi, EAP 6.4.6 contains jboss-marshalling 1.4.10.Final and this issue should be resolved there. The patch to the jar within EAP distribution is
modules/system/layers/base/org/jboss/marshalling/main/jboss-marshalling-1.4.10.Final-redhat-1.jar


Note You need to log in before you can comment on or make changes to this bug.