GithubHelp home page GithubHelp logo

yveszoundi / eglot-java Goto Github PK

View Code? Open in Web Editor NEW
50.0 6.0 11.0 208 KB

Java extension for the eglot LSP client

License: GNU General Public License v3.0

Emacs Lisp 100.00%
emacs emacs-lisp eglot java

eglot-java's People

Contributors

magielbruntink avatar tomrss avatar yveszoundi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

eglot-java's Issues

Upgrade existing JDT LS installation

Problem

There appears to be no "official" way to upgrade the installed JDT LS. You could delete the installation directory, but it's obviously a hack. Probably also need to shut down (how exactly?) the eglot server and (manually?) start again after deleting.

Potential solution

  • Check the currently installed version against the latest known available version
  • For each opened buffer associated with eglot-java-mode, ensure that the eglot-server is not running, otherwise stop it: Maybe just disabling eglot-java-mode is good enough
  • Install the new jdtls version to a temporary folder
  • If the installation succeeds
    • Move the old jdtls installation folder to a temporary folder
    • Move the new jdtls to its new destination
    • Delete the old jdtls installation folder
  • For each opened buffer associated with java-mode, ensure that the eglot-server is running, by reassociating the buffer with eglot-java-mode

References

This depends on #15 .

Support running specific @Test method

Problem

Currently it's only possible to run tests for an entire class.

Proposed Solution

Approach

The eglot-java-run-test function behavior will be changed:

  • If there's an enclosing method near the current cursor location ("the point"), that specific method will be executed
  • Otherwise, all the tests in the current file will be executed (current behavior at this time)

Technical constraints

There's no built-in LSP server handler that will return automatically all the available test methods in a given file.

If the mouse cursor is near a helper method, this package will blindly assume that "you know what you're doing" and you'll get an error message from the Junit console logs.

Support JDT URIs from textDocument/defintion requests

I have been looking at an issue over in the JDT LSP repository: eclipse-jdtls/eclipse.jdt.ls#2322

A summary of how I reproduce this issue (with the latest snapshot of jdtls, not using eglot-java at all)

  • Add this entry to the eglot-server-programs: (java-mode . ("jdtls" :initializationOptions (:extendedClientCapabilities (:classFileContentsSupport t))))
  • clone groot, commit 1f275a41cb63dfb985c797934005bcd7159ed0a7
  • cd groot && mvn compile
  • visit groot/src/main/java/org/jlab/groot/math/F1D.java
  • Execute xref-find-definitions on the Expression symbol on line 23

The relevant eglot logs

(:jsonrpc "2.0" :id 8 :method "textDocument/definition" :params
          (:textDocument
           (:uri "file:///home/user/dev/groot/src/main/java/org/jlab/groot/math/F1D.java")
           :position
           (:line 22 :character 4)))
[server-reply] (id:8) Sun Nov 13 13:37:57 2022:
(:jsonrpc "2.0" :id 8 :result
          [(:uri "jdt://contents/exp4j-0.4.4.jar/net.objecthunter.exp4j/Expression.class?=groot/%5C/home%5C/user%5C/.m2%5C/repository%5C/net%5C/objecthunter%5C/exp4j%5C/0.4.4%5C/exp4j-0.4.4.jar=/maven.pomderived=/true=/=/javadoc_location=/jar:file:%5C/home%5C/user%5C/.m2%5C/repository%5C/net%5C/objecthunter%5C/exp4j%5C/0.4.4%5C/exp4j-0.4.4-javadoc.jar%5C!%5C/=/=/maven.groupId=/net.objecthunter=/=/maven.artifactId=/exp4j=/=/maven.version=/0.4.4=/=/maven.scope=/compile=/=/maven.pomderived=/true=/%3Cnet.objecthunter.exp4j(Expression.class" :range
                 (:start
                  (:line 24 :character 13)
                  :end
                  (:line 24 :character 23)))])

I think this package would be a good place to handle those JDT URIs. There is a reply in the issue over in JDTLS repository that explains the process for handling them. Essentially the client must make an extra request to the java/classFileContents method of the language server, which will serve back the contents of the decompiled class. From there the client is free to dump the contents into a buffer.

I would be happy to take a swing at implementing this here at some point, but wanted to drop an issue here in case someone else wants to try and beat me to it.

