You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by "Mikasch, Fares (EXT-IBM - DE/Berlin)" <Fa...@nsn.com> on 2010/03/25 11:56:03 UTC

UndeclaredThrowableException as a result of false ClassLoading

Hello,

Apache Tomcat/5.5.26
jdk1.5.0_11 / jdk1.5.0_19
Windows XP / SunOS 5.10

Short description of the use case:
- User fills form with some wrong information
- tomcat sends (RMI call) to another server
- server throws ValidationException back to tomcat
- tomcat _sometimes_ wraps the ValidationException with
UndeclaredThrowableException

Installation:
Tomcat hosts several web applications (war), each of the wars include a
jar with the ValidationException class in the WEB-INF/lib directory. The
deployed jars are indentical. The jar cannot be put to shared or common
because of some internal reasons.

Analysis:
In the case where the ValidationException is wrapped by the
UndeclaredThrowableException, the WebappClassLoader instance of the
current thread and the instance of the WebappClassLoader of the caught
(and wrapped) ValidationException are different. As a result the
ValidationException that is caught is not the same as the one that is
expected and thus violates the interface =>
UndeclaredThrowableException.
In the following code the "instanceof ValidationException" returns
false:
	[...]
            key = saveSomething();
        }
        catch (ValidationException e)
        {
	[...]
        }
        catch( UndeclaredThrowableException e1 )
        {
            Throwable t = e1.getUndeclaredThrowable();
            
            if(t instanceof ValidationException)
            {
	    [...]
            }
            else
            {
                log.info( "Not a ValidationException: ", t );
                log.info( "  thrown Exception class: " + t.getClass() +
": " + getUniqueID( t ) );
                log.info( "expected Exception class: " +
ValidationException.class + ": " + getUniqueID( new
ValidationException() ) );
                throw e1;
            }
        }

Hint:
getUniqueID also prints the ClassLoader information. In this case both
ValidationExceptions are loaded by different WebappClassLoader
instances.

Question:
It seems that during unmarshalling of the ValidationException it is not
predictable which ValidationException (identified by its ClassLoader) is
constructed. It seems that the WebApp may get a ValidationException that
doesn't fit to its own ClassLoader but to a ClassLoader of another
WebApp.
Is this a bug of the tomcat? I mean shouldn't the WebApp get the
ValidationException from the same ClassLoader that belongs to the WebApp
that invoked the RMI call?

Regards
Fares


RE: UndeclaredThrowableException as a result of false ClassLoading

Posted by "Mikasch, Fares (EXT-IBM - DE/Berlin)" <Fa...@nsn.com>.
Hi Chuck,

Thanks for your response.

You are right, the webapp does the RMI call, and as I am debugging I got
unsure if this is a tomcat issue or a jbossall-client(.jar) issue.

Of course it is the Java runtime that wraps exceptions with the UTE when
the (non Runtime-) Exception does not meet the interface.

To reproduce this issue I didn't use the SOAP service. 

Some additional information: Sometimes the behavior changes during the
runtime of the tomcat from wrapped to unwrapped and vice versa. But it
is much easier to reproduce it by just restarting the tomcat a few times
and retry.

Regards
Fares

-----Original Message-----
From: ext Caldarale, Charles R [mailto:Chuck.Caldarale@unisys.com] 
Sent: Thursday, March 25, 2010 4:16 PM
To: Tomcat Users List
Subject: RE: UndeclaredThrowableException as a result of false
ClassLoading

> From: Mikasch, Fares (EXT-IBM - DE/Berlin)
> [mailto:Fares.Mikasch.ext@nsn.com]
> Subject: UndeclaredThrowableException as a result of false
ClassLoading
> 
> Short description of the use case:
> - User fills form with some wrong information
> - tomcat sends (RMI call) to another server

Let's get the terminology right: it's your webapp doing this, not
Tomcat.  Tomcat has no knowledge of or involvement with outbound
connections that your webapp attempts.

