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

textDocument/definition and textDocument/implementation NOT returning external libraries. #3291

Closed
maximstewart opened this issue Sep 29, 2024 · 2 comments

Comments

@maximstewart
Copy link

maximstewart commented Sep 29, 2024

I am unable to get results for external libraries using textDocument/definition and textDocument/implementation but CAN for my source code itself.

To simplify the attempt I copied some of the libraries to a lib folder at my project root. i.e same level as my POM file

What I have tried:

I have added to my .classpath file

<classpathentry kind="lib" path="lib/springframework/spring-web/6.0.11/spring-web-6.0.11.jar"
    sourcepath="lib/springframework/spring-web/6.0.11/spring-web-6.0.11-sources.jar"/>

I have tried editing my init-options with various setups. For example, I add absolute paths to my m2 folders for classPath and docPath but I then see errors regarding them not being found in my project. (They absolutely do exist as paths.) Current init-options are the following:

{
    "workspaceFolders":[
        "file:///home/abaddon/Coding/Projects/Active/Java_Projects/thumbnail-api"
    ],
    "settings":{
        "java":{
            "autobuild":{
                "enabled":false
            },
            "completion":{
                "enabled":true,
                "importOrder":[
                    "java",
                    "javax",
                    "org",
                    "com"
                ]
            },
            "configuration":{
                "maven":{
                    "userSettings":"/home/abaddon/.config/jdtls/settings.xml",
                    "globalSettings":"/home/abaddon/.config/jdtls/settings.xml"
                },
                "runtimes":[
                    {
                        "name":"JavaSE-17",
                        "path":"/usr/lib/jvm/default-runtime",
                        "javadoc":"https://docs.oracle.com/en/java/javase/17/docs/api/",
                        "default":true
                    }
                ]
            },
            "classPath":[
                "lib/**/*-sources.jar"
            ],
            "docPath":[
                "lib/**/*-javadoc.jar"
            ],
            "silentNotification":true,
            "project":{
                "encoding":"ignore",
                "outputPath":"bin",
                "referencedLibraries":[
                    "lib/**/*.jar"
                ],
                "importOnFirstTimeStartup":"automatic",
                "importHint":true,
                "resourceFilters":[
                    "node_modules",
                    "\\.git"
                ],
                "sourcePaths":[
                    "src"
                ]
            },
            "sources":{
                "organizeImports":{
                    "starThreshold":99,
                    "staticStarThreshold":99
                }
            },
            "imports":{
                "gradle":{
                    "wrapper":{
                        "checksums":[]
                    }
                }
            },
            "import":{
                "maven":{
                    "enabled":true,
                    "offline":{
                        "enabled":false
                    },
                    "disableTestClasspathFlag":false
                },
                "exclusions":[
                    "**/node_modules/**",
                    "**/.metadata/**",
                    "**/archetype-resources/**",
                    "**/META-INF/maven/**"
                ],
                "generatesMetadataFilesAtProjectRoot":false
            },
            "maven":{
                "downloadSources":true,
                "updateSnapshots":true
            },
            "signatureHelp":{
                "enabled":true,
                "description":{
                    "enabled":true
                }
            },
            "implementationsCodeLens":{
                "enabled":true
            }
        }
    }
}

Additional (maybe relevant) details:

JDTLS Version:

  • jdtls-1.9.0

Java:

  • openjdk 17.0.12 2024-07-16
  • OpenJDK Runtime Environment (build 17.0.12+7)
  • OpenJDK 64-Bit Server VM (build 17.0.12+7, mixed mode, sharing)

I am trying to setup integration between this and my own written editor. Completion seems to work fine and returns results for things like Spring classes plus additional edits to do imports. GoTo works but only for my project files and not external/additional sources or even just the lib path created under the project holding source JARs.

I am packaging JDTLS as part of an AppImage so JDTLS_PATH is defined when that whole process runs and is extracted. I have tried sans AppImage setup with same results.

Here is how I start JDTLS. Though, note that I have played with changing the -data path to be my project root as well but that just creates a folder jdt.ls-java-project (same level as my POM) and I then get messages about my source code not being in a source directory and thus nothing resolves. config_linux gets copied from my AppImage to the user's .config path.

    export JDTLS_PATH="<see my comments>"
    export JDTLS_CONFIG_PATH="${HOME}/.config/jdtls"
    export JDTLS_DATA_PATH="${JDTLS_CONFIG_PATH}/data"

    java \
	    -Declipse.application=org.eclipse.jdt.ls.core.id1 \
	    -Dosgi.bundles.defaultStartLevel=4 \
	    -Declipse.product=org.eclipse.jdt.ls.core.product \
	    -Dlog.level=ALL \
	    -Xmx1G \
	    --add-modules=ALL-SYSTEM \
	    --add-opens java.base/java.util=ALL-UNNAMED \
	    --add-opens java.base/java.lang=ALL-UNNAMED \
	    -jar "${JDTLS_PATH}/plugins/org.eclipse.equinox.launcher_1.6.400.v20210924-0641.jar" \
	    -configuration "${JDTLS_CONFIG_PATH}/config_linux" \
	    -data "${JDTLS_DATA_PATH}"

