Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove duplicate listing of Symbols #3452

Closed
rajinder-yadav opened this issue Jan 7, 2024 · 10 comments · Fixed by eclipse-jdtls/eclipse.jdt.ls#3140
Closed

Remove duplicate listing of Symbols #3452

rajinder-yadav opened this issue Jan 7, 2024 · 10 comments · Fixed by eclipse-jdtls/eclipse.jdt.ls#3140
Assignees
Labels
Milestone

Comments

@rajinder-yadav
Copy link

Type: Bug

When searching for Symbols in workspace, IDE will show duplicates.

Open a Java source file, then perform a Symbol lookup in the workspace.
Search for "ArrayList" and you will see several duplicates in the list.

snap-20240107-01

Extension version: 1.25.1
VS Code version: Code - Insiders 1.86.0-insider (9621add46007f7a1ab37d1fce9bcdcecca62aeb0, 2023-12-20T05:36:34.875Z)
OS version: Linux x64 6.6.7-1-default
Modes:

System Info
Item Value
CPUs AMD Ryzen 9 5900X 12-Core Processor (24 x 3998)
GPU Status 2d_canvas: enabled
canvas_oop_rasterization: disabled_off
direct_rendering_display_compositor: disabled_off_ok
gpu_compositing: enabled
multiple_raster_threads: enabled_on
opengl: enabled_on
rasterization: enabled
raw_draw: disabled_off_ok
skia_graphite: disabled_off
video_decode: enabled
video_encode: disabled_software
vulkan: disabled_off
webgl: enabled
webgl2: enabled
webgpu: disabled_off
Load (avg) 0, 1, 1
Memory (System) 62.71GB (48.35GB free)
Process Argv /home/yadav/dev/docs/guides --crash-reporter-id 210d9130-10f4-4cf9-ad76-187d60112fd6
Screen Reader no
VM 0%
DESKTOP_SESSION plasma5
XDG_CURRENT_DESKTOP KDE
XDG_SESSION_DESKTOP KDE
XDG_SESSION_TYPE x11
A/B Experiments
vsliv695:30137379
vsins829:30139715
vsliv368:30146709
vsreu685:30147344
vspor879:30202332
vspor708:30202333
vspor363:30204092
vslsvsres303:30308271
vsc_aa:30263845
vshan820:30294714
vscod805cf:30301675
bridge0708:30335490
bridge0723:30353136
vsaa593cf:30376535
py29gd2263:30784851
vsclangdf:30492506
c4g48928:30535728
2i9eh265:30646982
pythongtdpath:30726887
i26e3531:30792625
welcomedialog:30812478
pythonidxpt:30768918
pythonnoceb:30776497
asynctok:30898717
dsvsc013:30777762
dsvsc014:30777825
dsvsc015:30821418
pythontestfixt:30866404
pythonregdiag2:30926734
pyreplss1:30879911
pythonmypyd1:30859725
pythoncet0:30859736
pythontbext0:30879054
accentitlementst:30870582
dsvsc016:30879898
dsvsc017:30880771
dsvsc018:30880772
aa_t_chat:30882232
cp7184t3:30927821

@rgrunber
Copy link
Member

I'm able to reproduce this by creating a multi-module Maven project where modules have different compiler requirements. For example, one project has source/target 1.8 while another has 17.

When I search for ArrayList, the 2 results (among others) coming from the language server are :

