Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8994595
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 15, 20262026-06-15T23:28:04+00:00 2026-06-15T23:28:04+00:00

In my osgi application I have three bundles, travel.api , table.api and utils .

  • 0

In my osgi application I have three bundles, travel.api, table.api and utils. travel.api depends on table.api which depends on utils. Note that travel.api doesn’t directly depend on utils. I use aQute Bnd to generate the manifests and I believe it is working fine. The manifests are displayed below.

There is a class called PageData that has a field of type TableData, which in turn has a field of type TestObject. PageData is located in travel.api, TableData is located in table.api and TestObject is located in utils. This all works fine when the bundles are loaded. The problem comes when I receive an array of bytes representing a PageData object. I have to deserialize it in the travel.api bundle. This shouldn’t be a problem as that is where it is defined. I use org.jboss.netty.handler.codec.serialization.ObjectDecoderInputStream and pass in the classloader from the travel.api bundle. The exception shown below is thrown but basically it says:

Caused by: java.lang.ClassNotFoundException: com.openaf.utils.TestObject not 
    found by travel.api [9].

Now this makes sense because if you look at the Import-Package for travel.api you will see that com.openaf.utils (where TestObject is located) isn’t listed. If I add this package then it is correctly deserialized. However, this doesn’t seem like a good general solution as I would have to go through every field that PageData uses and ensure that they are all imported in this module, and recursively on every field contained by those fields etc.

Am I doing something completely wrong here?

What is the best way to deserialize an object when using OSGi?

If I’m doing it correctly and I have to specify all the “deep” imports, is there a way to get Bnd to do a “deep” generation?

Any help would be greatly appreciated!

I’m using felix v4 as my osgi library.

Manifest-Version: 1
Bnd-LastModified: 1355404320862
Bundle-ManifestVersion: 2
Bundle-Name: travel.api
Bundle-SymbolicName: travel.api
Bundle-Version: 0
Created-By: 1.7.0_07 (Oracle Corporation)
Export-Package: com.openaf.travel.api;uses:="scala.runtime,scala,scala.c
 ollection,com.openaf.pagemanager.api,scala.reflect,com.openaf.table.api
 ";version="0.0.0"
Import-Package: com.openaf.pagemanager.api,com.openaf.table.api,scala,sc
 ala.collection,scala.reflect,scala.runtime
Tool: Bnd-1.44.0

Manifest-Version: 1
Bnd-LastModified: 1355404158858
Bundle-ManifestVersion: 2
Bundle-Name: table.api
Bundle-SymbolicName: table.api
Bundle-Version: 0
Created-By: 1.7.0_07 (Oracle Corporation)
Export-Package: com.openaf.table.api;uses:="scala.runtime,scala,scala.co
 llection,scala.reflect,scala.collection.immutable,scala.collection.gene
 ric,com.openaf.utils";version="0.0.0"
Import-Package: com.openaf.utils,scala,scala.collection,scala.collection
 .generic,scala.collection.immutable,scala.reflect,scala.runtime
Tool: Bnd-1.44.0

Manifest-Version: 1
Bnd-LastModified: 1355404158801
Bundle-ManifestVersion: 2
Bundle-Name: utils
Bundle-SymbolicName: utils
Bundle-Version: 0
Created-By: 1.7.0_07 (Oracle Corporation)
Export-Package: com.openaf.utils;uses:="scala.runtime,scala,scala.collec
 tion,scala.reflect";version="0.0.0"
Import-Package: scala,scala.collection,scala.reflect,scala.runtime
Tool: Bnd-1.44.0

java.io.InvalidClassException: failed to read class descriptor
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1585)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1514)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at org.jboss.netty.handler.codec.serialization.ObjectDecoderInputStream.readObject(ObjectDecoderInputStream.java:115)
at com.openaf.rmi.common.DefaultObjectEncoder$.decode(RMICommon.scala:33)
at com.openaf.rmi.client.ClientHandler.messageReceived(ClientPipelineFactory.scala:43)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296)
at org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:363)
at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:345)
at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:211)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:94)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.processSelectedKeys(AbstractNioWorker.java:372)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:246)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:38)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.ClassNotFoundException: com.openaf.utils.TestObject not found by travel.api [9]
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1460)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:72)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1843)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at org.jboss.netty.handler.codec.serialization.ClassLoaderClassResolver.resolve(ClassLoaderClassResolver.java:30)
at org.jboss.netty.handler.codec.serialization.CachingClassResolver.resolve(CachingClassResolver.java:39)
at org.jboss.netty.handler.codec.serialization.CompactObjectInputStream.readClassDescriptor(CompactObjectInputStream.java:55)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1583)
... 28 more

