|
|
|
|
|
|
Re: Launch e4 RCP application by code? [message #1745861 is a reply to message #1745843] |
Tue, 18 October 2016 13:26 |
Eclipse User |
|
|
|
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:31But 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.
|
|
|
Re: Launch e4 RCP application by code? [message #1745909 is a reply to message #1745861] |
Wed, 19 October 2016 08:55 |
Roman Zimmer 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 |
Eclipse User |
|
|
|
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.
|
|
|
Powered by
FUDForum. Page generated in 0.03639 seconds