[
    ...
    ...
    {
        "name": "ArrayList",
        "kind": 5,
        "location": {
            "uri": "jdt://contents/rt.jar/java.util/ArrayList.class?=com.example.project-eight-my-app/%5C/usr%5C/lib%5C/jvm%5C/java-1.8.0-openjdk-1.8.0.392.b08-7.fc39.x86_64%5C/jre%5C/lib%5C/rt.jar=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/javase%5C/8%5C/docs%5C/api%5C/=/=/maven.pomderived=/true=/%3Cjava.util(ArrayList.class",
            "range": {
                "start": {
                    "line": 0,
                    "character": 0
                },
                "end": {
                    "line": 0,
                    "character": 0
                }
            }
        },
        "containerName": "java.util"
    },
    {
        "name": "ArrayList",
        "kind": 5,
        "location": {
            "uri": "jdt://contents/java.base/java.util/ArrayList.class?=com.example.project-two-my-app/%5C/usr%5C/lib%5C/jvm%5C/java-17-openjdk%5C/lib%5C/jrt-fs.jar%60java.base=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/en%5C/java%5C/javase%5C/17%5C/docs%5C/api%5C/=/=/maven.pomderived=/true=/%3Cjava.util(ArrayList.class",
            "range": {
                "start": {
                    "line": 0,
                    "character": 0
                },
                "end": {
                    "line": 0,
                    "character": 0
                }
            }
        },
        "containerName": "java.util"
    }
]

