eclipse-archived / smarthome

Eclipse SmartHome™ project
https://www.eclipse.org/smarthome/
Eclipse Public License 2.0
861 stars 787 forks source link

[LSP] Connection to LSP fails with internal error if smb network path is used #6611

Open MHerbst opened 5 years ago

MHerbst commented 5 years ago

My environment:

If I open an openHAB config file from a SMB share by using a SMB network path (e.g. \\raspi\openhab\conf) VSCode issues an "Internal error".

The message returned from the LSP contains this error message and call stack:

"java.util.concurrent.CompletionException: java.lang.IllegalArgumentException: URI has an authority component
    at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:292)
    at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:308)
    at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:593)
    at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:577)
    at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:474)
    at java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:1977)
    at org.eclipse.xtext.ide.server.concurrent.WriteRequest.run(WriteRequest.java:44)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalArgumentException: URI has an authority component
    at sun.nio.fs.UnixUriUtils.fromUri(UnixUriUtils.java:53)
    at sun.nio.fs.UnixFileSystemProvider.getPath(UnixFileSystemProvider.java:98)
    at java.nio.file.Paths.get(Paths.java:138)
    at org.eclipse.smarthome.model.lsp.internal.MappingUriExtensions.toPathAsInXtext212(MappingUriExtensions.java:209)
    at org.eclipse.smarthome.model.lsp.internal.MappingUriExtensions.mapToClientPath(MappingUriExtensions.java:119)
    at org.eclipse.smarthome.model.lsp.internal.MappingUriExtensions.toUriString(MappingUriExtensions.java:110)
    at org.eclipse.xtext.ide.server.LanguageServerImpl.lambda$publishDiagnostics$26(LanguageServerImpl.java:447)
    at org.eclipse.xtext.xbase.lib.ObjectExtensions.operator_doubleArrow(ObjectExtensions.java:139)
    at org.eclipse.xtext.ide.server.LanguageServerImpl.publishDiagnostics(LanguageServerImpl.java:457)
    at org.eclipse.xtext.ide.server.LanguageServerImpl.lambda$null$9(LanguageServerImpl.java:293)
    at org.eclipse.xtext.ide.server.ProjectManager.lambda$null$3(ProjectManager.java:135)
    at org.eclipse.xtext.build.IncrementalBuilder$InternalStatefulIncrementalBuilder.validate(IncrementalBuilder.java:267)
    at org.eclipse.xtext.build.IncrementalBuilder$InternalStatefulIncrementalBuilder.lambda$launch$6(IncrementalBuilder.java:244)
    at org.eclipse.xtext.build.ClusteringStorageAwareResourceLoader.lambda$executeClustered$1(ClusteringStorageAwareResourceLoader.java:77)
    at org.eclipse.xtext.xbase.lib.internal.FunctionDelegate.apply(FunctionDelegate.java:42)
    at com.google.common.collect.Lists$TransformingRandomAccessList$1.transform(Lists.java:617)
    at com.google.common.collect.TransformedIterator.next(TransformedIterator.java:48)
    at java.util.AbstractCollection.toArray(AbstractCollection.java:141)
    at java.util.ArrayList.addAll(ArrayList.java:581)
    at com.google.common.collect.Iterables.addAll(Iterables.java:352)
    at org.eclipse.xtext.build.ClusteringStorageAwareResourceLoader.executeClustered(ClusteringStorageAwareResourceLoader.java:80)
    at org.eclipse.xtext.build.BuildContext.executeClustered(BuildContext.java:55)
    at org.eclipse.xtext.build.IncrementalBuilder$InternalStatefulIncrementalBuilder.launch(IncrementalBuilder.java:251)
    at org.eclipse.xtext.build.IncrementalBuilder.build(IncrementalBuilder.java:399)
    at org.eclipse.xtext.build.IncrementalBuilder.build(IncrementalBuilder.java:384)
    at org.eclipse.xtext.ide.server.ProjectManager.doBuild(ProjectManager.java:115)
    at org.eclipse.xtext.ide.server.ProjectManager.doInitialBuild(ProjectManager.java:107)
    at org.eclipse.xtext.ide.server.BuildManager.doInitialBuild(BuildManager.java:148)
    at org.eclipse.xtext.ide.server.WorkspaceManager.refreshWorkspaceConfig(WorkspaceManager.java:148)
    at org.eclipse.xtext.ide.server.WorkspaceManager.initialize(WorkspaceManager.java:117)
    at org.eclipse.xtext.ide.server.LanguageServerImpl.lambda$initialize$10(LanguageServerImpl.java:295)
    at org.eclipse.xtext.ide.server.concurrent.WriteRequest.run(WriteRequest.java:38)
    ... 5 more
"

The problem can be bypassed by assigning a drive letter to the path and open the config folder via the drive letter.

mhilbush commented 5 years ago

When using \\openhabhost\openhab-u\openhab2\conf

Identified client workspace as 'file://openhabhost/openhab-u/openhab2/conf'

Versus when using u:/openhab2/conf

