yveszoundi / eglot-java

Java extension for the eglot LSP client
GNU General Public License v3.0
54 stars 13 forks source link

Setting JVM arguments for the LSP server not working with lombok #13

Closed quanlinc closed 9 months ago

quanlinc commented 1 year ago

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.

yveszoundi commented 1 year ago

This seems to be a configuration issue. I haven't used lombok for several years but I created a minimal project that seems to work (per details to follow). As you can see in the screenshot below, I get completion for the "getName" method.

screenshot

Environment

Relevant JVM args

Notes

(setq eglot-java-eclipse-jdt-args
'(
"-noverify"
"-Xmx1G"
"-XX:+UseG1GC"
"-XX:+UseStringDeduplication"
"-javaagent:/Users/yveszoundi/Downloads/lombok-1.18.20.jar"
"-Xbootclasspath/a:/Users/yveszoundi/Downloads/lombok-1.18.20.jar"
))

Minimal project created for testing

I created a simple project with the command below

mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-
archetype-quickstart -DarchetypeVersion=1.4

Relevant maven pom sections

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <maven.compiler.release>17</maven.compiler.release>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.20</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
quanlinc commented 1 year ago

Thanks for the quick response, other than the architecture difference, I don't see anything different in our settings. Also I've tried using the absolute path, doesn't seem to be the problem, actually I was doing that before I switch to eglot with lsp-java, so the same setting works for lsp, can't think of any reason it won't work as it's just passing the arguments to the same jvm. as of the value to "eglot-java-eclipse-jdt-args", here is a screenshot of what I have after starting up emacs: [image: Screenshot 2023-04-30 at 12.49.31 PM.png]

I also checked the java version, I don't think it matters here, I was using jdk 11, tried 17 as well, if I use maven to compile, test, everything works, but somehow, as soon as I set 'javaagent', it causes server to die I've attached the log for a freshly installed java server. Also, instead of trying things out on my existing project, I started a new one like you did, same issue, if I import lombok classes, with the same jvm settings less 'javaagent' and '-Xbootclasspath/a', I'm able to jump to definitions, but compiler will complain about not able to find definitions of "lombok.val" for example, and I don't get auto completion, which makes sense as I haven't supplied the location of lombok.jar to jvm. The other change I did before switching to eglot on my emacs is the autocompletion plugin, I switched from "company" to "corfu", but I don't think it will cause this behavior either.

I do have an old intel Mac which I will try to play with eglot java later today when I have time, also I will try with a fresh installed vanilla emacs to see if it was caused by some conflict with other settings I have.

