Results 1 to 7 of 7

Thread: ClassNotFound During Deserialization(canot use even TCCL)

Hybrid View

  1. #1
    Join Date
    Nov 2008
    Location
    London,UK
    Posts
    299

    Default 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. #2
    Join Date
    Oct 2008
    Location
    Winchester, UK
    Posts
    535

    Default

    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.
    Glyn Normington
    SpringSource

  3. #3
    Join Date
    Nov 2008
    Location
    London,UK
    Posts
    299

    Default

    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.

  4. #4
    Join Date
    Oct 2008
    Location
    Winchester, UK
    Posts
    535

    Default

    I'm glad you made progress.
    Glyn Normington
    SpringSource

  5. #5
    Join Date
    Nov 2008
    Location
    London,UK
    Posts
    299

    Default

    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);
    	}

  6. #6
    Join Date
    Oct 2008
    Location
    Winchester, UK
    Posts
    535

    Default

    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.)
    Glyn Normington
    SpringSource

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •