Announcement Announcement Module
Collapse
No announcement yet.
ClassNotFound During Deserialization(canot use even TCCL) Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • ClassNotFound During Deserialization(canot use even TCCL)

    I have use cases where framework bundle does deserialization of the object.

    Now the framework cannot import object which has to be deserialized. [as framework is generic]

    How do i handle this case ?

    Code:
    2010-04-16 08:16:37.045] PacketDigestTaskManager TaskDelegator #18 System.err  com.springsource.kernel.osgi.framework.ExtendedClassNotFoundException: com.pg.jms.messages.JMSUserProfile in KernelBundleClassLoader: [bundle=XXX_0.0.0]
    
    [2010-04-16 08:16:37.046] PacketDigestTaskManager TaskDelegator #18 System.err          at com.springsource.kernel.userregion.internal.equinox.KernelBundleClassLoader.loadClass(KernelBundleClassLoader.java:149)
    
    [2010-04-16 08:16:37.047] PacketDigestTaskManager TaskDelegator #18 System.err          at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
    
    [2010-04-16 08:16:37.047] PacketDigestTaskManager TaskDelegator #18 System.err          at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
    
    [2010-04-16 08:16:37.047] PacketDigestTaskManager TaskDelegator #18 System.err          at java.lang.Class.forName0(Native Method)
    
    [2010-04-16 08:16:37.047] PacketDigestTaskManager TaskDelegator #18 System.err          at java.lang.Class.forName(Class.java:247)
    
    [2010-04-16 08:16:37.048] PacketDigestTaskManager TaskDelegator #18 System.err          at java.io.ObjectInputStream.resolveC
    
    
    This was caused by this piece of framework code
    
         public static Object getObject(byte[] bArr){
            try{
                ByteArrayInputStream bais = new ByteArrayInputStream(bArr);
                ObjectInputStream ois = new ObjectInputStream(bais);
                return ois.readObject();   - was failing
            }catch(Exception err){
                err.printStackTrace();
            }
            return null;
       }
    In the above case how can i use TCCL ?

    Is there any way I can achieve TCCL visiblity during deserialization ?

  • #2
    In general if you are going to use de/serialisation in an OSGi environment, you have to make sure that the class spaces are equivalent between the point of serialisation and the point of deserialisation. There is some standardisation work going on in this area in the OSGi Alliance, but essentially that a number of pitfalls that you will need to discover and design around.

    I hope that helps. dm Server does not provide any explicit support for de/serialisation other than the TCCL support I have mentioned recently on another thread.

    Comment


    • #3
      We had this issue for two frameworks which deserializes our application classes - jboss and ehcache.

      Jboss - they use TCCL to do the deserialization.(which is set in our bundle activator)

      Ehcache - doesnt seem to take of this when a listener is registered with it.


      Thanks Glyn.

      Comment


      • #4
        I'm glad you made progress.

        Comment


        • #5
          Just an update so that it could help anyone stuck with similar problem.

          Java ObjectInputStream doesnt take into consideration Thread Context Class Loader when deserializing the classes.Hence most cases fail under OSgi.

          To get away with this case we had to extend ObjectInputStream and override the resolveClass method to use tccl.

          Code as follows


          Code:
               ObjectInputStream ois = new ObjectInputStream(bais);
                      return ois.readObject()
          
          
          Overidden method
          
          
          	@Override
          	public Class<?> resolveClass(ObjectStreamClass desc) throws IOException,
          			ClassNotFoundException {
          	
          	ClassLoader currentTccl = null;
          		try {
          		
          			currentTccl = Thread.currentThread().getContextClassLoader();
          			return currentTccl.loadClass(desc.getName());
          
          		} catch (Exception e) {
                                     //my sysouts
          			}
          
          		}
          		return super.resolveClass(desc);
          	}

          Comment


          • #6
            Interesting. Thanks for sharing that. I suspect this works because of dm Server's careful management of TCCLs. (For any non dm Server users seeing this, note this approach may not be quite so successful in other environments such as vanilla Equinox or Felix.)

            Comment


            • #7
              Yes that is true.

              We did observe that when we called the bundle activator the tccl was set to the bundles class loader which was very useful.

              Comment

              Working...
              X