Identified client workspace as 'file:///u:/openhab2/conf'

@sjka Do you have any ideas? I'm not sure if I introduced this with my fix.

Full TRACE log...

Using drive letter (works).

2018-12-05 09:52:40.917 [DEBUG] [thome.model.lsp.internal.ModelServer] - Going to wait for a client to connect
2018-12-05 09:52:40.917 [DEBUG] [thome.model.lsp.internal.ModelServer] - Client /192.168.99.66:58987 connected
2018-12-05 09:52:40.970 [DEBUG] [el.lsp.internal.MappingUriExtensions] - Identified client workspace as 'file:///u:/openhab2/conf'
2018-12-05 09:52:40.970 [TRACE] [el.lsp.internal.MappingUriExtensions] - Going to map path file:///opt/openhab2/conf
2018-12-05 09:52:40.971 [TRACE] [el.lsp.internal.MappingUriExtensions] - Mapped path file:///u:/openhab2/conf to file:///opt/openhab2/conf/
2018-12-05 09:52:41.057 [TRACE] [el.lsp.internal.MappingUriExtensions] - Mapping server path file:///opt/openhab2/conf/rules/test.rules to client path file:///u:/openhab2/conf/rules/test.rules
2018-12-05 09:52:41.206 [TRACE] [el.lsp.internal.MappingUriExtensions] - Going to map path file:///opt/openhab2/conf/rules/test.rules
2018-12-05 09:52:41.207 [TRACE] [el.lsp.internal.MappingUriExtensions] - Mapped path file:///u:/openhab2/conf/rules/test.rules to file:///opt/openhab2/conf/rules/test.rules
2018-12-05 09:52:41.228 [TRACE] [el.lsp.internal.MappingUriExtensions] - Mapping server path file:///opt/openhab2/conf/rules/test.rules to client path file:///u:/openhab2/conf/rules/test.rules

Using SMB network path (doesn't work).

2018-12-05 09:49:48.627 [DEBUG] [thome.model.lsp.internal.ModelServer] - Going to wait for a client to connect
2018-12-05 09:49:48.628 [DEBUG] [thome.model.lsp.internal.ModelServer] - Client /192.168.99.66:58945 connected
2018-12-05 09:49:48.660 [DEBUG] [el.lsp.internal.MappingUriExtensions] - Identified client workspace as 'file://openhabhost/openhab-u/openhab2/conf'
2018-12-05 09:49:48.661 [TRACE] [el.lsp.internal.MappingUriExtensions] - Going to map path file:///opt/openhab2/conf
2018-12-05 09:49:48.661 [TRACE] [el.lsp.internal.MappingUriExtensions] - Mapped path file://openhabhost/openhab-u/openhab2/conf to file:///opt/openhab2/conf/
2018-12-05 09:49:48.745 [ERROR] [eclipse.lsp4j.jsonrpc.RemoteEndpoint] - Internal error: java.lang.IllegalArgumentException: URI has an authority component
java.util.concurrent.CompletionException: java.lang.IllegalArgumentException: URI has an authority component
        at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:292) ~[?:?]
        at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:308) ~[?:?]
mhilbush commented 5 years ago

So in the IDE, at this point in the code I can see this when a drive letter is used (i.e. c:\Users\mark_000...)

pathWithScheme: file:///c%3A/Users/mark_000/smarthome-master/git/smarthome/distribution/smarthome/conf

And this when a UNC path is used (i.e. \\localhost\Users\mark_000...)

pathWithScheme: file://localhost/Users/mark_000/smarthome-master/git/smarthome/distribution/smarthome/conf

Not sure where to go with this next...

MHerbst commented 5 years ago

Not sure where to go with this next...

If I understand the implementation correctly the code gets the pathes from the client and tries to translate it the path that is local to the LSP. Therefore it tries to parse and understand the complete path. But this does not work in all situations:

Maybe the solution of this is quite simple but I am not sure whether I am missing something: as far as I can see you only need the name file and the directory entry where it is stored. Why not simply cut these elements from the passed path and then concat them with local configuration path.

Example: Let's assume the configuration files are stored on Linux in /etc/openhab2.

The LSP client now passes the following UNC path to the LSP //openhabian/openhab/items/testitems.items.

From this path only the filename, its extension and the directory where it is store are needed, so extract them from the path: items/testitems.items (if the local filesystem and the path passed to the LSP use different slashes they need to be translated)

Now concat the extracted file information with the configuration folder: /etc/openhab2 + / + items/testitems.items giving: /etc/openhab2/items/testitems.items.

unparagoned commented 5 years ago

I was confused why LSP had stopped working after a new windows install. I was just opening the openhab-config directly over the network with vscode i.e. open folder \openhabian\openhab2-config. And I got the "java.util.concurrent.CompletionException: java.lang.IllegalArgumentException: URI has an authority component error, without realising what it meant, I thought it was from upgrading to 2.4. Anyway the fix was quite simple, map the network drive to Z:/ and open up Z:/ with vscode, and LSP started running straight away.