Access to instances in the RCP Client from a Oxygen Extension

Oxygen general issues.
SSC
Posts: 206
Joined: Thu Dec 01, 2011 4:22 pm
Location: Hamburg, Germany

Access to instances in the RCP Client from a Oxygen Extension

Post by SSC »

Hello,

we are using the ro.sync.exml.editor.xmleditor.pageauthor.AuthorDnDListener and the ro.sync.ecss.extensions.api.StylesFilter Extensions.

In the our Eclipse RCP client we have our own data-model, which can be accessed via a static singleton method. Like it is also done with the org.eclipse.core.runtime.Platform and org.eclipse.ui.PlatformUI.

Unfortunately I cannot get access to the currently used instance of the PlatformUI and our DataModel.
When I define the dependencys to it in the classpath of the Extension, I can use those classes, but they are not correctly initialized.
The reason for that is maybe the use of a different classloader for your extensions and/or the fact that PlatformUI and our Datamodel are static and initialized in a static way at startup of the RCP client.

Do you have any idea how I could gain access to the same singleton object instance, which is used in the RCP Client, in an Oxygen extension?

Best regards,

Simon
Simon Scholz
vogella GmbH
http://www.vogella.com
Radu
Posts: 9051
Joined: Fri Jul 09, 2004 5:18 pm

Re: Access to instances in the RCP Client from a Oxygen Extension

Post by Radu »

Hi Simon,
When I define the dependencys to it in the classpath of the Extension, I can use those classes, but they are not correctly initialized.
To what Extension are you referring? When editing a document type in Oxygen there is a Classpath tab. Are you referring to it? If so, you must not add the JAR libraries there. Each extension is run in its own class loader (which has as a parent our plugin's class loader). That extension class loader will prefer to instantiate classes from the added JARs to basically it will re-instantiate the singleton instance but on a different class loader.

In my opinion, you should probably add in our plugin.xml in the <requires> section a dependency to your plugin, in this way maybe they will share the same class loader.

Or you should try to use Java reflection to call the static methods and see if it works.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
SSC
Posts: 206
Joined: Thu Dec 01, 2011 4:22 pm
Location: Hamburg, Germany

Re: Access to instances in the RCP Client from a Oxygen Extension

Post by SSC »

Hello Radu,

[quote=Radu]To what Extension are you referring? When editing a document type in Oxygen there is a Classpath tab. Are you referring to it?[/quote]

No. I added the necessary classes to the MANIFEST.MF of the Extension JAR.
Actually this works, but not for those static classes, which are not initialized.

Tomorrow we´ll try your proposal to add the necessary dependencies to your plugin.

Hopefully this will work :)

Best regards,

Simon
Simon Scholz
vogella GmbH
http://www.vogella.com
SSC
Posts: 206
Joined: Thu Dec 01, 2011 4:22 pm
Location: Hamburg, Germany

Re: Access to instances in the RCP Client from a Oxygen Extension

Post by SSC »

Hello Radu,

it seems that your Oxygen plugin and our eclipse plugins use different class loaders.
A colleague of mine just found out that you have your own classloader called ro.sync.util.tb, which comes from the org.eclipse.core.runtime.internal.adaptor.ContextFinder@d76237.

But we use the org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@80937b for our classes.

Do you have any idea, if you can combine those different types of classloader or if they have any connection to each other.
So that it becomes possible to gain access to our class instances at runtime in oxygen extension classes like the ro.sync.ecss.extensions.api.StylesFilter or com.oxygenxml.editor.editors.author.AuthorDnDListener?

Best regards,

Simon
Simon Scholz
vogella GmbH
http://www.vogella.com
Radu
Posts: 9051
Joined: Fri Jul 09, 2004 5:18 pm

Re: Access to instances in the RCP Client from a Oxygen Extension

Post by Radu »

Hi Simon,

As you've seen, each defined document type (DITA, Docbook, etc) has a set of JAR libraries added to it.
Document types must not conflict with each other so thus each Author extension implementation needs to be loaded by a separate class loader. The original name of that obfuscated class is ro.sync.util.LateDelegationClassLoader which is the class loader in which the Author extension was instantiated (styles filter implementation or DND handler implementation or extensions bundle implementation).

The LateDelegationClassLoader has as a parent class loader the Eclipse's org.eclipse.core.runtime.internal.adaptor.ContextFinder so if it cannot find a certain class (because it might not be present in the Document Type's JARs)

From what I've studied a while ago what the Eclipse ContextFinder does is to look at the method calls stack and see if it can find in that stack of calls a class loader which can load the class.
But we use the org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@80937b for our classes.
Do you do something special class-loader related in your plugin?

I made some tests trying to reproduce the situation on my side and here are my findings:

1) I created a simple plugin using the Eclipse Plugin Wizard.
In my plugin I had a singleton Java class like:

Code: Select all

package testplugin;

public class TestSingleton {
private static TestSingleton instance;
public static TestSingleton getInstance() {
if (instance == null) {
instance = new TestSingleton();
System.err.println("CREATED INSTANCE " + instance);
}
System.err.println("Returned INSTANCE " + instance);
return instance;
}
}
When the simple plugin gets started, I call the singleton class like:

Code: Select all

	/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
System.err.println("START SECOND PLUGIN ACTIVATOR");
super.start(context);
plugin = this;
TestSingleton.getInstance();
}
2) In the main plugin (Oxygen) "plugin.xml" I added a dependency to the test plugin like:

Code: Select all

<import plugin="testPlugin"/>
3) I created a custom DITA styles filter which also calls the singleton object from the second plugin:

Code: Select all

  /**
* @see ro.sync.ecss.extensions.api.ExtensionsBundle#createAuthorStylesFilter()
*/
@Override
public StylesFilter createAuthorStylesFilter() {
return new StylesFilter() {
@Override
public String getDescription() {
return "Description";
}

@Override
public Styles filter(Styles styles, AuthorNode authorNode) {
try {
TestSingleton.getInstance();
} catch(Throwable ex) {
ex.printStackTrace();
}
return null;
}
};
}
4) When running the runtime workbench the styles filter could not find the singleton class, a class not found exception was thrown.

5) Then in the simple test plugin in the MANIFEST.MF I added an export property:

Code: Select all

Export-Package: testplugin
After adding this property, the styles filter in the Oxygen plugin could use the singleton class, and it used the same instance of the object as created on the "start" method of the test plugin.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
tjarvas
Posts: 4
Joined: Wed Feb 11, 2015 3:52 pm

Re: Access to instances in the RCP Client from a Oxygen Exte

Post by tjarvas »

Hello Radu,

I have exactly the same issue. I am trying to integrate the oXygen Author into a CMS system, which is based on eclipse. So I put together a customized target platform, which is an eclipse with a lot of extra plugins for the CMS system. Additionally I added the oxygen author 16.1.0.v2015012213. I am using this as the target platform in my eclipse IDE. I am developing an eclipse plugin, which would do the integration between the CMS functionality and the oxygen.

Here is my use-case: We are working with xml documents, which can have different type of links. The links are handled by the CMS system, in the XML content there are no href attributes for the links, just an ID which represents the link ID in the CMS. My task is to add some extra style for those <link> elements (<link> is just an example, a link can be started from any pre-defined element) which has a start link anchor. So having a <link> element not necessarily means that it is a real link - this is why I can't solve this task from CSS. I will also have to handle the click event on these nodes, but that is another story.

For both tasks it seems there would be a solution by using the StylesFilter and ElementLocatorProvider extensions of Oxygen.

Here is what I do:
1. When opening an XML in the oxygen, I am collecting the links by the CMS api. I am also able to get the list of related AuthorNode objects, which should be handled as clickable links.
2. I created an implementation for the StylesFilter, where I would like to check if the filtered AuthorNode is in the list of link nodes. For this I would like to access this list from the StylesFilter. I am trying to access it through a singleton class by a static getInstance() call. But this gives me a different instance what I have anywhere else in the plugin. So it seems I have the same issue.

I was trying your solution, but didn't helped me. Perhaps I am doing something wrong (I am new in Oxygen). This is what I was trying:

1. I set the Export-Package: myplugin.extensions in the MANIFEST.MF of my plugin. Of course myplugin.extensions package is the package, where my StylesFilter implementation is located.

2. I have exported this plugin as a jar file and copied it to the plugins directory of my target platform eclipse (where the oxygen author plugin is also located).

3. I have edited the plugin.xml of the oxygen author plugin and added the