> - tomcat _sometimes_ wraps the ValidationException with
> UndeclaredThrowableException

No, Tomcat doesn't.  There is no usage of UndeclaredThrowableException
within Tomcat.

> In the case where the ValidationException is wrapped by the
> UndeclaredThrowableException, the WebappClassLoader instance of the
> current thread and the instance of the WebappClassLoader of the caught
> (and wrapped) ValidationException are different.

Are you sure they are instances of *Tomcat's* WebappClassLoader?  Note
that Axis uses its own classloading mechanism, and you may well be
stumbling into a problem with that.

 - Chuck


THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY
MATERIAL and is thus for use only by the intended recipient. If you
received this in error, please contact the sender and delete the e-mail
and its attachments from all computers.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: UndeclaredThrowableException as a result of false ClassLoading

Posted by "Caldarale, Charles R" <Ch...@unisys.com>.
> From: Mikasch, Fares (EXT-IBM - DE/Berlin)
> [mailto:Fares.Mikasch.ext@nsn.com]
> Subject: UndeclaredThrowableException as a result of false ClassLoading
> 
> Short description of the use case:
> - User fills form with some wrong information
> - tomcat sends (RMI call) to another server

Let's get the terminology right: it's your webapp doing this, not Tomcat.  Tomcat has no knowledge of or involvement with outbound connections that your webapp attempts.

> - tomcat _sometimes_ wraps the ValidationException with
> UndeclaredThrowableException

No, Tomcat doesn't.  There is no usage of UndeclaredThrowableException within Tomcat.

> In the case where the ValidationException is wrapped by the
> UndeclaredThrowableException, the WebappClassLoader instance of the
> current thread and the instance of the WebappClassLoader of the caught
> (and wrapped) ValidationException are different.

Are you sure they are instances of *Tomcat's* WebappClassLoader?  Note that Axis uses its own classloading mechanism, and you may well be stumbling into a problem with that.

 - Chuck


THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: UndeclaredThrowableException as a result of false ClassLoading

Posted by "Mikasch, Fares (EXT-IBM - DE/Berlin)" <Fa...@nsn.com>.
Hi Chris, 

Apparently I mixed up some lines regarding the traces during copy and
paste.
So here comes the correct trace:

INFO  [...] -                   Thread ClassLoader:
[@org.apache.catalina.loader.WebappClassLoader@78529d@cid:1d38b87@]
INFO  [...] -         BusinessDelegate ClassLoader:
[@org.apache.catalina.loader.WebappClassLoader@78529d@cid:1d38b87@]
INFO  [...] - expected Exception class classloader:
[@org.apache.catalina.loader.WebappClassLoader@78529d@cid:1d38b87@]
INFO  [...] -   thrown Exception class classloader:
[@org.apache.catalina.loader.WebappClassLoader@12b3349@cid:1d38b87@]
INFO  [...] -  Wrapped exception Class:
[@[...].validation.ValidationException@adaa9f@cid:1176e5c@]
INFO  [...] -  Wrapped exception ClassLoader......:
[@org.apache.catalina.loader.WebappClassLoader@12b3349@cid:1d38b87@] -
parent:
[@org.apache.catalina.loader.StandardClassLoader@10f0625@cid:1c86be5@]
INFO  [...] - Not a ValidationException:
[...].validation.ValidationException
INFO  [...] -   thrown Exception class: class
[...].validation.ValidationException:
[@[...].validation.ValidationException@adaa9f@cid:1176e5c@]
INFO  [...] - expected Exception class: class
[...].validation.ValidationException:
[@[...].validation.ValidationException@11f25f3@cid:12ca580@]

Sorry for the inconvenience.

So now you can see here that both ValidationExceptions although of the
same fully qualified name have a different class id because they are
loaded by different class loaders. The expected ValidationException has
the same ClassLoader as the current thread's context class loader and
the business delegate which was called to do the RMI call.

Regards
Fares