Lombok does not always seem to work correctly

I cannot imagine why it would work in some cases, but not in others, but throughout the majority of the project things work fine, until I see the @Getter annotation.

Everything works fine when I compile the thing.

Also, my lombok verrsion (1.18.30) seems to work fine with lsp-mode and nvim-jdtls.

When things go wrong, I get a lint error at the top of the buffer which reads:
Java [0]: Lombok annotation handler class lombok.eclipse.handlers.HandleGetter failed - See error log. and sometimes, but not always, missing references down the buffer from there.

My vmargs are set as such:

(defun td-eglot-java-setup ()
  (setq eglot-java-eclipse-jdt-args (list (concat "-javaagent:"
                                               td-eglot-java-lombok-path)))
  (td-bind-keys '(("C-c e n" . eglot-java-file-new)
                  ("C-c e x" . eglot-java-run-main)
                  ("C-c e t" . eglot-java-run-test)
                  ("C-c e N" . eglot-java-project-new)
                  ("C-c e T" . eglot-java-project-build-task)
                  ("C-c e R" . eglot-java-project-build-refresh))
                eglot-java-mode-map))

(add-hook 'eglot-java-mode-hook 'td-eglot-java-setup)

When I check the jdt args at run time, they look pretty good to me:

Its value is
("-javaagent:/home/trev/.emacs.d/eglot-java/lombok/lombok.jar" "-jar" "/home/trev/.emacs.d/share/eclipse.jdt.ls/plugins/org.eclipse.equinox.launcher_1.6.700.v20231214-2017.jar" "-configuration" "/home/trev/.emacs.d/share/eclipse.jdt.ls/config_linux" "-data" "/home/trev/.emacs.d/eglot-java-eclipse-jdt-cache/ba359c4c589a8cb98349d0107123787e")
Original value was nil

Any ideas as to what's going on here?

Publish eglot-java on ELPA?

Hi,

would you consider adding this package to ELPA? If so, may I suggest to get in touch with @phikal to check what you need to do?

Thank you!

Allow upgrading the Junit standalone jar for tests

Background

When you invoke the eglot-java-run-test function, it will attempt to download the maven junit-platform-console-standalone jar artifact (if not already cached locally). You can describe the variable eglot-java-junit-platform-console-standalone-jar for more details (C-h v).

Problem

It is not current possible to systemically upgrade the install junit standalone console jar. This is similar in nature to issue #16 .

Solution

Approach

Check for the latest version and then upgrade any existing download.

  • If there was no previously recorded junit version, prompt the user for a new installation
  • Otherwise, upgrade to the latest version, if available

Challenges

It is possible that a version might denote a milestone (e.g., 1.0.0-M1 or 1.0.0-rc1). It is not guaranteed that those versions will be recorded as "releases" in the maven repository metadata.xml.

Core emacs functions will report 1.0.0-M1 as invalid, in comparison to 1.0.0. => (version< "1.0.0-M1" "1.0.0")

See sample metadata.xml
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
  <groupId>org.junit</groupId>
  <artifactId>junit-gradle</artifactId>
  <versioning>
    <latest>5.0.0-ALPHA</latest>
    <release>5.0.0-ALPHA</release>
    <versions>
      <version>5.0.0-ALPHA</version>
    </versions>
    <lastUpdated>20160201140008</lastUpdated>
  </versioning>
</metadata>

Let's assume that the latest available version is 1.0.0-M2 and the installed version is 1.0.0-M1:

  • Check for the presence of a dash (-)
  • Comparse the first portion of the string (version<= "1.0.0" "1.0.0")
  • If the latest version was winning, then stop (e.g., the installed version was "1.0.1")
  • Otherwise, sort compare the rest of the string M2 with the installed version M1
    • If the installed version didn't have any suffix, the installed version wins (and vice-versa)
    • Otherwise, compare the version suffixes with emacs built-in functions (string> "M2" "M1")

build.gradle.kts auto detection

Background

Gradle added Kotlin support in late 2016, starting with version 3.0.

eglot-java never included any Kotlin support for Gradle projects for 2 main reasons:

  • I never used Kotlin professionally, but I did try it few times (mostly in its early days)
  • I don't really program professionally anymore, and I completely forgot about Kotlin

