Subject: bug#66726: 29.1; Eglot jdtls formatter ignored

From: Cay Horstmann <[email-masked]>
Date: Mon, 6 Nov 2023 18:16:01 +0100

On 29/10/2023 15.40, João Távora wrote:
> On Sun, Oct 29, 2023 at 12:08 PM Eli Zaretskii <[email-masked]> wrote:
>>
>>> Date: Tue, 24 Oct 2023 11:17:09 +0200
>>> From: Cay Horstmann <[email-masked]>
>>>
>>> Eglot does not trigger a custom formatter with jdtls, while lsp-java and VS Code with the Red Hat Java plugin can do this. See https://github.com/joaotavora/eglot/discussions/1222 for more background.
>>>
>>> I attach files
>>> * eglot-debug.el (the minimal configuration to see the failure)
>>> * NotHelloWorld.java (a sample Java file)
>>> * cay-eclipse-formatter.xml (the formatting rules for jdtls)
>>> * eglot-events.txt (the events log from eglot)
>>> * lsp-java-debug.el (the minimal configuration to see how it works with lsp-java)
>>> * lsp-log.txt (the log from the successful run with lsp)
>>>
>>> Download jdtls from https://download.eclipse.org/jdtls/snapshots/?d. I
>>> have the version from Oct. 14, 2023. Put it somewhere on your PATH
>>>
>>> Put the NotHelloWorld.java file in some directory (I use /tmp/hello)
>>>
>>> Put the cay-eclipse-formatter.xml file somewhere and adjust the path in eglot-debug.el and lsp-java-debug.el.
>>>
>>> emacs -q -l eglot-debug.el /tmp/hello/NotHelloWorld.java
>>>
>>> M-x eglot RET
>>>
>>> Wait for jdtls to start
>>>
>>> M-x eglot-format-buffer RET
>>>
>>> The formatting should now use the rules in the cay-eclipse-formatter.xml
>>> file, resulting in 8 changes but the same Allman indentation
>>> style. Instead, it uses a K&R indentation style.
>>>
>>> To see the proper formatting, install lsp-mode and lsp-java and start with lsp-java-debug.el. Or use VS Code with the Red Hat Java plugin and the settings.json
>>>
>>> {
>>>       "java.format.settings.url": "file:///data/cay/bin/cay-eclipse.formatter.xml",
>>>       "java.format.settings.profile": "cay"
>>> }
>>
>> João, any comments?
> 
> Not many.  Seems like a good error recipe, assuming someone
> finds the time to reproduce it.  If I had to guess, I'd say
> almost surely a server-side quirk about it not finding the
> xml file from that slightly strange url.  Maybe lsp-mode is
> setting some environment variable.  But that would
> require me debugging Java which I haven't done in just
> about 20 years and not really looking forward to.
> 
> Cay, is there some kind of jtdls error log where it reports
> things?  Can you also attach the Eglot stderr buffer, in case
> it has something useful?  Use `M-x eglot-stderr-buffer`.
> 
> The only thing that seems to be missing is the Emacs version,
> but I'll assume it's the version used in M-x report-emacs-bug
> itself, which is 29.1.
> 
> João

Hello, here is another stab at this.

* There is no problem with that funny looking file:/// URL. jdtls can find it when invoked from VS Code and lsp-mode.

* I attach the initialization that happens from VS Code. It looks just like the one that I am setting up in eglot. Look at the path initializationOptions.settings.java.format.settings.

Formatting works fine in VS Code. The logs show requests such as this one:

[Trace - 3:51:32 PM] Sending request 'textDocument/formatting - (71)'.
Params: {
     "textDocument": {
         "uri": "file:///tmp/test/NotHelloWorld.java"
     },
     "options": {
         "tabSize": 4,
         "insertSpaces": true
     }
}

These look just like the ones that eglot sends. But the response is a formatting directive that follows the formatter, whereas with eglot, the response is a directive that follows some default.

* Here is the requested eglot-stderr-buffer:

WARNING: Using incubator modules: jdk.incubator.vector, jdk.incubator.foreign
Nov 06, 2023 4:20:36 PM org.apache.aries.spifly.BaseActivator log
INFO: Registered provider ch.qos.logback.classic.servlet.LogbackServletContainerInitializer of service jakarta.servlet.ServletContainerInitializer in bundle ch.qos.logback.classic
Nov 06, 2023 4:20:36 PM org.apache.aries.spifly.BaseActivator log
INFO: Registered provider ch.qos.logback.classic.spi.LogbackServiceProvider of service org.slf4j.spi.SLF4JServiceProvider in bundle ch.qos.logback.classic

* Yes, it is Emacs 29.1.

* The jdtls logs are a mystery to me. According to https://github.com/eclipse-jdtls/eclipse.jdt.ls/issues/752#issuecomment-412275314,

"Should be in workspace/.metadata/.log, workspace location is a parameter you pass when starting the server."

Who is "you"? I suppose the client, i.e. eglot or VS Code. I find files such as

./eglot-java-eclipse-jdt-cache/a397d9cc217eb5e87ff722051c2f059b/.metadata/.log

but they don't contain any info on today's interactions. There is no other directory in that cache. I can tell from that log that the directory was passed as a --data command-line argument. But when I intercept jdtls today via a script to log the command-line args, there is no --data command-line argument passed when invoking jdtls.

Thanks,

Cay

--

Cay S. Horstmann | http://horstmann.com | mailto:[email-masked]