-----Original Message-----
From: ext Christopher Schultz [mailto:chris@christopherschultz.net] 
Sent: Thursday, March 25, 2010 8:48 PM
To: Tomcat Users List
Subject: Re: UndeclaredThrowableException as a result of false
ClassLoading

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Fares,

On 3/25/2010 6:56 AM, Mikasch, Fares (EXT-IBM - DE/Berlin) wrote:
> In the case where the ValidationException is wrapped by the
> UndeclaredThrowableException, the WebappClassLoader instance of the
> current thread and the instance of the WebappClassLoader of the caught
> (and wrapped) ValidationException are different.

Can you supply the full source of ValidationException? Are you storing
ClassLoader objects in the ValidationException or anything like that,
which might have a problem being de-serialized? Is it possible that you
are throwing a ValidationException from one container whose
serialVersionID doesn't match that of the receiving container?

> getUniqueID also prints the ClassLoader information. In this case both
> ValidationExceptions are loaded by different WebappClassLoader
> instances.

Care to show us the output of the above code?

> It seems that during unmarshalling of the ValidationException it is
not
> predictable which ValidationException (identified by its ClassLoader)
is
> constructed. It seems that the WebApp may get a ValidationException
that
> doesn't fit to its own ClassLoader but to a ClassLoader of another
> WebApp.

Are you calling a lookback RMI server (meaning the JVM is contacting
itself)? It would be strange for one webapp to get an object that was
loaded by another webapp unless you had put your library in a shared
location or otherwise used some kind of shared resource: anything loaded
through RMI should probably come through the WebappClassLoader.

You might want to check to see if the RMI client always uses Thread's
"context class loader" to load/define new classes. Otherwise, you might
see some weirdness like this.

> Is this a bug of the tomcat? I mean shouldn't the WebApp get the
> ValidationException from the same ClassLoader that belongs to the
WebApp
> that invoked the RMI call?

One would hope, but this has absolutely nothing to do with Tomcat: RMI
is entirely outside Tomcat's scope.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkurvggACgkQ9CaO5/Lv0PC2awCgsEOJoamv1fh5zVQy0Avhdpmo
4fQAnjF93rzRyCAObMDoW/C/9KyUcfGu
=mvkF
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: UndeclaredThrowableException as a result of false ClassLoading

Posted by "Mikasch, Fares (EXT-IBM - DE/Berlin)" <Fa...@nsn.com>.
Hi chris,

Thanks for you support.

There are no ClassLoader references stored in the ValidationExceptions
(VE) and I doublechecked serialization - all ValidationExceptions are
identical. The VE class only exists in one jar which is deployed in
several wars. 

INFO [...] - Not a ValidationException:
[...].validation.ValidationException
INFO [...] -    thrown Exception class:
[...].validation.ValidationException:
	[@[...].validation.ValidationException@f8f6ea@cid:178aae1@] 
	 :
[@org.apache.catalina.loader.WebappClassLoader@294f62@cid:1d38b87@]
INFO [...] -  expected Exception class:
[...].validation.ValidationException: 
	[@[...].validation.ValidationException@6dca9d@cid:113e8f3@]
	 :
[@org.apache.catalina.loader.WebappClassLoader@12b3349@cid:1d38b87@]

Thread
ClassLoader:[@org.apache.catalina.loader.WebappClassLoader@294f62@cid:1d
38b87@]
Hint: [@fullyQualifiedClassname@instanceId@classId@]

As I already indicated in a previous mail I am currently debugging
jbossall-client code. At a first glance it seems to make use of
Thread.currentThread().getContextClassLoader() but I will have a closer
look.

Regards
Fares

-----Original Message-----
From: ext Christopher Schultz [mailto:chris@christopherschultz.net] 
Sent: Thursday, March 25, 2010 8:48 PM
To: Tomcat Users List
Subject: Re: UndeclaredThrowableException as a result of false
ClassLoading

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Fares,

On 3/25/2010 6:56 AM, Mikasch, Fares (EXT-IBM - DE/Berlin) wrote:
> In the case where the ValidationException is wrapped by the
> UndeclaredThrowableException, the WebappClassLoader instance of the
> current thread and the instance of the WebappClassLoader of the caught
> (and wrapped) ValidationException are different.

Can you supply the full source of ValidationException? Are you storing
ClassLoader objects in the ValidationException or anything like that,
which might have a problem being de-serialized? Is it possible that you
are throwing a ValidationException from one container whose
serialVersionID doesn't match that of the receiving container?

> getUniqueID also prints the ClassLoader information. In this case both
> ValidationExceptions are loaded by different WebappClassLoader
> instances.

Care to show us the output of the above code?

> It seems that during unmarshalling of the ValidationException it is
not
> predictable which ValidationException (identified by its ClassLoader)
is
> constructed. It seems that the WebApp may get a ValidationException
that
> doesn't fit to its own ClassLoader but to a ClassLoader of another
> WebApp.

Are you calling a lookback RMI server (meaning the JVM is contacting
itself)? It would be strange for one webapp to get an object that was
loaded by another webapp unless you had put your library in a shared
location or otherwise used some kind of shared resource: anything loaded
through RMI should probably come through the WebappClassLoader.

You might want to check to see if the RMI client always uses Thread's
"context class loader" to load/define new classes. Otherwise, you might
see some weirdness like this.

> Is this a bug of the tomcat? I mean shouldn't the WebApp get the
> ValidationException from the same ClassLoader that belongs to the
WebApp
> that invoked the RMI call?

One would hope, but this has absolutely nothing to do with Tomcat: RMI
is entirely outside Tomcat's scope.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkurvggACgkQ9CaO5/Lv0PC2awCgsEOJoamv1fh5zVQy0Avhdpmo
4fQAnjF93rzRyCAObMDoW/C/9KyUcfGu
=mvkF
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: UndeclaredThrowableException as a result of false ClassLoading

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Fares,

On 3/25/2010 6:56 AM, Mikasch, Fares (EXT-IBM - DE/Berlin) wrote:
> In the case where the ValidationException is wrapped by the
> UndeclaredThrowableException, the WebappClassLoader instance of the
> current thread and the instance of the WebappClassLoader of the caught
> (and wrapped) ValidationException are different.

Can you supply the full source of ValidationException? Are you storing
ClassLoader objects in the ValidationException or anything like that,
which might have a problem being de-serialized? Is it possible that you
are throwing a ValidationException from one container whose
serialVersionID doesn't match that of the receiving container?

> getUniqueID also prints the ClassLoader information. In this case both
> ValidationExceptions are loaded by different WebappClassLoader
> instances.

Care to show us the output of the above code?

> It seems that during unmarshalling of the ValidationException it is not
> predictable which ValidationException (identified by its ClassLoader) is
> constructed. It seems that the WebApp may get a ValidationException that
> doesn't fit to its own ClassLoader but to a ClassLoader of another
> WebApp.

Are you calling a lookback RMI server (meaning the JVM is contacting
itself)? It would be strange for one webapp to get an object that was
loaded by another webapp unless you had put your library in a shared
location or otherwise used some kind of shared resource: anything loaded
through RMI should probably come through the WebappClassLoader.

You might want to check to see if the RMI client always uses Thread's
"context class loader" to load/define new classes. Otherwise, you might
see some weirdness like this.

> Is this a bug of the tomcat? I mean shouldn't the WebApp get the
> ValidationException from the same ClassLoader that belongs to the WebApp
> that invoked the RMI call?

One would hope, but this has absolutely nothing to do with Tomcat: RMI
is entirely outside Tomcat's scope.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkurvggACgkQ9CaO5/Lv0PC2awCgsEOJoamv1fh5zVQy0Avhdpmo
4fQAnjF93rzRyCAObMDoW/C/9KyUcfGu
=mvkF
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org