As of mid-2023, it seems that Kotlin is now the default DSL for Gradle project files.

Problem

There's no support for Gradle Kotlin files : no build.gradle.kts or settings.gradle.kts existence checks.
Some people might prefer Kotlin to the Groovy syntax, maybe even more likely when working on Android projects.

Potential Approach

  • Update the conceptual notion of a project for project.el (see eglot-java--project-try)
  • Update the test for gradle projects (see eglot-java--project-gradle-p)
  • Update Gradle project name support (best effort) by considering setttings.gradle.kts if it exists (See eglot-java--project-name-gradle)
  • Update Gradle projects build refresh logic to account for a potential build.gradle.kts file (See eglot-java-project-build-refresh)

Custom timeout settings?

Background

When eglot tries to launch an LSP server, a timeout error can happen if the LSP server is not ready very quickly.

Problem

From a user perspective, the timeout error could be seen as a bug??

Potential solution

  • Custom variable just for the Java LSP server?
  • Or documentation task? "if you get timeout issues, please consult the documentation of the eglot-sync-connect variable...."

The documentation task seem like a better option. The user may want all the connectivity to be async with eglot-sync-connect set to 0.

JDT formatter options

Hi! Awesome package and much appreciated :)

Small tweaks here would make it perfect for my use cases:

  • build.gradle.kts auto detection (I believe this is quite simple looking through the code, but am not certain of it)
  • a wiki to help setting up eclipse JDT formatter options (and maybe some quick tips for auto-format hooked into eglot-format)

These are small things... I am always wondered by the Emacs evolution in recent years!

I am currently in a Termux session so can't really try to open a PR easilly here but I might try it in the future. Leaving this here for reference if anyone can do it before me (which might take a while since I am no pro in Elisp).

Thanks once again for your work! Happy incoming new year!

Crashes on Emacs master. `exited abnormally with code 13`

I am editing a simple Java for Android project, and (eglot-java-mode) does not even start.
Error buffer:

[jsonrpc] D[09:52:40.631] Running language server: /usr/lib64/zulu-openjdk11/bin/java -Declipse.application=org.eclipse.jdt.ls.core.id1 -Dosgi.bundles.defaultStartLevel=4 -Declipse.product=org.eclipse.jdt.ls.core.product -jar /home/lockywolf/.emacs.d/share/eclipse.jdt.ls/plugins/org.eclipse.equinox.launcher_1.6.700.v20231214-2017.jar -configuration /home/lockywolf/.emacs.d/share/eclipse.jdt.ls/config_linux -data /home/lockywolf/.emacs.d/eglot-java-eclipse-jdt-cache/fb975d1c5daaeb77385e3b232729edd2
[jsonrpc] e[09:52:40.633] --> initialize[1] {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"processId":4795,"clientInfo":{"name":"Eglot","version":"1.15"},"rootPath":"/home/lockywolf/OfficialRepos/Telegram/TMessagesProj/","rootUri":"file:///home/lockywolf/OfficialRepos/Telegram/TMessagesProj","initializationOptions":{"extendedClientCapabilities":{"classFileContentsSupport":true},"workspaceFolders":["file:///home/lockywolf/OfficialRepos/Telegram/TMessagesProj"],"settings":{"java":{"home":"/usr/lib64/zulu-openjdk8"},"import":{"gradle":{"enabled":true},"wrapper":{"enabled":true}}}},"capabilities":{"workspace":{"applyEdit":true,"executeCommand":{"dynamicRegistration":false},"workspaceEdit":{"documentChanges":true},"didChangeWatchedFiles":{"dynamicRegistration":true},"symbol":{"dynamicRegistration":false},"configuration":true,"workspaceFolders":true},"textDocument":{"synchronization":{"dynamicRegistration":false,"willSave":true,"willSaveWaitUntil":true,"didSave":true},"completion":{"dynamicRegistration":false,"completionItem":{"snippetSupport":true,"deprecatedSupport":true,"resolveSupport":{"properties":["documentation","details","additionalTextEdits"]},"tagSupport":{"valueSet":[1]}},"contextSupport":true},"hover":{"dynamicRegistration":false,"contentFormat":["markdown","plaintext"]},"signatureHelp":{"dynamicRegistration":false,"signatureInformation":{"parameterInformation":{"labelOffsetSupport":true},"documentationFormat":["markdown","plaintext"],"activeParameterSupport":true}},"references":{"dynamicRegistration":false},"definition":{"dynamicRegistration":false,"linkSupport":true},"declaration":{"dynamicRegistration":false,"linkSupport":true},"implementation":{"dynamicRegistration":false,"linkSupport":true},"typeDefinition":{"dynamicRegistration":false,"linkSupport":true},"documentSymbol":{"dynamicRegistration":false,"hierarchicalDocumentSymbolSupport":true,"symbolKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]}},"documentHighlight":{"dynamicRegistration":false},"codeAction":{"dynamicRegistration":false,"resolveSupport":{"properties":["edit","command"]},"dataSupport":true,"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"]}},"isPreferredSupport":true},"formatting":{"dynamicRegistration":false},"rangeFormatting":{"dynamicRegistration":false},"rename":{"dynamicRegistration":false},"inlayHint":{"dynamicRegistration":false},"publishDiagnostics":{"relatedInformation":false,"codeDescriptionSupport":false,"tagSupport":{"valueSet":[1,2]}}},"window":{"showDocument":{"support":true},"workDoneProgress":true},"general":{"positionEncodings":["utf-32","utf-8","utf-16"]},"experimental":{}},"workspaceFolders":[{"uri":"file:///home/lockywolf/OfficialRepos/Telegram/TMessagesProj","name":"~/OfficialRepos/Telegram/TMessagesProj/"}]}}
[stderr]  Picked up _JAVA_OPTIONS:  -Dsun.java2d.uiScale=1.35 -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel -Dswing.crossplatformlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel
[stderr]  Jan 19, 2024 9:52:41 AM org.apache.aries.spifly.BaseActivator log
[stderr]  INFO: Registered provider ch.qos.logback.classic.servlet.LogbackServletContainerInitializer of service jakarta.servlet.ServletContainerInitializer in bundle ch.qos.logback.classic
[stderr]  Jan 19, 2024 9:52:41 AM org.apache.aries.spifly.BaseActivator log
[stderr]  INFO: Registered provider ch.qos.logback.classic.spi.LogbackServiceProvider of service org.slf4j.spi.SLF4JServiceProvider in bundle ch.qos.logback.classic
[jsonrpc] D[09:52:41.541] Connection state change: `exited abnormally with code 13
'

----------b---y---e---b---y---e----------
[stderr]  
[stderr]  
[stderr]  nil
[stderr]  nil
[stderr]  Process EGLOT (TMessagesProj/(java-mode java-ts-mode)) stderr finished

Add few more custom variables

Background

Since 2017-2018 (before the code was even on GitHub), eglot-java always had very minimal configuration options for the Eclipse JDT language server. It might be time to add few settings found in forks.

Problem

It's not possible to manual define the following

  • JAVA_HOME location
  • An explicit PATH to the java executable, if the java executable is not already in the user PATH environment variable
  • Few gradle options
    • Enabling/Disabling gradle wrapper support at the Java language server level
    • Specifying a Gradle version when Gradle wrapper support is disabled or missing

Discussion: run/debug configurations

Now that with eglot-java it's possible to easily run main classes and test classes/methods, I would like to understand how it could support specific configurations for such runs.

The following come to mind:

  • environment vars
  • main class args
  • other JVM args

One specific case is for projects that use Lombok. With the following in .dir-locals.el we can convince jdtls to process Lombok's annotations:

((nil . ((eval . (setq-local eglot-java-eclipse-jdt-args
                             (push (concat "-javaagent:" "/PATH/TO/lombok.jar")
                                   eglot-java-eclipse-jdt-args))))))

I wonder whether .dir-locals.el is a good mechanism to set Java run configurations in general. For main class args that doesn't seem very convenient, but for environment vars and JVM args it may be.

What are you thoughts?

Eglot-java would not start when open java file

Eglot and eglot-java didn't start when I open any file with java source code from my project.

Steps to reproduce:

  1. Install eglot and eglot-java
  2. Go to folder with java project and open any java file
  3. Got message: File mode specification error: (wrong-type-argument consp nil)
  4. Eclipse Java Language Server didn't installs automatically.

Emacs 28.2
Eglot 1.10
Eglot-java 20221218.1809 from MELPA

ะœัƒ configuration:

(use-package eglot)

(use-package eglot-java
  :requires eglot
  :config
  (progn
    (add-hook 'java-mode-hook 'eglot-java-mode)))

I found (via M-x toggle-debug-on-error) what problem also reproduces, when I call M-x eglot-java-mode after open the java file.

Debugger entered--Lisp error: (wrong-type-argument consp nil)
  eglot-java--init()
  eglot-java-mode(toggle)
  funcall-interactively(eglot-java-mode toggle)
  call-interactively(eglot-java-mode record nil)
  command-execute(eglot-java-mode record)
  execute-extended-command(nil "eglot-java-mode" "eglot-java-m")
  funcall-interactively(execute-extended-command nil "eglot-java-mode" "eglot-java-m")
  call-interactively(execute-extended-command nil nil)
  command-execute(execute-extended-command)

Download issues for Junit standalone jar behind VPN

Background

When you invoke the eglot-java-run-test function, it will attempt to download the maven junit-platform-console-standalone jar artifact (if not already cached locally).

  • This will look for the jar artifact in sonatype.org repositories.
  • For more information, please also inspect the value of the eglot-java-junit-platform-console-standalone-jar-url variable (C-h v).

Problem

When behind a VPN (e.g., NordVPN), sonatype.org might request some user credentials for the junit jar download (as no browser captcha will be displayed to check whether you're a bot or a real human).

Please note that I'm not promoting a specific VPN such as NordVPN.

Potential Solution

  • Create a new custom variable holding the junit-platform-console-standalone root maven url, such as https://repo1.maven.org/maven2/. If that URL creates problems, users can change it themselves with another URL that doesn't attempt to block them behind their particular network setup.
  • Mark the variable eglot-java-junit-platform-console-standalone-jar-url as obsolete (See the make-obsolete-variable function)
  • Get the latest version from the maven-metadata.xml (metadata > versioning > latest).
    • Insert the metadata.xml contents into a temporary buffer (with the url-insert-file-contents function)
    • Parse the XML string (XML_STRING) by parsing the current temporary XML buffer
    • Extract the version (caddar (xml-get-children (car (xml-get-children (car (XML_STRING)) 'versioning)) 'release))
  • Download the latest available jar artifact, after computing accordingly the jar URL location.

recent change created invalid property list

I have a failure with ensure-eglot due to these lines. This can't be serialized to JSON because it's an invalid property list (a tag with 2 values).

eglot-java/eglot-java.el

Lines 146 to 149 in ea51c47

`(:settings (:java (:home ,home))
(:import (:gradle (:enabled t)))
)

Moving a left parenthesis seems to fix it, though I'm just guessing that :import is another setting of :java.

          `(:settings (:java (:home ,home)
                       :import (:gradle (:enabled t)))
                      
                      )

Attempt to mitigate some doom-emacs issues

Background

https://discourse.doomemacs.org/t/error-when-loading-eglot-java/3923

Problem

  • Some functions don't seem to be autoloaded in other emacs variants (while apparently working just fine on "plain emacs").
  • Extracting the Eclipse JDT archive (tar.gz file) fails because of multi-byte settings??? It could be that multi-byte defaults are not necessarily the same across emacs variants????

Potential solution

For multibyte issues, not really sure about what can be done, buffer local settings would be set for a given file mode apparently.

For functions not automatically discovered, libraries can be eagerly loaded (xml and tar-mode libraries)

Setting JVM arguments for the LSP server not working with lombok

Emacs version 28.2
OS version: MacOS 13.3.1
Architecture: ARM (Apple M1)

(setq eglot-java-eclipse-jdt-args
'(
"-noverify"
"-Xmx1G"
"-XX:+UseG1GC"
"-XX:+UseStringDeduplication"
"-javaagent:/.m2/repository/org/projectlombok/lombok/1.18.20/lombok-1.18.20.jar"
"-Xbootclasspath/a:
/.m2/repository/org/projectlombok/lombok/1.18.20/lombok-1.18.20.jar"
))

jsonrpc-request: jsonrpc-error: "request id=73 failed:", (jsonrpc-error-code . -32603), (jsonrpc-error-message . "Internal error."), (jsonrpc-error-data . "java.util.concurrent.CompletionException: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @377c7eaf
at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:315)
at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:320)
at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:649)
at java.base/java.util.concurrent.CompletableFuture$Completion.exec(CompletableFuture.java:483)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @377c7eaf
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)
at org.eclipse.osgi.internal.loader.ModuleClassLoader.overrideLoadResult(ModuleClassLoader.java:86)
at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
at org.eclipse.jdt.internal.compiler.parser.Parser.consumeExitVariableWithInitialization(Parser.java:4205)
at org.eclipse.jdt.internal.compiler.SourceElementParser.consumeExitVariableWithInitialization(SourceElementParser.java:406)
at org.eclipse.jdt.internal.compiler.parser.Parser.consumeRule(Parser.java:7156)
at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:13179)
at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:13434)
at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:13391)
at org.eclipse.jdt.internal.compiler.SourceElementParser.parseCompilationUnit(SourceElementParser.java:1122)
at org.eclipse.jdt.internal.core.CompilationUnit.buildStructure(CompilationUnit.java:196)
at org.eclipse.jdt.internal.core.Openable.generateInfos(Openable.java:266)
at org.eclipse.jdt.internal.core.JavaElement.openWhenClosed(JavaElement.java:597)
at org.eclipse.jdt.internal.core.JavaElement.getElementInfo(JavaElement.java:328)
at org.eclipse.jdt.internal.core.JavaElement.getElementInfo(JavaElement.java:314)
at org.eclipse.jdt.internal.core.Openable.getBuffer(Openable.java:296)
at org.eclipse.jdt.ls.core.internal.JDTUtils.findElementsAtSelection(JDTUtils.java:992)
at org.eclipse.jdt.ls.core.internal.JDTUtils.findElementAtSelection(JDTUtils.java:978)
at org.eclipse.jdt.ls.core.internal.handlers.NavigateToDefinitionHandler.computeDefinitionNavigation(NavigateToDefinitionHandler.java:83)
at org.eclipse.jdt.ls.core.internal.handlers.NavigateToDefinitionHandler.definition(NavigateToDefinitionHandler.java:73)
at org.eclipse.jdt.ls.core.internal.handlers.JDTLanguageServer.lambda$7(JDTLanguageServer.java:658)
at org.eclipse.jdt.ls.core.internal.BaseJDTLanguageServer.lambda$0(BaseJDTLanguageServer.java:87)
at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:646)
... 6 more
")

The above setting for lsp-java does work, so I wonder why passing the same jvm argument will cause the discrepancy.

Improve automatic JDT LS installation

Problem

Default value of eglot-java-eclipse-jdt-ls-download-url is a snapshot download. If you are unlucky to install it a time when the latest snapshot is buggy, good luck understanding what's wrong when you are not familiar with eglot.

Potential solution

Switching from release snapshots to release milestones could mitigate this issue.

Sadly, it seems that there's no official Eclipse website API endpoint to retrieve available jdtls releases. (i.e., in comparison to let's say fetching GitHub releases for a given project).

Approach

One option is to leverage the Homebrew jdtls formula REST endpoint to retrieve the latest "known" stable version.

The property paths of interest are .urls.stable.url and .versions.stable, per JSON response exceprt below.

Toggle JSON response exceprt
{
  "name": "jdtls",
  ...
  "versions": {
    "stable": "1.30.0",
    "head": null,
    "bottle": true
  },
  "urls": {
    "stable": {
      "url": "https://www.eclipse.org/downloads/download.php?file=/jdtls/milestones/1.30.0/jdt-language-server-1.30.0-202311301503.tar.gz",
      "tag": null,
      "revision": null,
      "using": null,
      "checksum": "579809f27df5f4e53566217f7273fa25cd45a22d3870c0aafd4f84cdd4c97acd"
    }
  },
  ...
}

Other considerations

We probably need to record the installed jdtls version ( in some form of metadata file??).

Caveats

  • The jdtls version recorded in the Homebrew formula might not be the latest available release milestone.
  • A relase milestone is usually more stable than a release snaphsot, but the milestone could be buggy as well...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.