Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse 4 » Launch e4 RCP application by code?
icon5.gif  Launch e4 RCP application by code? [message #1745629] Thu, 13 October 2016 15:26 Go to next message
Roman Zimmer is currently offline Roman ZimmerFriend
Messages: 27
Registered: November 2010
Junior Member
Hey @ll,

our project consists of a non-ui-plugin (acting as a local server) and a e4 RCP application with .product-file (i.e. desktop application). The server pulls in the RCP application as dependency, because our use case is to launch the application, whenever the server receives a certain command to do so.

I tried starting the corresponding bundle from the server code hoping the UI would pop-up, but without success:

Platform.getBundle("org.example.application").start();


So, is it somehow possible to launch a e4 RCP application by Java code? And if so, how do I pass arguments to the application?

Any help is really appreciated! Thanks in advance!
Re: Launch e4 RCP application by code? [message #1745651 is a reply to message #1745629] Fri, 14 October 2016 00:38 Go to previous messageGo to next message
Brian de Alwis is currently offline Brian de AlwisFriend
Messages: 680
Registered: January 2012
Senior Member

The entry point into E4 programs is the E4Application class, which is an Equinox IApplication class. I've never heard of anybody trying to do what you're doing, so it may be rough.

You should be able to use the OSGi/Equinox Application service to launch the E4Application. See the following for some examples about how you go about doing this:

https://wiki.eclipse.org/Equinox_Application_Model_Demo


Eclipse Platform committer. Ask me about Eclipse support, training, and consulting.
Re: Launch e4 RCP application by code? [message #1745694 is a reply to message #1745651] Fri, 14 October 2016 15:37 Go to previous messageGo to next message
Roman Zimmer is currently offline Roman ZimmerFriend
Messages: 27
Registered: November 2010
Junior Member
Thanks for the pointer!

As I understand the examples you try to get a ApplicationDescriptor and just launch it.

I tried to get the corresponding ApplicationDescriptor for the RCP application and to launch it, but got an org.osgi.service.application.ApplicationException: A singleton application instance is already running: org.example.server.0 .

In the meantime I found something about EclipseStarter and tried starting the application using EclipseStarter.run() as this seems just what I need. No luck yet either, but I keep going...
Re: Launch e4 RCP application by code? [message #1745803 is a reply to message #1745694] Mon, 17 October 2016 15:35 Go to previous messageGo to next message
Roman Zimmer is currently offline Roman ZimmerFriend
Messages: 27
Registered: November 2010
Junior Member
Using EclipseStarter I get an java.lang.IllegalStateException: Platform already running. So no luck on this road neither.

Might it be that the desktop application is already running, but not showing any visible window yet? If so, is there a way to render/show the corresponding window?
Re: Launch e4 RCP application by code? [message #1745810 is a reply to message #1745803] Mon, 17 October 2016 18:08 Go to previous messageGo to next message
Brian de Alwis is currently offline Brian de AlwisFriend
Messages: 680
Registered: January 2012
Senior Member

Your application is likely marked as a singleton instance: check its `cardinality` attribute. For details, see the org.eclipse.core.runtime.applications extension point.



Eclipse Platform committer. Ask me about Eclipse support, training, and consulting.
Re: Launch e4 RCP application by code? [message #1745843 is a reply to message #1745810] Tue, 18 October 2016 10:31 Go to previous messageGo to next message
Roman Zimmer is currently offline Roman ZimmerFriend
Messages: 27
Registered: November 2010
Junior Member
Using the org.eclipse.core.runtime.applications extension point indeed brought me one step further by changing the cardinality. But now I hit another wall as I'm requested to give an application class for startup - and org.eclipse.e4.ui.workbench.swt.E4Application as a internal class cannot be found....
Re: Launch e4 RCP application by code? [message #1745861 is a reply to message #1745843] Tue, 18 October 2016 13:26 Go to previous messageGo to next message
Brian de Alwis is currently offline Brian de AlwisFriend
Messages: 680
Registered: January 2012
Senior Member

Oh, I see: our org.eclipse.e4.ui.worksbench.swt.E4Application application is marked as singleton-global. That's awkward and not very helpful. It should at the very worst be singleton-scoped. Ugh.

So it sounds like you're defining your own application, which is fine.

Roman Zimmer wrote on Tue, 18 October 2016 06:31
But now I hit another wall as I'm requested to give an application class for startup - and org.eclipse.e4.ui.workbench.swt.E4Application as a internal class cannot be found....


The class is org.eclipse.e4.ui.internal.workbench.swt.E4Application.


Eclipse Platform committer. Ask me about Eclipse support, training, and consulting.
Re: Launch e4 RCP application by code? [message #1745909 is a reply to message #1745861] Wed, 19 October 2016 08:55 Go to previous messageGo to next message
Roman Zimmer is currently offline Roman ZimmerFriend
Messages: 27
Registered: November 2010
Junior Member
Thanks for your input! This got me one step further... I now have understood more details about my case that weren't obvious to me before. Sorry for the confusion!
I try to summarize them here and maybe you have one more hint for me:

My local server application is a plugin that starts a simple legacy (i.e. e3) workbench. It's started via it's own .product-file, which also includes the actual RCP application via the Contents tab.
The server plugin is defined for being an application:

   <extension
         id="application"
         point="org.eclipse.core.runtime.applications">
      <application
            cardinality="*">
         <run
               class="org.example.server.Application">
         </run>
      </application>
   </extension>


The RCP application is a true e4 application that also has a .product-file for individual start (which works absolutely fine).
Following your hint, I made the it an application as well:

<extension
      id="org.example.application"
      point="org.eclipse.core.runtime.applications">
   <application
         cardinality="*"
         thread="any"
         visible="true">
      <run
            class="org.eclipse.e4.ui.internal.workbench.swt.E4Application">
      </run>
   </application>
</extension>
 <extension id="product" point="org.eclipse.core.runtime.products">
      <product application="org.eclipse.e4.ui.workbench.swt.E4Application" name="org.example.application">
         <property name="lifeCycleURI" value="bundleclass://org.example.application/org.example.application.LifeCycle">
         </property>
         <property name="appName" value="org.example.application">
         </property>
         <property
               name="applicationXMI"
               value="org.example.application/Application.e4xmi">
         </property>
      </product>
   </extension>


To start the RCP application from the server, I currently use the following code:

ServiceReference<?> serviceReference = Activator.getContext().getAllServiceReferences("org.osgi.service.application.ApplicationDescriptor", "(service.pid=org.example.application)")[0];
ApplicationDescriptor app = (ApplicationDescriptor) Activator.getContext().getService(serviceReference);
app.launch(null);


This successfully finds a ApplicationDescriptor (actual a EclipseAppDescriptor) and launches it via E4Application.start() passing in the EclipseAppHandle as IApplicationContext .
So far, so good! But I got the following stacktrace:

org.eclipse.swt.SWTException: Invalid thread access
	at org.eclipse.swt.SWT.error(SWT.java:4533)
	at org.eclipse.swt.SWT.error(SWT.java:4448)
	at org.eclipse.swt.SWT.error(SWT.java:4419)
	at org.eclipse.swt.widgets.Display.error(Display.java:1262)
	at org.eclipse.swt.widgets.Display.checkDevice(Display.java:766)
	at org.eclipse.swt.graphics.Device.dispose(Device.java:297)
	at org.eclipse.e4.ui.internal.workbench.swt.E4Application.start(E4Application.java:173)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.equinox.internal.app.AnyThreadAppLauncher.run(AnyThreadAppLauncher.java:26)
	at java.lang.Thread.run(Thread.java:745)


Debugging the code, this is caused by a exception thrown at E4Application.java:310:

boolean highContrastMode = getApplicationDisplay().getHighContrast();


getHighContrast() calls checkDevice() and determines being on the wrong thread. Although I already tried with running all this in a new thread or via Display.asyncExec() and Display.syncExec(), I couldn't avoid the exception. But that seems solvable.
Debugging further my real problem now is the following:

The ApplicationContext used to determine arguments for the e4 application like IWorkbench.XMI_URI_ARG and IWorkbench.LIFE_CYCLE_URI_ARG does not contain valid values from the RCP application's plugin.xml and thus does not load the correct files but fallback values like org.eclipse.ui.workbench/LegacyIDE.e4xmi for XMI_URI_ARG.
This does surprise me as a correctly get a - in my eyes valid - ApplicationDescriptor to my RCP application plugin.

Do you see anything I might do wrong? Is this approach intended to work? If so, what might be missing?

EDIT: I was able to pass in the requested arguments building an Map like so:

String[] args = {
		"-" + IWorkbench.LIFE_CYCLE_URI_ARG, "bundleclass://org.example.application/org.example.LifeCycle", 
		"-appName", "org.example.application",
		"-" + IWorkbench.XMI_URI_ARG, "org.example.application/Application.e4xmi" };

...

Map<String, String[]> arguments = new HashMap<String, String[]>();
arguments.put(IApplicationContext.APPLICATION_ARGS, args);
app.launch(arguments);


Unfortunately, still there is the SWT thread error. Changing the RCP application thread to main gives a org.osgi.service.application.ApplicationException: An application instance is already running on the main thread: org.example.server.application.0....



PS: If I've missed some important information for you to give further advice, please let me know.

[Updated on: Wed, 19 October 2016 10:11]

Report message to a moderator

Re: Launch e4 RCP application by code? [message #1746016 is a reply to message #1745909] Thu, 20 October 2016 13:32 Go to previous message
Brian de Alwis is currently offline Brian de AlwisFriend
Messages: 680
Registered: January 2012
Senior Member

You need to ensure you start the workbench from the SWT thread. On your first thread, you'll need to create and hold onto the display instance. Then use Display#asyncExec() (or syncExec(), I suppose) to run a runnable that launches your app. I think that will work.

Another approach would be to set IWorkbenchConfigurer#setExitOnLastWindowClose(false). Then you'd launch a normal workbench application, and you'd just hang around. But this doesn't work at the moment, and nobody has stepped up to work on it; it's tracked in bug 74073.

Brian.


Eclipse Platform committer. Ask me about Eclipse support, training, and consulting.
Previous Topic:Update NEON to NEON.1 and get error
Next Topic:How to disable MenuItems from Fragment
Goto Forum:
  


Current Time: Wed Nov 22 09:37:20 GMT 2017

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

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