redhat-developer / vscode-java

Java Language Support for Visual Studio Code
Eclipse Public License 2.0
2.07k stars 433 forks source link

"java.lang.IllegalArgumentException: Bad escape" when path has non-ASCII characters #3735

Closed alexchentt closed 1 month ago

alexchentt commented 1 month ago

EDIT: CORRECTION

TLDR is that on version 1.33.0, when the project path contains non-ASCII characters, diagnostics would throw the exception java.lang.IllegalArgumentException: Bad escape. Moving the project to a path that contains only ASCII characters would prevent this.

Original Post

[provide a description of the issue] (Noobie here, I'm sorry if I am not supposed to ask about this here)

Fresh install of openjdk@21, vscode (universal binary) and Extension Pack for Java (that includes redhat-developer/vscode-java 1.33.0) on arm64 macOS 15.0 will cause internal errors when loading in any java projects and the plugin will then provide no syntax checking. The plugin on 1.32.0 functions as expected.

Most errors are of the same type, here is an example:

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-08-06 17:03:04.096
!MESSAGE >> java/validateDocument

!ENTRY org.eclipse.jdt.ls.core 1 0 2024-08-06 17:03:04.711
!MESSAGE begin problem for /Sample.java

!ENTRY org.eclipse.core.jobs 4 2 2024-08-06 17:03:04.712
!MESSAGE An internal error occurred during: "Publish Diagnostics".
!STACK 0
java.lang.IllegalArgumentException: Bad escape
    at java.base/sun.nio.fs.UnixUriUtils.fromUri(Unknown Source)
    at java.base/sun.nio.fs.UnixFileSystemProvider.getPath(Unknown Source)
    at java.base/java.nio.file.Path.of(Unknown Source)
    at java.base/java.nio.file.Paths.get(Unknown Source)
    at org.eclipse.jdt.ls.core.internal.JDTUtils.isExcludedFile(JDTUtils.java:1843)
    at org.eclipse.jdt.ls.core.internal.handlers.BaseDiagnosticsHandler.matchesDiagnosticFilter(BaseDiagnosticsHandler.java:154)
    at org.eclipse.jdt.ls.core.internal.handlers.WorkspaceDiagnosticsHandler.publishDiagnostics(WorkspaceDiagnosticsHandler.java:324)
    at org.eclipse.jdt.ls.core.internal.handlers.WorkspaceDiagnosticsHandler.publishDiagnostics(WorkspaceDiagnosticsHandler.java:254)
    at org.eclipse.jdt.ls.core.internal.handlers.JDTLanguageServer$2.run(JDTLanguageServer.java:334)
    at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
Environment
Steps To Reproduce
  1. Install macOS 15.0 Beta.
  2. Fresh install OpenJDK brew install openjdk@21
  3. Symlink and path setting of openjdk
    sudo ln -sfn /opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-21.jdk)
    echo 'export PATH="/opt/homebrew/opt/openjdk@21/bin:$PATH"' >> ~/.profile
  4. Fresh install vscode
  5. Install Extension Pack for Java in vscode
  6. Load any projects or create a new one **Load any projects WITH PATH containing non-ASCII characters***
  7. Let the extension load
  8. Run "Open Java Language Server Logfile" and see the error.

[Please attach a sample project reproducing the error] Any project will do. Projects located in paths with non-ASCII characters

Please attach logs log.log

Current Result
Expected Result
Additional Informations
rgrunber commented 1 month ago

Are you using java.diagnostic.filter option ? It was newly introduced in 1.33.0. What is it set to ? (Going to assume it's likely empty as the stacktrace indicates it isn't related to the value itself)

Are you able to share the sample project for which this occurs ? Seems pretty similar to https://bugs.openjdk.org/browse/JDK-8162518 .

alexchentt commented 1 month ago

@rgrunber that non ASCII character bug is the culprit, thank you!

My new system is German and turns out the OneDrive directory is not ~/Library/CloudStorage/OneDrive-Personal anymore but OneDrive-Persönlich. That ö is causing all the trouble. After moving the folder out of OneDrive, plugin version 1.33.0 worked absolutely flawlessly. Thank you so much.

Still don't quite understand why 1.32.0 can handle that ö but 1.33.0 can't though.

rgrunber commented 1 month ago

We added a new feature in 1.33.0 that requires checking each file (most likely when diagnostics need to be update). This happens in places like : https://github.com/eclipse-jdtls/eclipse.jdt.ls/blob/master/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/BaseDiagnosticsHandler.java#L149-L155 . This ends up calling https://github.com/eclipse-jdtls/eclipse.jdt.ls/blob/master/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/JDTUtils.java#L1837-L1846 .

We can definitely reduce the likelihood of this for people not using the filter feature, since we can check if the list is empty ([] is the default value) before going through all that conversion.

Update: I also found errors that likely existed even before 1.33.0 relating to mishandling of non-ascii characters in the paths :

[Error - 12:04:51] Aug. 6, 2024, 12:04:51 p.m. Error while handling document save. URI: file:///home/rgrunber/sample-projects/json-example/src/org/example/OneDrive-Pers%C3%B6/Testing.java
_/src/org/example/OneDrive-Persö [in json-example_96bcdf0c] does not exist
Java Model Exception: Error in Java Model (code 969): _/src/org/example/OneDrive-Persö [in json-example_96bcdf0c] does not exist
    at org.eclipse.jdt.internal.core.JavaElement.newNotPresentException(JavaElement.java:562)
    at org.eclipse.jdt.internal.core.PackageFragmentRoot.getUnderlyingResource(PackageFragmentRoot.java:764)
    at org.eclipse.jdt.internal.core.PackageFragment.getUnderlyingResource(PackageFragment.java:430)
    at org.eclipse.jdt.internal.core.Openable.getUnderlyingResource(Openable.java:328)
    at org.eclipse.jdt.internal.core.CompilationUnit.getUnderlyingResource(CompilationUnit.java:967)
    at org.eclipse.jdt.ls.core.internal.handlers.BaseDocumentLifeCycleHandler.handleSaved(BaseDocumentLifeCycleHandler.java:569)
    at org.eclipse.jdt.ls.core.internal.handlers.BaseDocumentLifeCycleHandler.didSave(BaseDocumentLifeCycleHandler.java:369)
    at org.eclipse.jdt.ls.core.internal.handlers.JDTLanguageServer.didSave(JDTLanguageServer.java:925)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.base/java.lang.reflect.Method.invoke(Unknown Source)
    at org.eclipse.lsp4j.jsonrpc.services.GenericEndpoint.lambda$recursiveFindRpcMethods$0(GenericEndpoint.java:65)
    at org.eclipse.lsp4j.jsonrpc.services.GenericEndpoint.notify(GenericEndpoint.java:160)
    at org.eclipse.lsp4j.jsonrpc.RemoteEndpoint.handleNotification(RemoteEndpoint.java:231)
    at org.eclipse.lsp4j.jsonrpc.RemoteEndpoint.consume(RemoteEndpoint.java:198)
    at org.eclipse.jdt.ls.core.internal.ParentProcessWatcher.lambda$1(ParentProcessWatcher.java:144)
    at org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer.handleMessage(StreamMessageProducer.java:185)
    at org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer.listen(StreamMessageProducer.java:97)
    at org.eclipse.lsp4j.jsonrpc.json.ConcurrentMessageProcessor.run(ConcurrentMessageProcessor.java:114)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.base/java.lang.Thread.run(Unknown Source
snjeza commented 1 month ago

We can try to use

path = Paths.get(uri.toURL().getPath());

instead of

path = Paths.get(uri);

at https://github.com/eclipse-jdtls/eclipse.jdt.ls/blob/b7998dc6e5c42fe7b83c69d2eab3b150d75ff025/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/JDTUtils.java#L1843

rgrunber commented 1 month ago

I can add that to the existing PR after testing that it works.

CT702-7 commented 1 month ago

Same issue happens when chinese characters appear in the address of the project...