ClassNotFoundException when deserialized from web app

Hi,

Sorry for being little over descriptive here. I have an issue deserializing a file that contains a Map<String, List><POJOs>>. These POJO bean classes are stored in a jar file uder web-app/lib. I can deserialize the file from a standalone java program, from tomcat web app when tomcat is started from within Eclipse IDE; but I can not get it to work from the same webapp when tomcat is started in standalone mode (not from within IDE). I have some javabeans added into a List object which is added to a LinkedHashMap object in the serialized file.

This is the partial stack trace -

java.lang.ClassNotFoundException: com.biz.icomp.dbi.DBCustomer

at java.net.URLClassLoader$1.run(URLClassLoader.java:200)

at java.security.AccessController.doPrivileged(Native Method)

at java.net.URLClassLoader.findClass(URLClassLoader.java:188)

at java.lang.ClassLoader.loadClass(ClassLoader.java:306)

at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)

at java.lang.ClassLoader.loadClass(ClassLoader.java:251)

at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)

at java.lang.Class.forName0(Native Method)

at java.lang.Class.forName(Class.java:242)

at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:585)

This is the code -

FileInputStream fis = new FileInputStream(serializedFilePath);

ObjectInputStream ois = new ObjectInputStream(fis);

Map map = (Map)ois.readObject();

ois.close();

I even tried to override the default class loader as -

ClassLoader old = Thread.currentThread().getContextClassLoader();

FileInputStream fis = new FileInputStream(serializedFilePath);

ObjectInputStream ois = new ObjectInputStream(fis);

File root = new File(<path of jar file containing the DBCustomer and similar classes>);

URLClassLoader urlLoader = new URLClassLoader(new URL[] { root.toURL() }, Thread.currentThread().getContextClassLoader());

Map map = (Map)ois.readObject();

ois.close();

Thread.currentThread().setContextClassLoader(old);

It still doesn't work. I also tried printing the default class loader and the loader after overriding it. This is what I see -

>When run from a standalone java class-

Default Class Loader -> sun.misc.Launcher$AppClassLoader@a39137

URLClassLoader Class Loader -> java.net.URLClassLoader@127f79d

>When run from tomcat started directly (not from IDE)-

Default Class Loader -> WebappClassLoader

delegate: false

repositories:

/WEB-INF/classes/

-> Parent Classloader:

org.apache.catalina.loader.StandardClassLoader@25c828 (these last 3 lines are automatically printed by tomcat container)

URLClassLoader Class Loader -> java.net.URLClassLoader@170a4d0

>When run from tomcat started within Eclipse-

Default Class Loader -> WebappClassLoader

delegate: false

repositories:

/WEB-INF/classes/

-> Parent Classloader:

org.apache.catalina.loader.StandardClassLoader@10d4f27

URLClassLoader Class Loader -> java.net.URLClassLoader@1ec4333

The class which is not found by the class loader, is actually there in a jar file in WEB-IN\lib. As I said, it works when I start tomcat from eclipse. Am I missing anything? Appreciate your help.

[3429 byte] By [jtigrea] at [2007-11-27 8:13:11]
# 1
You do need to set up your web application to have access to that jar.When running inside an IDE the IDE usually takes care of those details, but you will need to configure things properly when running as it should (outside the IDE that is).
jwentinga at 2007-7-12 19:57:42 > top of Java-index,Core,Core APIs...
# 2

Thanks for your reply. I have been using that jar (of bean classes) in the rest of the application and never had any classpath issue when put it in WEB-INF\lib. But when I try to deserialize, somehow it can not access it. I also tried copying this jar to common\lib of tomcat installation to make available for all applications globally. It did not help either.

jtigrea at 2007-7-12 19:57:42 > top of Java-index,Core,Core APIs...
# 3

> Hi,

> Sorry for being little over descriptive here. I have

> an issue deserializing a file that contains a

> Map<String, List><POJOs>>. These POJO bean classes are

> stored in a jar file uder web-app/lib. I can

> deserialize the file from a standalone java program,

> from tomcat web app when tomcat is started from

> within Eclipse IDE; but I can not get it to work from

> the same webapp when tomcat is started in standalone

> mode (not from within IDE). I have some javabeans

