WARN: [kryo] Unable to load class slade.core.Child with kryo's ClassLoader. Retrying with current...
Unable to find class: slade.core.Child
Serialization trace:
child (slade.core.Parent)
I have an issue where Kryo throws the above error when trying to deserialize a custom object type contained within the root object type. This only happens when running from within an OSGi bundle and referencing the object from within another OSGi bundle. (I am using Karaf as my OSGi implementation)
I can see that this is something to do with Class Loaders, though from what I can see it's using the type loader it needs. I have uploaded a tar containing a sample 3 projects created inside NetBeans to show the isolated issue. No custom class loaders are used (as can be seen in the sample code).
Project setup:
core
- OSGi bundle
- Contains the
Parent
andChild
classes - Exports everything
bundle
- OSGi bundle
- Has a dependency on Kryo
- Has a dependency on core
- Creates an instance of
Parent
containing an instance ofChild
, then serializes into a byte array using Kryo and attempts to deserialize back to the object (this is where the error happens) - Uses class loader:
BundleWiringImpl$BundleClassLoader
app
- Java Application
- Has a dependency on Kryo
- Has a dependency on core
- Creates an instance of
Parent
containing an instance ofChild
, then serializes into a byte array using Kryo and successfully deserializes back to the object - Uses class loader:
Launcher$AppClassLoader
Any suggestions as to how to resolve this would be greatly appreciated!
Source code can be downloaded from here.
I am no expert with Kryo but sounds as though Kryo is not OSGi compatible by default and considering its function (serialise and deserialise objects)I would imagine it is very difficult to make it so.
In OSGi, each bundle is given its own ClassLoader and only has visibility of the classes within the bundle and those classes it imports from other bundles (or their packages). If, as I say above, Kryo is not OSGi compatible then it will import no packages and if you think about it how can it import all possible packages that people want to use? I imagine that Kryo requires the class you wish to deserialise for it to have a 'blueprint' to construct an instance from the byte stream but if it hasn't got visibility how can it do so? Hence the class not found exception (I believe).
How can you fix this? Not easily I think. I had to do something similar but fortunately the library I worked with had a method to allow me to register a Class object so it was then aware of that class. I do not know if Kryo has the same function.