jdtls为啥只能通过 sudo 才正常工作

描述

如果是直接点击图标,或者是命令行就emacs启动,jdtls会报错 Server jdtls:67683/starting exited (check corresponding stderr buffer for details). Do you want to restart it? (y or n) 除非我用sudo emacs,可关键是我也没在这个链路上看到需要有关什么权限的啊。emacs安装目录,jdtls的安装目录都是正常的用户权限,不需要root权限

环境

macOS: Ventura 13.5.1
emacs: [email protected] (installed by brew)
lsp-java: 20230827.428
jdtls : jdt-language-server-1.26.0-202307271613
java : 17 (JAVA_HOME is setted by jenv)

场景重现

  1. 下载 jdtls-1.26 from http://download.eclipse.org/jdtls/milestones/
  2. 将 jdtls 那个bin 目录加载到 环境变量. jdtls所在的目录不需要root权限 export PATH=/Users/mmmmmcclxxvii/.emacs.d/lsp-server/jdt-language-server-1.26.0-202307271613/bin:$PATH image
  3. Install lap-java via melpa
  4. emacs中 配置 jdtls的路径 (setq lsp-java-server-install-dir "~/.emacs.d/lsp-server/jdt-language-server-1.26.0-202307271613")
  5. 配置lsp-java Quick start
  6. 启动 emacs --debug-init
  7. C-x C-f open ~/Develop/temp/Application.java

期待结果

展示类似于: LSP:: jdtls connected to xxxx

截图 image 点击图标启动的/或者是 emacs --debug-init 启动


image

上面是通过sudo emacs 启动的,可以看到 jdtls可以正常

  1. 可能是你的项目或临时文件夹权限设置问题。
  2. *lsp-log* 缓冲有更详细的日志信息。
  1. 临时文件不需要root权限 image

  2. lsp-log里面

Command "semgrep lsp" is not present on the path.
Command "semgrep lsp" is not present on the path.
Found the following clients for /Users/mmmmmcclxxvii/Develop/temp/Application.java: (server-id jdtls, priority 0)
The following clients were selected based on priority: (server-id jdtls, priority 0)
Command "semgrep lsp" is not present on the path.
Command "semgrep lsp" is not present on the path.
Found the following clients for /Users/mmmmmcclxxvii/Develop/temp/Application.java: (server-id jdtls, priority 0)
The following clients were selected based on priority: (server-id jdtls, priority 0)

log 只有这么多?

sudo 下可以运行,说明 jdtls 本身没有问题。我能想到的可能:

  1. sudo和当前用户环境变量不同。
  2. 文件权限,除了项目/临时/缓存目录之外,还有可能是在这之前用 sudo 安装了 jdtls 依赖的文件。
  3. 你的配置当中存在干扰,建议使用最小配置。

直接外部终端执行 jdtls 看看报什么错,另外可以也可以在emacs 的 term 内执行。

直接执行好像没报错啊

log只有这么多,是的。

通过lsp-bridge 去连jdtls,不用sudo启动

你这个截图不完整,后面还会返回一串 json。

除了直接运行 jdtls 之外,还可以试试完整命令(命令因人不同,以 (insert (string-join (lsp-java--ls-command) " ")) 导出为准):

java -Declipse.application=org.eclipse.jdt.ls.core.id1 \
    -Dosgi.bundles.defaultStartLevel=4 \
    -Declipse.product=org.eclipse.jdt.ls.core.product \
    -Dlog.protocol=true \
    -Dlog.level=ALL \
    -XX:+UseParallelGC \
    -XX:GCTimeRatio=4 \
    -XX:AdaptiveSizePolicyWeight=90 \
    -Dsun.zip.disableMemoryMapping=true \
    -Xmx1G \
    -Xms100m \
    -jar $HOME/.jdtls/plugins/org.eclipse.equinox.launcher_1.6.500.v20230717-2134.jar \
    -configuration $HOME/.jdtls/config_mac \
    -data $HOME/.emacs.d/29.1/workspace/ \
    --add-modules=ALL-SYSTEM \
    --add-opens java.base/java.util=ALL-UNNAMED \
    --add-opens java.base/java.lang=ALL-UNNAMED
Content-Length: 126

{"jsonrpc":"2.0","method":"window/logMessage","params":{"type":3,"message":"Sep 14, 2023, 1:04:36 PM Main thread is waiting"}}

这个返回表示 jdtls 正在等待接入。

重启提示是 lsp-mode 发出的,有可能真的 jdtls 退出了,有可能 jdtls 还在运行,但是 lsp-mode 连不上。

你说的是这个lsp-log吧

我在 #8 楼说的是命令行,后边还举了例子。

jdtils 正常运行必然有返回。

  1. 直接执行jdtls 就只有截图那一点,后面没有出现json
  2. 看一下完整命令
  3. 执行命令 但是报错了,这个log文件很大,这是前面部分 一些Caused by
  4. 上面命令加了sudo 出现你说的json

~/.emacs.d/workspace/.metadata 失败:

1 个赞

谢谢 大佬 发现多次出现 这个 .metadata 写不进去, 结果发现,是这里

修改用户和组别后可以了!