In your case, the paths probably look even more similar because in your case, the 2 JREs are above version 9 (so it'd be a module path).

If you can confirm that's what's happening in your case, I think this still raises a good point. If someone has 2 Types (or even visible member) coming from different libraries that look identical, we should probably add version information to how its displayed to make it more clear.

@rajinder-yadav
Copy link
Author

My java project is based off a maven project, I am only using java 21.

As for a working solution, I makes sense to see items from the version used in the project. It's possible the local installed version of java could differ from the one the project is getting built with and run off. As a developer, I only care for what the version the project is based on, which could be:

  • Maven project
  • Gradle project
  • VSCode own Java project structured
  • Eclipsed based

I use SDKMAN to install different java versions, but I don't think this is the cause of what getting shown in vscode for symbols.

I'm not sure how VSCode determines where to find the java/jdk to use?
I did a search from my environment variables.
I know I am setting the values for JAVA_HOME and JRE_HOME is my .bashrc script to that of the SDKMAN install location.

Not sure what is setting JAVA_BINDIR, JAVA_ROOT value? or is VSCode even uses these values.

$ set|grep JAVA
JAVA_BINDIR=/usr/lib64/jvm/jre-openjdk/bin
JAVA_HOME=/home/yadav/.sdkman/candidates/java/current
JAVA_ROOT=/usr/lib64/jvm/jre-openjdk

$ set|grep JRE
JRE_HOME=/home/yadav/.sdkman/candidates/java/current/bin

SDKMAN version:

$ sdk current java

Using java version 21-tem

Current java version

$ java -version
openjdk version "21" 2023-09-19 LTS
OpenJDK Runtime Environment Temurin-21+35 (build 21+35-LTS)
OpenJDK 64-Bit Server VM Temurin-21+35 (build 21+35-LTS, mixed mode, sharing)

Maven POM

Project java version is set to 21

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.1</version>
    <relativePath /> <!-- lookup parent from repository -->
  </parent>
  <groupId>com.ninja</groupId>
  <artifactId>collection</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>h2-jpa-maven</name>
  <description>Demo project for Spring Boot</description>
  <properties>
    <java.version>21</java.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <excludes>
            <exclude>
              <groupId>org.projectlombok</groupId>
              <artifactId>lombok</artifactId>
            </exclude>
          </excludes>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

Let me know if there is any other investigation I can help with, like any log file or debug output vscode might show.

@rgrunber
Copy link
Member

That ArrayListPointer symbol in your original screenshot would seem to be coming from an OpenJ9 JDK. Any chance that's the 2nd JDK being picked up ? One thing you could try is temporarily setting the java.trace.server to verbose (default is off). Go into VS Code's "Output" tab (often beside the "Problems" view), and select "Language Support for Java" from the dropdown. Now try to search for "ArrayList" using the workspace symbol search. Since the search is incremental, you'll want to look for an entry like :

[Trace - 16:14:10] Sending request 'workspace/symbol - (34)'.
Params: {
    "query": "ArrayList"
}

(you can search for "query": "ArrayList" as a search term, and everything below it should be elements that matched that query.)

You should probably see 2 entries (among a few others) whose "containerName" is "java.util", and whose "name" is "ArrayList". Look at their uri value and that should indicate which JDK is contributing them. For example, in my case it was :

"uri": "jdt://contents/rt.jar/java.util/ArrayList.class?=com.example.project-eight-my-app/%5C/usr%5C/lib%5C/jvm%5C/java-1.8.0-openjdk-1.8.0.392.b08-7.fc39.x86_64%5C/jre%5C/lib%5C/rt.jar=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/javase%5C/8%5C/docs%5C/api%5C/=/=/maven.pomderived=/true=/%3Cjava.util(ArrayList.class"

"uri": "jdt://contents/java.base/java.util/ArrayList.class?=com.example.project-two-my-app/%5C/usr%5C/lib%5C/jvm%5C/java-17-openjdk%5C/lib%5C/jrt-fs.jar%60java.base=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/en%5C/java%5C/javase%5C/17%5C/docs%5C/api%5C/=/=/maven.pomderived=/true=/%3Cjava.util(ArrayList.class"

which are clearly /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.392.b08-7.fc39.x86_64 & /usr/lib/jvm/java-17-openjdk

@rajinder-yadav
Copy link
Author

Hi here is what I am seeing

{
        "name": "ArrayList",
        "kind": 5,
        "location": {
            "uri": "jdt://contents/java.base/java.util/ArrayList.class?=jdt.ls-java-project/%5C/home%5C/yadav%5C/.sdkman%5C/candidates%5C/java%5C/11.0.11.j9-adpt%5C/lib%5C/jrt-fs.jar%60java.base=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/en%5C/java%5C/javase%5C/11%5C/docs%5C/api%5C/=/%3Cjava.util(ArrayList.class",
            "range": {
                "start": {
                    "line": 0,
                    "character": 0
                },
                "end": {
                    "line": 0,
                    "character": 0
                }
            }
        },
        "containerName": "java.util"
    },
    {
        "name": "ArrayList",
        "kind": 5,
        "location": {
            "uri": "jdt://contents/java.base/java.util/Arrays$ArrayList.class?=jdt.ls-java-project/%5C/home%5C/yadav%5C/.sdkman%5C/candidates%5C/java%5C/11.0.11.j9-adpt%5C/lib%5C/jrt-fs.jar%60java.base=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/en%5C/java%5C/javase%5C/11%5C/docs%5C/api%5C/=/%3Cjava.util(Arrays$ArrayList.class",
            "range": {
                "start": {
                    "line": 0,
                    "character": 0
                },
                "end": {
                    "line": 0,
                    "character": 0
                }
            }
        },
        "containerName": "java.util.Arrays"
    },

@rgrunber
Copy link
Member

The 2 entries aren't duplicates though. One is java.util.Arrays.ArrayList and the other is java.util.ArrayList. There must be a 2nd entry (among others) that is either java.util.ArrayList or java.util.Arrays.ArrayList. The uri of that one would give some more information. Both the above entries are coming from /home/yadav/.sdkman/candidates/java/11.0.11.j9-adpt

@rajinder-yadav
Copy link
Author

rajinder-yadav commented Jan 17, 2024

So why does vscode show each 2 times in the snapshot?
I've opened the same project in IntelliJ and it shows each once.

@fbricon
Copy link
Collaborator

fbricon commented Jan 17, 2024

@rajinder-yadav was the trace you pasted really complete? Please attach the entire json response

@rgrunber
Copy link
Member

rgrunber commented Jan 17, 2024

I can reproduce this. I took a single-module Maven project and simply set the compiler runtime to something other than 17. It's also reproducible with Gradle.

<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
{
        "name": "ArrayList",
        "kind": 5,
        "location": {
            "uri": "jdt://contents/java.base/java.util/ArrayList.class?=jdt.ls-java-project/%5C/usr%5C/lib%5C/jvm%5C/java-17-openjdk%5C/lib%5C/jrt-fs.jar%60java.base=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/en%5C/java%5C/javase%5C/17%5C/docs%5C/api%5C/=/%3Cjava.util(ArrayList.class",
            "range": {
                "start": {
                    "line": 0,
                    "character": 0
                },
                "end": {
                    "line": 0,
                    "character": 0
                }
            }
        },
        "containerName": "java.util"
    },
    ...
    ...
   {
        "name": "ArrayList",
        "kind": 5,
        "location": {
            "uri": "jdt://contents/java.base/java.util/ArrayList.class?=my-app/%5C/usr%5C/lib%5C/jvm%5C/java-11-openjdk-11.0.21.0.9-3.fc39.x86_64%5C/lib%5C/jrt-fs.jar%60java.base=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/en%5C/java%5C/javase%5C/11%5C/docs%5C/api%5C/=/=/maven.pomderived=/true=/%3Cjava.util(ArrayList.class",
            "range": {
                "start": {
                    "line": 0,
                    "character": 0
                },
                "end": {
                    "line": 0,
                    "character": 0
                }
            }
        },
        "containerName": "java.util"
    },
    ...
    ...

The interesting part is :
?=my-app/%5C/usr%5C/lib%5C/jvm%5C/java-11-openjdk-11.0.21.0.9-3.fc39.x86_64%5C/lib%5C/jrt-fs.jar
vs.
?=jdt.ls-java-project/%5C/usr%5C/lib%5C/jvm%5C/java-17-openjdk%5C/lib%5C/jrt-fs.jar

You were right @fbricon , it looks like the default project's classpath is part of the search. I would guess it should be disabled when the project isn't invisible.. or it should also react to the change to keep everything the same.

I wouldn't mind having @rajinder-yadav post that extra symbol data to confirm but this is very likely the cause.

@rajinder-yadav
Copy link
Author

@rajinder-yadav was the trace you pasted really complete? Please attach the entire json response

vscode-java-trade.txt

@rgrunber
Copy link
Member

rgrunber commented Jan 17, 2024

Thanks! Yup, it looks like the same issue. Your "collections" project is configured with Java 21 but the "default" project (jdt.ls-java-project) is set to Java 11.

{
      "name": "ArrayList",
      "kind": 5,
      "location": {
        "uri": "jdt://contents/java.base/java.util/ArrayList.class?=collections/%5C/home%5C/yadav%5C/.sdkman%5C/candidates%5C/java%5C/21-tem%5C/lib%5C/jrt-fs.jar%60java.base=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/en%5C/java%5C/javase%5C/20%5C/docs%5C/api%5C/=/=/maven.pomderived=/true=/%3Cjava.util(ArrayList.class",
        "range": {
          "start": {
            "line": 0,
            "character": 0
          },
          "end": {
            "line": 0,
            "character": 0
          }
        }
      },
      "containerName": "java.util"
    },
    ...
    ...
    {
      "name": "ArrayList",
      "kind": 5,
      "location": {
        "uri": "jdt://contents/java.base/java.util/ArrayList.class?=jdt.ls-java-project/%5C/home%5C/yadav%5C/.sdkman%5C/candidates%5C/java%5C/11.0.11.j9-adpt%5C/lib%5C/jrt-fs.jar%60java.base=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/en%5C/java%5C/javase%5C/11%5C/docs%5C/api%5C/=/%3Cjava.util(ArrayList.class",
        "range": {
          "start": {
            "line": 0,
            "character": 0
          },
          "end": {
            "line": 0,
            "character": 0
          }
        }
      },
      "containerName": "java.util"
    },
    ...
    ...

There's 2 things we should probably do as part of this :

  1. Maybe set the default project to any project JDK that is in use, just to avoid the duplication. I considered disabling the default project during the symbol search lookup but that option doesn't seem too great
  2. For any workspace symbol results originating from the same library, we should add some version number into the label to make it more obvious what's happening.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: ✅ Done
Development

Successfully merging a pull request may close this issue.

3 participants