When I did do -data at project level the .metadata/.log file would show messages but I think they mostly tied to the issues I saw as mentioned above. When set to .config/jdtls/data/.metadata it has nothing meaningful there.

log.txt

@rgrunber
Copy link
Contributor

rgrunber commented Oct 1, 2024

There's a few things to address here :

  • You're using settings like java.classPath, java.docPath, java.silentNotification but these aren't provided by JDT-LS at all. java.silentNofication does exist but it's a setting meant for vscode-java-debug from what I can see, so doesn't seem like it'd to anything. Is there something in your client that knows to handle these, or some other language server that you're sending these to ? See https://github.com/eclipse-jdtls/eclipse.jdt.ls/wiki/Language-Server-Settings-&-Capabilities#settings for the set of known settings supported by the language server. The rest of your settings look fine though.
  • You shouldn't need to touch the .classpath at all. It's not meant to be modified. Do you have a sample of your thumbnail-api project that can be shared ? You mentioned pom files, so I'm assuming this is a Maven project. If that's the case you should not need to touch the .classpath or attempt to set any dependencies. The language server has support for most Maven/Gradle/Eclipse projects, which means it should automatically detect dependencies and set up the classpath. The reason for java.project.referencedLibraries, java.project.sourcePaths, java.project.outputPath is for when you have a project with no metadata (no pom.xml, no build.gradle, no Eclipse .project/.classpath). Just a set of folders and java source files. In that case we need users to define where the dependencies are stored (eg. default is lib/**/*.jar).
  • For the language server to respond with references into external libraries, you'll need to set { "extendedClientCapabilities": { "classFileContentsSupport": true } }. See result of textDocument/declaration is [] #3166 (comment) as an example.
  • The -data argument is not meant to point to your project, but rather just some location where some of the project metadata can be stored. For convenience, we also have a script, https://github.com/eclipse-jdtls/eclipse.jdt.ls/tree/master/org.eclipse.jdt.ls.product/scripts/jdtls which gets placed at ./org.eclipse.jdt.ls.product/target/repository/bin/jdtls .

I can confirm that this should work though. See https://rgrunber.github.io/vscode/java/lsp/language/server/2023/09/18/talk-to-language-server.html for more details on how I communicate with the language server in this very basic manner.

(formatted for legibility)

Content-Length: 244

{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "textDocument/definition",
    "params": {
        "textDocument": {
            "uri": "file:///home/rgrunber/git/lemminx/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/XMLLanguageServer.java"
        },
        "position": {
            "line": 177,
            "character": 5
        }
    }
}

Content-Length: 478

{
    "jsonrpc": "2.0",
    "id": 2,
    "result": [
        {
            "uri": "jdt://contents/java.base/java.lang/Object.class?=org.eclipse.lemminx/%5C/usr%5C/lib%5C/jvm%5C/java-17-openjdk-17.0.12.0.7-2.fc40.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/17%5C/docs%5C/api%5C/=/=/maven.pomderived=/true=/%3Cjava.lang(Object.class",
            "range": {
                "start": {
                    "line": 37,
                    "character": 13
                },
                "end": {
                    "line": 37,
                    "character": 19
                }
            }
        }
    ]
}

@maximstewart
Copy link
Author

{"extendedClientCapabilities": { "classFileContentsSupport": true } }

The above worked! My goodness I could not find the needed setting to save my life.

  • Good to know about java.classPath, java.docPath, and java.silentNotification not working for JDTLS as I'd gotten some of these settings from another project and think I got myself confused about those. I think maybe it's tied to another LS but don't think it hurts to have them there if ever I want to mix things up. The client I wrote is pretty dumb and all I really want is completion and GOTO so it doesn't handle a lot.
  • I could share my project and it is public if you look for it but I don't really want to actively share it as it's not fit for wiping a nose with. Plus, the mentioned setting works and now all I need to do is actually handle the archived files and load them to my UI.
  • <3
  • Good to get confirmation as I pretty much concluded -data is treated as you say. I just wanted to mention my steps just in case I misunderstood something.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants