6 Replies Latest reply on Sep 6, 2007 12:33 AM by EJP

    ClassNotFoundException when deserialized from web app

    843790
      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.
        • 1. Re: ClassNotFoundException when deserialized from web app
          843790
          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).
          • 2. Re: ClassNotFoundException when deserialized from web app
            843790
            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.
            • 3. Re: ClassNotFoundException when deserialized from web app
              843790
              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
              • 4. Re: ClassNotFoundException when deserialized from web app
                843790
                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.
                • 5. Re: ClassNotFoundException when deserialized from web app
                  843790
                  I got a similar problem:

                  1) I load that class from thread context class loader

                  2) Then I serialize the object

                  3) When I want to desirialize the object I got ClassNotFoundException
                  because the class is not in the system class loader

                  Maybe some one can help here ?
                  • 6. Re: ClassNotFoundException when deserialized from web app
                    EJP
                    If stream is corrupted or other i/o error. Then also
                    ClassNotFoundException is thrown....
                    Just to note that this is definitely untrue. In those cases you get the IOException or StreamCorruptedException or whatever.