Warning: exec-path-from-shell execution took 772ms. See the README for tips on reducing this. Loading /Users/tranchen/.emacs.d/recentf...done Cleaning up the recentf list...done (0 removed) .emacs.d/config/init-dired.el: Warning: ‘after-load’ is an obsolete alias (as of ); use ‘with-eval-after-load’ instead. [2 times] [yas] Prepared just-in-time loading of snippets successfully. [2 times] .emacs.d/config/init-projectile.el: Warning: ‘after-load’ is an obsolete alias (as of ); use ‘with-eval-after-load’ instead. .emacs.d/config/init-flycheck.el: Warning: ‘after-load’ is an obsolete alias (as of ); use ‘with-eval-after-load’ instead. .emacs.d/config/init-lisp.el: Warning: ‘after-load’ is an obsolete alias (as of ); use ‘with-eval-after-load’ instead. [3 times] .emacs.d/config/init-org.el: Warning: Use keywords rather than deprecated positional arguments to `define-minor-mode' .emacs.d/config/init-spelling.el: Warning: ‘after-load’ is an obsolete alias (as of ); use ‘with-eval-after-load’ instead. Starting new Ispell process aspell with default dictionary...done Loading project...done Loading eldoc...done Loading seq...done Loading flymake...done Loading xref...done Loading jsonrpc...done Loading external-completion...done [eglot-java--jdthandler-patch-eglot] Eglot successfully patched. Turn on helm-projectile key bindings Projectile is discovering projects in ~/projects...done [2 times] uncompressing byte-run.el.gz...done Projectile is discovering projects in ~/projects...done Using vacuous schema Projectile is discovering projects in ~/projects...done Setting up indent for shell type zsh Indentation variables are now local. Indentation setup for shell type zsh Projectile is discovering projects in ~/projects...done File mode specification error: (void-function prettier-js) Projectile is discovering projects in ~/projects...done Using vacuous schema Projectile is discovering projects in ~/projects...done [6 times] uncompressing subr.el.gz...done Projectile is discovering projects in ~/projects...done [4 times] uncompressing cl-extra.el.gz...done Projectile is discovering projects in ~/projects...done uncompressing package.el.gz...done Projectile is discovering projects in ~/projects...done [6 times] Wrote /Users/tranchen/.emacs.d/desktop-dir/lock Desktop: 1 frame, 23 buffers restored. Projectile is discovering projects in ~/projects...done init completed in 2526.88ms For information about GNU Emacs and the GNU system, type C-h C-a. Symbol’s value as variable is void: normal-gc-cons-threshold Package cl is deprecated [jsonrpc] Server exited with status 1 Error in post-command-hook (#[0 "\300\303 !\205 �r\211q\210\304\305\301\242\306#\210 ?\205 �\307\310\311 \")\207" [# (#0) eglot--managed-mode buffer-live-p remove-hook post-command-hook t apply eglot--connect eglot--guess-contact] 5]): (error "[eglot] -1: Server died")

-- Tran

On Sat, Apr 29, 2023 at 6:24 PM Yves Zoundi @.***> wrote:

This seems to be a configuration issue. I haven't used lombok for several years but I created a minimal project that seems to work (per details to follow). As you can see in the screenshot below, I get completion for the "getName" method.

[image: screenshot] https://user-images.githubusercontent.com/5206067/235330878-46858ae5-c4e1-426c-b0da-42a8e1e815b5.png Environment

  • Emacs version: 28.2 (installed via pkgsrc)
  • Java version: 17.0.6 (installed via pkgsrc)
  • Operating system: Mac OS 13.3.1 (x86_64), iMac Pro
  • eglot-java version: Latest

Relevant JVM args

Notes

  • I'm using absolute paths for the jars, I don't remember if there's a special syntax for relative paths, etc.
  • I ensured that I didn't have a custom variable set for eglot-java-eclipse-jdt-args (emacs custom-set-variables section in my init file)

(setq eglot-java-eclipse-jdt-args '("-noverify""-Xmx1G""-XX:+UseG1GC""-XX:+UseStringDeduplication""-javaagent:/Users/yveszoundi/Downloads/lombok-1.18.20.jar""-Xbootclasspath/a:/Users/yveszoundi/Downloads/lombok-1.18.20.jar" ))

Minimal project created for testing

I created a simple project with the command below

mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven- archetype-quickstart -DarchetypeVersion=1.4

Relevant maven pom sections

UTF-8 17 17 17 org.projectlombok lombok 1.18.20 provided junit junit 4.11 test

— Reply to this email directly, view it on GitHub https://github.com/yveszoundi/eglot-java/issues/13#issuecomment-1528913327, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABBYCWZN4A5RNAFJSE24QZTXDW5L3ANCNFSM6AAAAAAXQNKDZI . You are receiving this because you authored the thread.Message ID: @.***>

quanlinc commented 1 year ago
Screenshot 2023-04-30 at 12 49 31 PM

I probably should've replied via github when I have image attached, in case you can't view the one replied vie email, here is the screenshot of my "eglot-java-eclipse-jdt-args" setting.

yveszoundi commented 1 year ago

I'm wondering if it could be related to the way that eglot-java-eclipse-jdt-args is set and what it contains.

In the above screenshot, it looks like you've configured its value via the customize-variable function.

Can you please try the following:

  1. Remove any pre-existing entry of eglot-java-eclipse-jdt-args in the custom-set-variables block of your emacs initialization file or emacs custom file
  2. Only set eglot-java-eclipse-jdt-args manually via setq, per previous minimal example
trev-dev commented 1 year ago

This works for me.

.dir-locals.el

((nil . ((eval .
           (setq eglot-java-eclipse-jdt-args
             (list (concat "-javaagent:"
                 (getenv "LOMBOK_JAR"))))))))

My lombok path is set by nixos, with the help of direnv.

Pretty sure you guys need to lose the Xbootclasspath and make sure that -javaagent:/path-to-lombok is high on your options list.

yveszoundi commented 9 months ago

@quanlinc, closing this issue as others don't seem to have any problems.

I assume that you were able to adjust your configuration accordingly to make it work.