eclipse.platform.swt icon indicating copy to clipboard operation
eclipse.platform.swt copied to clipboard

No more handle exceptions with the Edge browser

Open vogella opened this issue 1 year ago • 17 comments

Using the Edge browser on Windows still results in a the no more handlers exception even after the commit https://github.com/eclipse-platform/eclipse.platform.swt/commit/ed8f82127b6e5f7b6d2526c0e027cde80b4e5eab from @HeikoKlare

Before the commit, the error was in Edge.java:343, now it occurs in Edge.java:362.

https://github.com/eclipse-platform/eclipse.platform.swt/blob/master/bundles/org.eclipse.swt/Eclipse%20SWT%20Browser/win32/org/eclipse/swt/browser/Edge.java#L362C1-L363C1

It seems to happen if the user starts multiple time the same application in different workspaces. I will try to provide a test case to reproduce.

vogella avatar Jan 29 '24 16:01 vogella

See https://github.com/eclipse-platform/eclipse.platform.swt/issues/339

vogella avatar Jan 29 '24 16:01 vogella

I am sorry that Edge instantiation does still not work properly. We did not have issues in productive usage recently, but we do not use it intensively either (usually only one instance). Some remarks on this:

  • Even though a `no more handles" error is shown, that is probably not the reason. This error is thrown if anything unexpected happens during WebView2 instantiation.
  • I once tried to parameterize the browser tests to also be executed for Edge (#672). But I have not been successful yet because of some interference between the test cases and their used Edge instances: it looked as if some OS events were not processed properly (see https://github.com/eclipse-platform/eclipse.platform.swt/pull/672/files#r1202546545).

I could image that the problem you describe, @vogella, is related to the one that can be seen in the tests. What I tried to do in my previous fix attempt was to ensure that asynchronous OS events for browser instantiation are processed properly. Taking a fresh look at the code, I would first have a look at the involved Edge#callAndWait() implementations again: https://github.com/eclipse-platform/eclipse.platform.swt/blob/2cdfd9705676cfcc15dc6c2cfb80057fdcbdf3fc/bundles/org.eclipse.swt/Eclipse%20SWT%20Browser/win32/org/eclipse/swt/browser/Edge.java#L212-L247 From my understanding, the OS event processing is supposed to trigger the callback setting the results (ppv/phr). However, the callAndWait performs a release on the callback even before doing the event processing, so maybe the problem is something pretty simple like an interface pointer being released too early. https://github.com/eclipse-platform/eclipse.platform.swt/blob/2cdfd9705676cfcc15dc6c2cfb80057fdcbdf3fc/bundles/org.eclipse.swt/Eclipse%20SWT%20Browser/win32/org/eclipse/swt/browser/Edge.java#L224-L227

HeikoKlare avatar Jan 30 '24 06:01 HeikoKlare

@vogella can you share which kind of error code is printed? I.e., there should be a message like org.eclipse.swt.SWTError: No more handles [0x802a000c] and the error code at the end of the message would be of particular interest. For error code 0x802a000c (wrong thred access), I have provided #1015 to better distinguish that kind of error.

HeikoKlare avatar Jan 30 '24 12:01 HeikoKlare

We see two errors: No more handles [0x8007139f] No more handles [0x800700aa]

[0x8007139f] happens more frequently.

vogella avatar Jan 31 '24 08:01 vogella

Thanks for sharing!

Some documentation I found (including the Microsoft documentation) states the following:

  • 0x800700AA (ERROR_BUSY): May be used to indicate that the device is busy processing another operation. Applications should wait for that operation to complete before retrying.
  • 0x8007139F: The group or resource is not in the correct state to perform the requested operation (also documented in a WebView2 issue)

The question is what kind of concurrent operation or incorrect state that is. One thing I could imagine is the access to a shared data directory: all Edge instances within (Eclipse) applications that have the same application name share the same data directory with the following path: https://github.com/eclipse-platform/eclipse.platform.swt/blob/44432b27cdac2dc37542bf1d21c2fe25f8fb0a71/bundles/org.eclipse.swt/Eclipse%20SWT/win32/org/eclipse/swt/widgets/Display.java#L2851 This will be something like C:\Users\...\AppData\Local\Eclipse.

@vogella is it possible for you to set the system property org.eclipse.swt.browser.EdgeDataDir to something different for each application and test if the issue still occurs? This will result in a different data folder for each application and would allow to verify whether the shared data directory is related to the issue.

HeikoKlare avatar Jan 31 '24 08:01 HeikoKlare

@HeikoKlare thanks for the information, we will try the org.eclipse.swt.browser.EdgeDataDir setting and I will report back if that solves the issue.

vogella avatar Jan 31 '24 08:01 vogella

JVM shutdown hook, via

Runtime.getRuntime().addShutdownHook(new Thread(() -> deleteDirectoryRecursively(edgeDataDir)));

private static void deleteDirectoryRecursively(Path path) {

		try {
			Files.walk(path).sorted((a, b) -> b.compareTo(a)) // Sort in reverse order to delete files before
																// directories
					.forEach(p -> {
						try {
							Files.delete(p);
						} catch (IOException e) {
							e.printStackTrace();
						}
					});
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

works fine now (not sure what was wrong before).

And we currently do not see the no more handlers exception. Thanks @HeikoKlare

vogella avatar Jan 31 '24 11:01 vogella

Good to hear that setting the data directory may solve/circumenvent the problem. Still this is quite interesting as meanwhile I took a look into Microsoft's documentation which states that in case you configure multiple WebView2Environments equally, they should be able to share a data directory: https://learn.microsoft.com/en-us/microsoft-edge/webview2/concepts/process-model?tabs=csharp#multiple-environment-objects So maybe there is some further difference in WebView2Options used by different SWT Edge instances (even though it looks as if their default values should be equal).

Anyway, I would expect that different RCP applications do not share browser data by default. I would rather expect an RCP application to place the browser data directory within its workspace folder. So maybe in case the user does not set a custom data directory, an RCP application should explicitly do so?

a dispose listener on Display cannot delete as the files are still locked

Might be that this is a race condition, since the WebView2Environment handle is also released via a display dispose listener: https://github.com/eclipse-platform/eclipse.platform.swt/blob/44432b27cdac2dc37542bf1d21c2fe25f8fb0a71/bundles/org.eclipse.swt/Eclipse%20SWT%20Browser/win32/org/eclipse/swt/browser/Edge.java#L349-L352

HeikoKlare avatar Jan 31 '24 11:01 HeikoKlare

Thanks @HeikoKlare for your work.

We tested your changes via the i-build from yesterday and it seems to solve our errors event without the edge data setting in most cases.

We tested: Starting multiple production RCP applications in parallel with and without the edge data directory set.

It still gives the error: No more handles [0x8007139f] if we do NOT set the edge data directory and start the application via the IDE and have another production version already running (which we build via Tycho). So a runtime version seems still to collide with a build version.

vogella avatar Feb 01 '24 12:02 vogella

Thanks for the follow-up information! It is interesting that multiple production applications seem to work fine while a production version infers with a version started from within Eclipse. And I have to admit that I have no clue why that happens. Maybe it is related to the used application names, as they are used to determine the default data directory. Anyway, there is pretty much to consider with respect to (sharing) user data directories: https://learn.microsoft.com/en-us/microsoft-edge/webview2/concepts/user-data-folder?tabs=win32

To me, it still seems to make sense to have the data folder either placed in the installation folder or even within the workspace (metadata) folder:

Anyway, I would expect that different RCP applications do not share browser data by default. I would rather expect an RCP application to place the browser data directory within its workspace folder. So maybe in case the user does not set a custom data directory, an RCP application should explicitly do so?

Then applications / workspaces are isolated properly. But it also feels a little strange to integrate such specific behavior into the general framework and maybe that should be something each application decides on its own. Then we could only think about adding it to the IDEApplication.

HeikoKlare avatar Feb 01 '24 13:02 HeikoKlare

@HeikoKlare using the installfolder is maybe not a good idea as one can still start multiple eclipse from the same install but different workspaces. Also the install location might be read-only.

laeubi avatar Feb 01 '24 13:02 laeubi

using the installfolder is maybe not a good idea as one can still start multiple eclipse from the same install but different workspaces. Also the install location might be read-only.

That's true. I also think that the workspace directory makes much more sense (semantically). Technically, it should be possible that multiple Eclipse instances started from the same installation use the same, shared data folder (according to the WebView2 documentation). But even if that worked properly, you are right that the install folder might be read-only and then you need some fallback anyway.

HeikoKlare avatar Feb 01 '24 14:02 HeikoKlare

just to share ours stuff that we get when enabling the Edge browser:

org.eclipse.swt.SWTError: No more handles [0x80070578]
	at org.eclipse.swt.SWT.error(SWT.java:4944)
	at org.eclipse.swt.browser.Edge.error(Edge.java:190)
	at org.eclipse.swt.browser.Edge.create(Edge.java:362)
	at org.eclipse.swt.browser.Browser.<init>(Browser.java:99)
	at com.servoy.eclipse.ui.views.solutionexplorer.HTMLToolTipSupport.createBrowserTooltipContentArea(HTMLToolTipSupport.java:80)
	at com.servoy.eclipse.ui.views.solutionexplorer.HTMLToolTipSupport.createViewerToolTipContentArea(HTMLToolTipSupport.java:65)
	at org.eclipse.jface.viewers.ColumnViewerToolTipSupport.createToolTipContentArea(ColumnViewerToolTipSupport.java:109)
	at org.eclipse.jface.window.ToolTip.toolTipShow(ToolTip.java:345)
	at org.eclipse.jface.window.ToolTip.toolTipOpen(ToolTip.java:469)
	at org.eclipse.jface.window.ToolTip.toolTipCreate(ToolTip.java:334)
	at org.eclipse.jface.window.ToolTip$ToolTipOwnerControlListener.handleEvent(ToolTip.java:609)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4273)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1066)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4071)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3659)

that is what we get all the time when we use a tooltip that uses the browser i first thought, maybe i forget to dispose something? But then i noticed that it is already in the first call to that method that goes wrong.

Then i tried to debug it a bit, and that got me to a very surprising behavior

image

that is the Edge class if i place a break point at 361, when it hits an i press resume.. bang "no more handles" if i step over (or step in and step out) so i really try to go to line 362.. it works... 100% of the time..

jcompagner avatar Feb 08 '24 10:02 jcompagner

Error code 0x80070578 means: "Invalid window handle"

Can you please post the environment (OS version, WebView2 version) on which the problem occurs? Doing a web search for that error code in combination with WebView2 gives several results over the last years, e.g., https://github.com/MicrosoftEdge/WebView2Feedback/issues/3097

HeikoKlare avatar Feb 08 '24 12:02 HeikoKlare

this is on all our windows environments (Windows 11). on our project build on Eclipse 2023.12 (4.30)

WebView2 version? i have no idea. that is default i think installed in windows 11, how can i quickly test that?

jcompagner avatar Feb 08 '24 12:02 jcompagner

The WebView2 runtime is installed as an ordinary Windows applications, so within the programs overview, you should find the runtime: image

I had a quick look into the class instantiating the browser, but unfortunately the posted strack trace does seem to fit with the source code.

HeikoKlare avatar Feb 08 '24 12:02 HeikoKlare

i have the same version

it is this line:

https://github.com/Servoy/servoy-eclipse/blob/master/com.servoy.eclipse.ui/src/com/servoy/eclipse/ui/views/solutionexplorer/HTMLToolTipSupport.java#L76

in that class so just new Browser()

my code was a bit different because of some debug stuff and dispose try outs.

jcompagner avatar Feb 08 '24 12:02 jcompagner

Re-opening this as we still need https://github.com/eclipse-platform/eclipse.platform.ui/pull/2434 to be merged for this to make a difference.

sratz avatar Oct 29 '24 09:10 sratz

Thanks for reopening! Sometimes, I am confused why issues become auto-closed, since there was no "fixes", "closes" or the like keyword in the PR/commit due to which this issue has been closed.

HeikoKlare avatar Oct 29 '24 10:10 HeikoKlare

It was marked as resolving this issue grafik

laeubi avatar Oct 29 '24 11:10 laeubi

It was marked as resolving this issue

Thanks! I missed that one.

HeikoKlare avatar Oct 29 '24 12:10 HeikoKlare

We can close this issue now. It has been fixed by https://github.com/eclipse-platform/eclipse.platform.swt/pull/1548.

amartya4256 avatar Nov 04 '24 15:11 amartya4256

All causes of "no more handles" in Edge that we know of have been fixed. Thus we close this issue for now.

In case anyone experiences further unexpected "no more handles" errors, please reopen this issue or create a new one.

HeikoKlare avatar Nov 04 '24 16:11 HeikoKlare