Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » [CDO] Loading JAVA_CLASS CdoType -> ClassNotFoundException
[CDO] Loading JAVA_CLASS CdoType -> ClassNotFoundException [message #1826650] Tue, 28 April 2020 09:16 Go to next message
Linuxhippy Mising name is currently offline Linuxhippy Mising nameFriend
Messages: 59
Registered: July 2009
Member
Hi,

When trying to load a cdo object which contains a field of the type CDOTypeImpl.JAVA_CLASS, I get an ClassNotFound-Exception when trying to load cdo objects with references to application provided classes (in my case an enum). Storing that Object however worked as expected.

I am rather new to OSGI, but from what I understand, this is expected - when storing the object, the custom class has already been loaded by the application-bundle classloader. However when deserializing the byte[], the bundle-classloader of org.eclipse.emf.cdo.common is used (because ObjectInputStream using latestUserDefinedLoader() by default) has no knowledge of the application-provided class.

Any idea how I can provide my application-bundle class loader to CDO in order to allow for application-classes to be deserialized?

Thanks you in advance & best regards, Clemens
Re: [CDO] Loading JAVA_CLASS CdoType -> ClassNotFoundException [message #1826662 is a reply to message #1826650] Tue, 28 April 2020 13:15 Go to previous messageGo to next message
Linuxhippy Mising name is currently offline Linuxhippy Mising nameFriend
Messages: 59
Registered: July 2009
Member
Are there any downsides in changing CDOs implementation to using the ContextClassLoader instead of what ObjectInputStream does?

Something like (CDOTypeImpl):

ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream((byte[])value))
{
   protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException
   {
      String name = desc.getName();
      try {
          return Class.forName(name, false, Thread.currentThread().getContextClassLoader());
      } catch (ClassNotFoundException ex) {
      return super.resolveClass(desc);
    }
  }
};

[Updated on: Tue, 28 April 2020 13:15]

Report message to a moderator

Re: [CDO] Loading JAVA_CLASS CdoType -> ClassNotFoundException [message #1826665 is a reply to message #1826662] Tue, 28 April 2020 13:38 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6556
Registered: July 2009
Senior Member
All your conclusions seem to be correct. I suspect that in the past 15 years nobody has tried to use org.eclipse.emf.cdo.common.model.CDOType.JAVA_CLASS. I'd have to study to implications of changing the ObjectInputStream's classloader. Perhaps it's just simpler to use an existing Equinox mechanism, e.g., "Eclipse-BuddyPolicy". If you have the sources of CDO available you can prototype it. Just two changes are needed:

1) In /org.eclipse.emf.cdo.common/META-INF/MANIFEST.MF add the following line:

Eclipse-BuddyPolicy: registered


2) In your application bundle's manifest add the following line:

Eclipse-RegisterBuddy: org.eclipse.emf.cdo.common


If you confirm that this solves the problem I will change the org.eclipse.emf.cdo.common bundle accordingly...


Re: [CDO] Loading JAVA_CLASS CdoType -> ClassNotFoundException [message #1826675 is a reply to message #1826665] Tue, 28 April 2020 16:29 Go to previous messageGo to next message
Linuxhippy Mising name is currently offline Linuxhippy Mising nameFriend
Messages: 59
Registered: July 2009
Member
Hi Eike,

Thanks a lot for taking a look at this.
I gave your suggestion a try, however I was not successful unfortunately - I still get the ClassNotFoundExceptions - even when trying to use the context class loader.
However ObjectInputStream seems to do a good job finding an appropriate class loader - it seems the BundleLoader is queried for the serialized class - still it seems not to be able to locate the class in question.

I wonder - are there other cases where CDO bundles have to load application-specific classes?

In case the Buddy-approach doesn't work (maybe it was just a mistake on my side), would an optional Classloader (system property or thread local) be an option? In this case the default behavour would stay unchanged.

Caused by: java.lang.ClassNotFoundException: some.proprietary.package.EnumClass cannot be found by org.eclipse.emf.cdo.common_4.9.1 //increased version to be sure the plugin hasn't been cached somewhere / I am really running with the new manifest
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:514)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:425)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:171)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:398)
at java.base/java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:727)
at org.eclipse.emf.cdo.internal.common.model.CDOTypeImpl$25$1.resolveClass(CDOTypeImpl.java:609) // Left over from experiments
at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1943)
at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1829)
at java.base/java.io.ObjectInputStream.readEnum(ObjectInputStream.java:2069)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1640)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:464)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
at org.eclipse.emf.cdo.internal.common.model.CDOTypeImpl$25.convertToEMF(CDOTypeImpl.java:614)