> added into a List object which is added to a

> LinkedHashMap object in the serialized file.

>

> This is the partial stack trace -

> java.lang.ClassNotFoundException:

> com.biz.icomp.dbi.DBCustomer

> at

> java.net.URLClassLoader$1.run(URLClassLoader.java:200)

>

> at java.security.AccessController.doPrivileged(Native

> Method)

> at

> java.net.URLClassLoader.findClass(URLClassLoader.java:

> 188)

> at

> java.lang.ClassLoader.loadClass(ClassLoader.java:306)

> at

> sun.misc.Launcher$AppClassLoader.loadClass(Launcher.ja

> va:268)

> at

> java.lang.ClassLoader.loadClass(ClassLoader.java:251)

> at

> java.lang.ClassLoader.loadClassInternal(ClassLoader.ja

> va:319)

> at java.lang.Class.forName0(Native Method)

> at java.lang.Class.forName(Class.java:242)

> at

> java.io.ObjectInputStream.resolveClass(ObjectInputStre

> am.java:585)

>

> This is the code -

> FileInputStream fis = new

> FileInputStream(serializedFilePath);

> ObjectInputStream ois = new ObjectInputStream(fis);

> Map map = (Map)ois.readObject();

> ois.close();

>

> I even tried to override the default class loader as

> -

> ClassLoader old =

> Thread.currentThread().getContextClassLoader();

> FileInputStream fis = new

> FileInputStream(serializedFilePath);

> ObjectInputStream ois = new ObjectInputStream(fis);

> File root = new File(<path of jar file containing the

> DBCustomer and similar classes>);

> URLClassLoader urlLoader = new URLClassLoader(new

> URL[] { root.toURL() },

> Thread.currentThread().getContextClassLoader());

> Map map = (Map)ois.readObject();

> ois.close();

> Thread.currentThread().setContextClassLoader(old);

>

> It still doesn't work. I also tried printing the

> default class loader and the loader after overriding

> it. This is what I see -

> >When run from a standalone java class-

> Default Class Loader ->

> sun.misc.Launcher$AppClassLoader@a39137

> URLClassLoader Class Loader ->

> java.net.URLClassLoader@127f79d

>

> >When run from tomcat started directly (not from

> IDE)-

> Default Class Loader -> WebappClassLoader

>delegate: false

> repositories:

>/WEB-INF/classes/

> > Parent Classloader:

> org.apache.catalina.loader.StandardClassLoader@25c828

> (these last 3 lines are automatically printed by

> tomcat container)

>

> URLClassLoader Class Loader ->

> java.net.URLClassLoader@170a4d0

>

> >When run from tomcat started within Eclipse-

> Default Class Loader -> WebappClassLoader

>delegate: false

> repositories:

>/WEB-INF/classes/

> > Parent Classloader:

> org.apache.catalina.loader.StandardClassLoader@10d4f27

>

>

> URLClassLoader Class Loader ->

> java.net.URLClassLoader@1ec4333

>

>

> The class which is not found by the class loader, is

> actually there in a jar file in WEB-IN\lib. As I

> said, it works when I start tomcat from eclipse. Am I

> missing anything? Appreciate your help.

ClassNotFoundException occurs if the Virtual Machine cannot find the class for the type of the object instance being deserialized on the classpath.

If stream is corrupted or other i/o error. Then also ClassNotFoundException is thrown....

You can try this.

Configuration conf = (Configuration)ois.readObject();

This line of code reads your Configuration object back into memory

rajulananda at 2007-7-12 19:57:42 > top of Java-index,Core,Core APIs...
# 4

> ClassNotFoundException occurs if the Virtual Machine

> cannot find the class for the type of the object

> instance being deserialized on the classpath.

>

> If stream is corrupted or other i/o error. Then also

> ClassNotFoundException is thrown....

>

> You can try this.

>

> Configuration conf =

> (Configuration)ois.readObject();

> This line of code reads your Configuration object

> back into memory

rajulanand,

How different is that than what I did? I need to call readObject() anyway and cast it to the type of object I expect to deserialize and that is what I am doing. I guess I did not follow what you are trying to say.

jtigrea at 2007-7-12 19:57:42 > top of Java-index,Core,Core APIs...