Home > Blockchain >  Navigate to JDK source code in vscode (Ctrl click)
Navigate to JDK source code in vscode (Ctrl click)

Time:12-30

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,

Java code image

it will navigate to

result image

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

  1. Close the vscode windows.
  2. Install openjdk-17-source
sudo apt install openjdk-17-source
  1. Open the vscode windows. Wait vscode to load your java project.
  2. Be sure to configure java runtime to openjdk-17 screenshot
  3. 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?

Reference

  • Related