[Updated on: Tue, 28 April 2020 16:40]

Report message to a moderator

Re: [CDO] Loading JAVA_CLASS CdoType -> ClassNotFoundException [message #1826680 is a reply to message #1826675] Tue, 28 April 2020 18:04 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 31839
Registered: July 2009
Senior Member
I'm not sure if you've looked at this:

https://wiki.eclipse.org/Context_Class_Loader_Enhancements#Eclipse-RegisterBuddy

Note the comments about Eclipse-RegisterBuddy and dependencies...

In emf.common and emf.ecore we use:

Eclipse-BuddyPolicy: dependent

Perhaps that's worth a try.


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: [CDO] Loading JAVA_CLASS CdoType -> ClassNotFoundException [message #1826694 is a reply to message #1826680] Wed, 29 April 2020 05:58 Go to previous messageGo to next message
Linuxhippy Mising name is currently offline Linuxhippy Mising nameFriend
Messages: 59
Registered: July 2009
Member
Ed: Thanks a lot for the hint - "Eclipse-BuddyPolicy: dependent" worked perfectly fine and is probably the more comfortable solution :)

I wonder however, why "Eclipse-BuddyPolicy: registered" + "Eclipse-RegisterBuddy: org.eclipse.emf.cdo.common" didn't work , I tried to specify RegisterBuddy on both bundles, the bundle defining the serialized class as well as the bundle actually calling into CDO when the object of the class was deserialized - however I still got ClassNotFound.

Thanks, Clemens
Re: [CDO] Loading JAVA_CLASS CdoType -> ClassNotFoundException [message #1826698 is a reply to message #1826694] Wed, 29 April 2020 07:22 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 31839
Registered: July 2009
Senior Member
I wonder if this condition was true when you tried the "registered" approach:

The bundle X must be dependent on a package exported by bundle Y. This can happen through either a Require-Bundle or Import-Package constraint.

I.e., did the registering bundle actually explicitly require org.eclipse.emf.cdo.common?


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: [CDO] Loading JAVA_CLASS CdoType -> ClassNotFoundException [message #1826705 is a reply to message #1826698] Wed, 29 April 2020 09:39 Go to previous messageGo to next message
Linuxhippy Mising name is currently offline Linuxhippy Mising nameFriend
Messages: 59
Registered: July 2009
Member
Ed: Thanks again, indeed that was the case. With explicitly requiring cdo.common it works as expected.

Eike: Could you please add Eclipse-BuddyPolicy: dependent or Eclipse-BuddyPolicy: registered?
Re: [CDO] Loading JAVA_CLASS CdoType -> ClassNotFoundException [message #1826755 is a reply to message #1826705] Thu, 30 April 2020 05:28 Go to previous message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6556
Registered: July 2009
Senior Member
Thanks to everybody here for figuring this out! Please open a bugzilla so that we can track the issue.

Previous Topic:issues while creating ecore from WSDL XSD
Next Topic:EMF + Multiple inheritance with Interfaces
Goto Forum:
  


Current Time: Mon Apr 19 23:16:01 GMT 2021

Powered by FUDForum. Page generated in 0.02288 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top