coc-java icon indicating copy to clipboard operation
coc-java copied to clipboard

Go To Definition Not Working (Windows 10, Git Bash, Open JDK 8)

Open gbroques opened this issue 5 years ago • 10 comments

Hi, For some reason, "gd" to "go to definition" isn't working for me.

There was a similar issue reported on Gitter: https://gitter.im/neoclide/coc.nvim?at=5d35dfa209580b7bbb88d2d4

Maybe it's a file path or escaping issue? Any troubleshooting ideas would be great!

The below is the error I get when wanting to jump to the definition of SpringApplication.

[coc.nvim] Error on 'jumpDefinition': request error nvim_call_function - Vim(edit):E480: ** No match**: jdt://contents/spring-boot-1.5.13.RELEASE.jar/org.springframework.boot/SpringApplication.class?=account-entitlement/C:%5C/Users%5C/P2812140%5C/.m2%5C/repository%5C/org%5C/springframework%5C/boot%5C/spring-boot%5C/1.5.13.RELEASE%5C/spring-boot-1.5.13.RELEASE.jar=/maven.pomderived=/true=/=/maven.pomderived=/true=/=/maven.groupId=/org.springframework.boot=/=/maven.artifactId=/spring-boot=/=/maven.version=/1.5.13.RELEASE=/=/maven.scope=/compile=/%3Corg.springframework.boot(SpringApplication.class

Workspace Output

See attached server.log for output of :CocCommand workspace.showOutput java: server.log

Attached GIF

jump-definition-error

Windows Version

I'm using Git Bash on Windows 10.

OS Name	Microsoft Windows 10 Enterprise Insider Preview
Version	10.0.19569 Build 19569
Java Version
$ java -version
openjdk version "1.8.0_242"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_242-b08)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.242-b08, mixed mode)

gbroques avatar Apr 21 '20 20:04 gbroques

It looks like LanguageClient-neovim had a similar issue and was able to resolve it.

@chemzqm, Do you have any insight into this issue?


P.S.: I see we declared support for the jdt:// URIs in index.ts. More information referencing this here.

Looks like we added support for eclipse.jdt.ls in #112 of coc.vim: https://github.com/neoclide/coc.nvim/issues/112

gbroques avatar Apr 21 '20 22:04 gbroques

Please upload connection log so I could reproduce it easily, please follow these steps:

  • Add let g:node_client_debug = 1 to your vimrc.
  • Restart your vim/neovim to make the issue happen.
  • Open the log file by command :call coc#client#open_log().
  • Attach the log file or paste content from the log.

chemzqm avatar Apr 22 '20 03:04 chemzqm

@chemzqm server2.log is uploaded.

Also, around 10:57:49 PM in the logs is an example of the error when trying to jump to the definition of String.java.

Thank you so much!! <3

I'm willing to help and contribute, but could use some guidance or pointers.

10:57:49 PM DEBUG [transport] - nvim notification: nvim_call_function,[
  "coc#util#echo_messages",
  [
    "Error",
    [
      "[coc.nvim] Error on 'jumpDefinition': request error nvim_call_function - Vim(edit):E480: No match: jdt://contents/rt.jar/java.lang/String.class\\?=account-entitlement/C:%5C/Program%20Files%5C/AdoptOpenJDK%5C/jdk-8.0.242.08-hotspot%5C/jre%5C/lib%5C/rt.jar=/maven.pomderived=/true=/=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/javase%5C/8%5C/docs%5C/api%5C/=/%3Cjava.lang(String.class"
    ]
  ]
]

gbroques avatar Apr 22 '20 04:04 gbroques

Doing more research.

I looked at the eclipse.jdt.ls project and the java/classFileContents handler.

This java/classFileContents handler calls the toURI method with special logic if it detects your OS as "win32" here:


package org.eclipse.jdt.ls.core.internal;
...
public final class JDTUtils {
        ...
        // Line 866
	URI uri = new URI(uriString);
        // Platform.OS_WIN32 => "win32"
	if (Platform.OS_WIN32.equals(Platform.getOS()) && URIUtil.isFileURI(uri)) {
		uri = URIUtil.toFile(uri).toURI();
	}
	return uri;

Also, more special "win32" OS logic in this findResource method.

gbroques avatar Apr 22 '20 05:04 gbroques

has win32unix

Also, I see there's calls to has("win32unix") to get special CygWin path prefixes in the logs. For example:

10:53:28 PM DEBUG [transport] - request to nvim: 2,nvim_eval,[
  "has(\"win32unix\")?get(g:,\"coc_cygqwin_path_prefixes\", v:null):v:null"
]

has("win32unix") evaluates to false, or 0 for me.

has win32

However, has("win32") evaluates to true, or 1 for me.

gbroques avatar Apr 22 '20 05:04 gbroques

Try :call coc#util#jump('edit', 'jdt://contents/rt.jar/java.lang/String.class\?=account-entitlement/C:%5C/Program%20Files%5C/AdoptOpenJDK%5C/jdk-8.0.242.08-hotspot%5C/jre%5C/lib%5C/rt.jar=/maven.pomderived=/true=/=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/javase%5C/8%5C/docs%5C/api%5C/=/%3Cjava.lang(String.class', [111,20]) in your vim, I don't get your error.

chemzqm avatar Apr 22 '20 06:04 chemzqm

The URL contains ? character, which causes a wildcard matching bug of both VIM and NeoVIM on Windows. Unlike Unix, Windows uses backslash as the path separator, but fnameescape() also uses backslash as the escaping character. After escaping, any ? in the original URL would become \?. For :edit command, the argument is treaded as {file} for VIM, thus, wildcard expansion applies. However, the escape does not work at all. The \ is recognized as the path separator (not the escaping charactor) , so ? would still be treated as a wildcard, causing VIM to search in the path, resulting in NO MATCH error.

This is a rather frustrating bug of VIM on Windows, as such a fundamental function fnameescape() is broken. Difficult to handle such URLs unless opening them using a different approach from :edit {file}.

chengzeyi avatar Apr 22 '20 08:04 chengzeyi

neovim/neovim#3912

chengzeyi avatar Apr 22 '20 08:04 chengzeyi

Try :call coc#util#jump('edit', 'jdt://contents/rt.jar/java.lang/String.class\?=account-entitlement/C:%5C/Program%20Files%5C/AdoptOpenJDK%5C/jdk-8.0.242.08-hotspot%5C/jre%5C/lib%5C/rt.jar=/maven.pomderived=/true=/=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/javase%5C/8%5C/docs%5C/api%5C/=/%3Cjava.lang(String.class', [111,20]) in your vim, I don't get your error.

@chemzqm I tried this, and get the same error.


@chengzeyi Thank you for some of this clarity. Is there a workaround for me? For example, how you would you manually edit the following JDT URI to work on Vim Windows?

jdt://contents/rt.jar/java.lang/String.class\?=account-entitlement/C:%5C/Program%20Files%5C/AdoptOpenJDK%5C/jdk-8.0.242.08-hotspot%5C/jre%5C/lib%5C/rt.jar=/maven.pomderived=/true=/=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/javase%5C/8%5C/docs%5C/api%5C/=/%3Cjava.lang(String.class

I can't seem to edit that URI and get my Neovim to open it.


Potential Workaround

@ZyX-I posted a modified fnameescape function for Windows: https://github.com/vim/vim/issues/2749#issuecomment-375929630

if has('win32') || has('win64')
  function Fnameescape(f)
    return '`='.json_encode(a:f).'`'
  endfunction
else
  let Fnameescape = function('fnameescape')
endif

Will something like that maybe work?

gbroques avatar Apr 22 '20 14:04 gbroques

Any update on this? I am experiencing a similar error when trying to go to definition:

[coc.nvim] definition not found

I have jdtls installed and no configurations related to it in my coc-settings.json

unrealapex avatar Oct 19 '22 18:10 unrealapex