Problem description
I write java code in VScode. When I holds Ctrl key and clicks a JDK built-in class or method, it seems that it will navigate to the source code of that class or method. But I found that "source code" is actually generated by Fernflower decompiler (I have no idea what it is), not the real source code.
(But if I Ctrl click on user class and method, it will actually navigate to the real source code)
For example,
when I hold the Ctrl key and click on the ArrayList
in the following screenshot,
it will navigate to
showing // Source code is unavailable, and was generated by the Fernflower decompiler.
How can I configure VScode and JDK to make "ctrl click" navigate to the real JDK source code?
More information
- OS: Ubuntu 20.04
- VScode version: 1.74.1
- Installed extension:
Extension Pack for Java (v0.25.7)
Gradle for Java (v3.12.6)
- settings.json
"java.configuration.runtimes": [
{
"name": "JavaSE-17",
"path": "/usr/lib/jvm/java-17-openjdk-amd64",
"default": true
},
{
"name": "JavaSE-11",
"path": "/usr/lib/jvm/java-11-openjdk-amd64"
},
{
"name": "JavaSE-1.8",
"path": "/usr/lib/jvm/java-8-openjdk-amd64"
}
],
What I have tried
See related questions
I see other questions with similar title
a. How to debug JDK source code and add comments in vscode
I can't even understand what OP want to ask. And the answer to that question is on C/C level, not on Java level.
b. VSCode Ctrl Click
The OP cannot use ctrl click to navigate. But I can, just not to the real source code.
Add sources
in settings.json
I found the VScode document Configure Runtime for Projects
and the example setting.json
"java.configuration.runtimes": [
{
"name": "JavaSE-1.8",
"path": "/usr/local/jdk1.8.0_201"
},
{
"name": "JavaSE-11",
"path": "/usr/local/jdk-11.0.3",
"sources" : "/usr/local/jdk-11.0.3/lib/src.zip",
"javadoc" : "https://docs.oracle.com/en/java/javase/11/docs/api",
"default": true
},
{
"name": "JavaSE-12",
"path": "/usr/local/jdk-12.0.2"
},
{
"name": "JavaSE-13",
"path": "/usr/local/jdk-13"
}
]
And I guess the sources
might have something to do with the problem (although the document doesn't mention what sources
does). So I imitate it and add the sources
pointing the path to src.zip
"java.configuration.runtimes": [
{
"name": "JavaSE-17",
"path": "/usr/lib/jvm/java-17-openjdk-amd64",
"default": true,
"sources": "/usr/lib/jvm/java-17-openjdk-amd64/lib/src.zip"
},
{
"name": "JavaSE-11",
"path": "/usr/lib/jvm/java-11-openjdk-amd64"
},
{
"name": "JavaSE-1.8",
"path": "/usr/lib/jvm/java-8-openjdk-amd64"
}
],
But it has no effect.
Disable Java Decompiler
I google "vscode Fernflower decompiler", and most result has somethings to do with the extension "Java Decompiler". I have disabled it, and nothing helps.
CodePudding user response:
I have solved the problem by myself, but still with some confusion.
Solution
- Close the vscode windows.
- Install openjdk-17-source
sudo apt install openjdk-17-source
- Open the vscode windows. Wait vscode to load your java project.
- Be sure to configure java runtime to openjdk-17 screenshot
- Then "Ctrl click" can navigate you to the source code of openjdk-17
Similarly, we can install openjdk-11-source and openjdk-8-source to enable Ctrl click to navigate to the source code of JDK 11 and JDK 8 when java runtime is configured to 11 or 8.
sudo apt install openjdk-11-source
Root cause
Before installing openjdk-17-source
, /usr/lib/jvm/java-17-openjdk-amd64/lib/src.zip
is a broken symbolic link, which doesn't point to a valid src.zip. (I didn't notice it at the first time because when using ls
command in Ubuntu terminal, archive files will be displayed in red font, and broken links will be displayed in red font with black background. There are nearly impossible to notice the difference when a user have a dark terminal background...)
After installing openjdk-17-source
, /usr/lib/jvm/java-17-openjdk-amd64/lib/src.zip
is a valid symbolic link, which points to ../../openjdk-17/src.zip
. And ../../openjdk-17/src.zip
point to lib/src.zip
, which is the real archive file src.zip
.
Some confusion
I found that whether sources
field exists or not in settings.json
has nothing to do with source code navigation.
So we don't need sources
field in settings.json
, like
"java.configuration.runtimes": [
{
"name": "JavaSE-17",
"path": "/usr/lib/jvm/java-17-openjdk-amd64",
},
{
"name": "JavaSE-11",
"path": "/usr/lib/jvm/java-11-openjdk-amd64"
},
{
"name": "JavaSE-1.8",
"path": "/usr/lib/jvm/java-8-openjdk-amd64",
"default": true
}
],
So what's the usage of sources
field?