Thanks, Nick.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-15T23:28:05+00:00Added an answer on June 15, 2026 at 11:28 pm

    This actually sounds like a serious shortcoming in deserialization? A decent deserializer should use the class loader of the class that causes the load. The given class loader should only be used for the top level object since the there is no parent object yet.

    So in this case the given class loader is used to load PageData. PageData’s loader is used to load TableData, and TableData’s loader must be used to load TestObject. There is no logical reason why this should fail unless the deserializer you use is really brain damaged since this is the model the VM uses to load classes. I am surprised that the Java deserializer does this, I consider this behavior a serious error since it uses different rules than the VM.

    Serialization is a problem in OSGi because modularity is about hiding implementation classes; deserialization has a tendency to want to access these private classes, the antithesis of modularity. However, there are very good solutions to this (which does not include Dynamic-ImportPackage, that is reverting to JAR hell in a more complicated and expensive way than just using plain Java). The basic trick is to have a root object from a public API that has access to the private/transiently needed classes. Hmm, doesn’t this sound like a service?

    Solution

    Looking at how negative people are about this, a small example how you can solve the problem with Java Serialization (that is, ObjectInputStream, and ObjectOutputStream). In your question you mention ObjectDecoderInputStream, a class I am not familiar with.

    The setup is:

    Bundle A:    class a.A { B b; }   (import b)
    Bundle B:    class b.B { C c; }   (import c)
    Bundle C:    class c.C { }
    

    So lets first serialize an object:

    ByteArrayOutputStream bous = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(bous);
    
    oos.writeObject(this);
    oos.close();
    

    Now the hard part. We override the resolveObject method, this gives us a chance to to actually do proper class loading …

    ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bous.toByteArray())) {
        Set<ClassLoader>    lhs = new LinkedHashSet<ClassLoader>();
        {
            // Keep a set if discovered class loaders
            lhs.add(getClass().getClassLoader());
        }
    
        @Override
        protected Class< ? > resolveClass(ObjectStreamClass desc) 
             throws ClassNotFoundException, IOException {
    
             for (ClassLoader cl : lhs) try {
                 Class< ? > c = cl.loadClass(name);
    
                 // we found the class, so we can use its class loader,
                 // it is in the proper class space  if the uses constraints 
                 // are set properly (and you're using bnd so you should be ok)
    
                 lhs.add(c.getClassLoader());
    
                 // The paranoid among us would check
                 // the serial uuid here ...
                 // long uuid = desc.getSerialVersionUID();
                 // Field field = c.getField("serialVersionUID");
                 // assert uuid == field.get(null)
    
                 return c;
             } catch (Exception e) {
               // Ignore
             }
    
             // Fallback (for void and primitives)
             return super.resolveClass(desc);
         }
     };
    
     // And now we've successfully read the object ...
    
     A clone = (A) in.readObject();
    

    Please not that this only works as long as the transient graph is properly exported. I.e. if you can do new TableData then this should also work. An example that does not work is if you for example get an implementation from an interface. The interface class is not connected to the impl. class. I.e. if you had a TableDataImpl that extended TableData you would be screwed. In those cases you need some service to find the “domain” of the implementation.

    Good luck.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a server application that consists of multiple OSGi bundles, some mine, some
I have a Java application built with OSGi that I want to run in
I develop an Eclipse RCP application which makes heavy use of OSGi bundles which
I have an osgi application (in felix) with multiple bundles. There are some common
I have an OSGi application which has a command line interface and a GWT
I have an OSGi-based, server side application that uses the filesystem to store scripts
I have an application with many different parts, it runs on OSGi, so there's
I have been working on getting my OSGi application to run outside eclipse. It
Which is a good architecture for a Web Application using OSGI and GWT as
I'm developing a web application that is going to be served from an OSGi

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.