<requires>
<import plugin="myplugin"/>
</requires>

4. I have my own framework extension, where I had to add an extra classpath: ${frameworks}\..\..\myplugin_1.0.0.jar This points to the jar file I copied in step 2.

5. After adding this extra classpath, on the Extensions tab I pressed the Choose button near the CSS styles filter extension and my custom implementation appeared. I selected it.

6. Now when I open an XML file, my customization is invoked, because I was adding some background color change, but it initializes a different instance from my singleton.

Am I doing something wrong? For me this whole way of configuring the custom extension looks like a little bit strange. I would expect to add my customized StylesFilter by an eclipse plugin extension point, like the com.oxygenxml.author.editorAdapterContributor which works nice.

Thanks in advance!

Tamas
Radu
Posts: 9051
Joined: Fri Jul 09, 2004 5:18 pm

Re: Access to instances in the RCP Client from a Oxygen Exte

Post by Radu »

Hi Tamas,

Actually what you want is not totally identical to what I said in the thread that could work.
The procedure I described in the thread was that a singleton class called in my example TestSingleton could exist in your plugin's project. Then the StylesFilter implementation could access this external singleton and get or set information to it. And this singleton could be accessed from some other part of the code and get/set information to it and it would be the same singleton.
So instead of adding a static "getInstance()" on the StylesFilter extension class you can use this additional singleton class to store certain values in it. Then from some other part of the code read data from this extra singleton class.

Because the problem with your approach is that when the "StylesFilter" constructor is called by our code, the StylesFilter object is created in a special framework class loader. But when you call "StylesFilterImpl.getInstance()" from your plugin's class loader, it will give you a new object created on your distinct class loader.

About this remark:
Am I doing something wrong? For me this whole way of configuring the custom extension looks like a little bit strange. I would expect to add my customized StylesFilter by an eclipse plugin extension point, like the com.oxygenxml.author.editorAdapterContributor which works nice.
That's a nice idea and I don't see an impediment in implementing it. I will add this as a feature request.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
tjarvas
Posts: 4
Joined: Wed Feb 11, 2015 3:52 pm

Re: Access to instances in the RCP Client from a Oxygen Exte

Post by tjarvas »

Hi Radu,

Thanks for the fast answer. Actually I was trying to access a static instance of a class in my plugin. So I have an OxygenEditorIntegration class in my plugin with a getInstance(). If I have the instance, then I can access all of my logic. I can access the list of AuthorNodes which I collected for links. I was also adding all of my packages to the list of Export-Package in the manifest. So it should be visible for the classloader of the oxygen, which loads the StylesFilterImpl, which is also located in my plugin (and its package is also added to the Export-Package list.

Anyway, it would be much better for us, if we would be able to use the StylesFilter through a plugin extension point, so we will wait for that feature I think. Is it possible to implement an extension point for the other oxygen extensions as well (especially the ElementLocatorProvider, but the others are also seems to be useful). When can we expect the release of this feature? A nightly is also good for us.

Thanks and regards,
Tamas
Radu
Posts: 9051
Joined: Fri Jul 09, 2004 5:18 pm

Re: Access to instances in the RCP Client from a Oxygen Exte

Post by Radu »

Hi Tamas,

Maybe be could offer also via an extension point the possibility to create an ro.sync.ecss.extensions.api.ExtensionsBundle which has a lot of other extensions which can be created inside it, including ExtensionsBundle.createAuthorStylesFilter() and ExtensionsBundle.createElementLocatorProvider().
I'll try to find some time to look into this, can I use the email address you used to registered on the forum to contact you if I have a beta kit which could be tested?

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
tjarvas
Posts: 4
Joined: Wed Feb 11, 2015 3:52 pm

Re: Access to instances in the RCP Client from a Oxygen Exte

Post by tjarvas »

Hi Radu,

Yes, that would be great. You can contact me on that email. I was already contacted Alex via email previously for another feature.

Thanks!

Tamas
Radu
Posts: 9051
Joined: Fri Jul 09, 2004 5:18 pm

Re: Access to instances in the RCP Client from a Oxygen Exte

Post by Radu »

Hi,

Just to update this thread, the Oxygen 17 Eclipse plugin.xml has two new extension points: stylesFilterContributor and extensionsBundleContributor.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
Post Reply