Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Sirius » [Solved] How to share a singleton between "Services.java" and other plugins ?("Services.java" is outside the OSGi classloader and therefore it has a different instance of the singleton than other plugins inside the OSGi classloader)
[Solved] How to share a singleton between "Services.java" and other plugins ? [message #1790860] Tue, 19 June 2018 08:06 Go to next message
Stéphane Tzvetkov is currently offline Stéphane TzvetkovFriend
Messages: 2
Registered: June 2018
Junior Member
Hi,
First, thank you for your great work with Sirius, this is a very usefull and interesting framework.

I'm still a beginner with this framework, so I may be using Sirius in a strange way, if so: please explain me how to do it right.

I'm using Sirius inside an Eclipse RCP application, so far everything was working great.
My Eclipse RCP applications (like all Eclipse apps) is based on the OSGi specification, wich is implemented by the Equinox framework. So in pratice I'm developping plugins that are interpreted as bundles from the OSGi point of view.

This is important because those plugins will all be related to the OSGi classloader at runtime.

On the other hand, Sirius provides a class "Services.java" that allow the execution of external (i.e. user-side) java code. For example: if I write a "run()" method in this class, I could call this method on an element of my Sirius diagram by writing "aql:self.run()" in the proper associated aql field.

My problem is: the methods inside the "Services.java" class do not depend on the OSGi classloader, but on the sun.misc classloader.

So, for example : I would like to share a singleton between the Services.java class and the rest of my Eclipse app, to share information across plugins. But because this singleton would be instanciate by two different classloaders (OSGi and sun.misc) there would be two different instances of my singleton: one in the OSGi classloader and the other one in the sun.misc classloader.

I already tried to write a classloader-safe singleton (surguy.net/articles/communication-across-classloaders.xml) (stackoverflow.com/questions/15156840/singleton-class-with-several-different-classloaders).

But without success...

My question is: is there a way to tell the "Services.java" class to use the OSGi classloader ? Or a way to tell OSGi to expose his bundles to sun.misc ? More generally: a way to avoid this classloaser issue ?

I don't know why the Services.java class is outside OSGi, maybe because it uses some reflection methods at some point ?
But I think this problem is also due to the OSGi classloader which may be not linked to the sun.misc classloader in any way. Therefore OSGi may forbid any bundles to be seen outside OSGi.

I found a way to expose some sun.misc related classes to OSGi (spring.io/blog/2009/01/19/exposing-the-boot-classpath-in-osgi/) (help.eclipse.org/neon/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fmisc%2Fruntime-options.html)
(in particular by adding those arguments to the VM arguments : -Dorg.osgi.compatibility.bootdelegation=true -Dorg.osgi.framework.bootdelegation=sun.misc.* -Dorg.osgi.framework.system.packages.extra=my.own.project.*)

But this is usless, I would like to achieve the opposite: in this case I would like to expose some OSGi related classes to sun.misc... This way Services.java could access other plugins.

I also tried to bypass the classloader issue by trying to get a bundle from the Services.java class: "Bundle bundle = FrameworkUtil.getBundle(MySingleton.class);" (in my "run()" method of Services.java I'm trying to call the "MySingleton.java" singleton) but it returns a null object;
I tried a workaround:
try {
  Bundle bundle = InternalPlatform.getDefault().getBundleContext().getBundle();

  System.out.println(">> " + bundle.getClass().getClassLoader().toString());
  Class<?> clazz = bundle.loadClass(MySingleton.class.getName());
  MySingleton instance = (MySingleton) clazz.newInstance();
  instance.setAThing(42);
  instance.runAThing();

} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
  e.printStackTrace();
}


But I get a ClassNotFoundException at "bundle.loadClass(MySingleton.class.getName());"

As an other workaround, I could share information by reading/writing through temp files, but I'd rather prefer avoid this kind of solution...

Did someone faced this kind of problem before ? Any idea on how to resolve it ?

EDIT:
Marked as solved, see below. Thanks again Florian.

[Updated on: Fri, 22 June 2018 13:52]

Report message to a moderator

Re: How to share a singleton between "Services.java" and other plugins ? [message #1790927 is a reply to message #1790860] Wed, 20 June 2018 09:48 Go to previous messageGo to next message
Florian Barbin is currently offline Florian BarbinFriend
Messages: 194
Registered: August 2010
Senior Member
Hi,

Are you testing your modeler in the same runtime where your odesign and all associated services classes are defined? Because there is a mechanism to load the services in the same workspace. The classloader used may be different.

Regards,

Florian
Re: How to share a singleton between "Services.java" and other plugins ? [message #1791080 is a reply to message #1790927] Fri, 22 June 2018 13:46 Go to previous message
Stéphane Tzvetkov is currently offline Stéphane TzvetkovFriend
Messages: 2
Registered: June 2018
Junior Member
Hi Florian,

Thank you very much for your answer.
I ran some tests, and I think you solved my problem !

My singleton was actually in the same plugin as my odesign and services classes, so I moved it to another plugin : now it works perfectly, the singleton is in the same classloader (the OSGi one) at runtime across every plugins, even when I call it from services classes.

Thanks again, you really helped me a lot.

Regards,

Stéphane
Previous Topic:Read an Excel Sheet with the Services java Extention
Next Topic:Sirius 5.1.2 Update Site
Goto Forum:
  


Current Time: Sat Sep 22 16:43:04 GMT 2018

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

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

Back to the top