lsp-mode install java eclipse.jdt.ls server 安装失败

Emacs只负责下载maven,jdtls是maven下载的

我看了一下 lsp 的代码,下载是通过 make-process 进行的,这大概是 with-proxy 无效的原因。即使楼主设置了 maven 的代理,恐怕也因为进入了 sh -c 而使得代理文件没有找到(生效)。


UPDATE:

不完全是代理设置的问题,代理其实是可以穿透到子 shell 的:

(with-proxy
    (make-process
     :name "test"
     :command '("sh" "-c" "echo $HTTP_PROXY")
     :stdout "*test*"
     :buffer "*test*"
     :noquery t))
;; => 127.0.0.1:7890

而像 wget (不了解 maven) 这样的工具不会自动使用环境中的代理,必须明确指定:

(display-buffer
 (process-buffer
  (with-proxy
    (make-process
     :name "test"
--   :command '("sh" "-c" "wget https://google.com")
++   :command `("sh" "-c" ,(concat "wget https://google.com"
++                                 " -e use_proxy=yes"
++                                 " -e http_proxy=$HTTP_PROXY"
++                                 " -e https_proxy=$HTTP_PROXY"))
     :stdout "*test*"
     :buffer "*test*"
     :noquery t))))
;; =>
;; --2020-03-15 13:29:32--  https://google.com/
;; Connecting to 127.0.0.1:7890... connected.
;; Proxy request sent, awaiting response... 301 Moved Permanently
;; Location: https://www.google.com/ [following]
;; --2020-03-15 13:29:33--  https://www.google.com/
;; Connecting to 127.0.0.1:7890... connected.
;; Proxy request sent, awaiting response... 200 OK

原来如此,那在lsp的make-process子进程里其实代理是继承的,奇怪,我确定代理是ok的,偏偏无法下载,不管试了几次都是timeout failed。

maven 也支持命令行直接设代理:

$ mvn clean install -DproxySet=true -DproxyHost=ur.proxy.server -DproxyPort=port

楼主试试把 maven 代理配置文件删掉,然后到 Emacs:

;; 1. `lsp-java--prepare-mvnw' 走 url.el,也需要代理
(with-proxy
  :http-server "127.0.0.1:XXXX"
  ;; 2. maven 下载命令由 `lsp-java--ensure-server' 生成,
  ;; 这里抖个机灵,把代理挂在 url 后面注入进去。
  ;; 也可以直接进到函数里面去修改:
  (let ((lsp-java-jdt-download-url
         (concat lsp-java-jdt-download-url
                 (format " -DproxySet=true -DproxyHost=%s -DproxyPort=%s"
                         "127.0.0.1"
                         "XXXX"))))
    ;; 3. 开始下载
    (call-interactively 'lsp-install-server)))

prepare 和 ensure 两个地方代理都设置到了,应该就可以了。

2 个赞

非常感谢,你的命令可行,执行后立马开始下载了。虽然maven 下载插件失败了。但是代理问题解决了。哈哈哈,赞一个。

以下是maven 安装 lsp-java 的输出内容:

https://paste.ubuntu.com/p/hG9rTQCnPT/

看报错,似乎Maven按照那样设置后,它把代理的字符串设置也当作artifact名的一部分了。

Downloading: https://download.eclipse.org/jdtls/snapshots/jdt-language-server-latest.tar.gz -DproxySet=true -DproxyHost=127.0.0.1 -DproxyPort=8118
org.apache.maven.wagon.ResourceDoesNotExistException: Resource missing at https://download.eclipse.org/jdtls/snapshots/jdt-language-server-latest.tar.gz%20-DproxySet=true%20-DproxyHost=127.0.0.1%20-DproxyPort=8118 404 Not Found
	at org.apache.maven.wagon.providers.http.wagon.shared.AbstractHttpClientWagon.fillInputData(AbstractHttpClientWagon.java:1185)

我觉得还是hack一下lsp-java–ensure-server函数,把代理注入到options里

看了下

发现lsp-java–ensure-server的参数都是定义在 pom.xml 里的,不知道外头定义的变量有没有用。


发现是用了download-maven-plugin这个插件,理论上应该时能继承java/maven proxy的? 看下面的issue还在Open的状态

直接进 lsp-java--ensure-server 加代理参数试试。

我前面的设置第 2 步没实测过,只是看了一下 lsp-java--ensure-server 的实现,感觉可以从 url 注入。

嗯嗯,直接hack下这个函数会方便点。我看看能不能有办法让它支持继承proxy设置。可以的话,去提交个PR。

之前在edebug调试的时候,发现lsp是在 /tmp/ 下新建一个临时目录,然后下载这个pom.xml 文件,然后在这个临时项目目录里用Maven去下载安装的。

– UPDATE – 我测试过 @twlz0ne 的那个最新的命令,是可以下载的,至少 从 githubusercontent.com 下载 pom.xml 这一步是可以了。看Maven的错误log,到 download-maven-plugin 这一步就出错了。之前 concatnate 后的maven proxy -D 设置被作为包的一部分了。我去除了concatnate的部分后重试,还是无法下载,监控流量,java和v2ray的进程都没有下载流量。我一开始也设置过Maven 的proxy设置,但是也不行的。看了 @zsxh 提供的issue,一样的情况,里面有些人可以。但是我这边还是不行。

还是手动的办法,在 lsp-java 自动创建的临时目录 /tmp/lsp-java-installeUtzg 下,使用命令:

mvn clean install -DproxySet=true -DproxyHost=127.0.0.1 -DproxyPort=8118 https://download.eclipse.org/jdtls/snapshots/jdt-language-server-latest.tar.gz

这样倒是能够下载。

我把代理设置的代码改了一下:

;; 1. `lsp-java--prepare-mvnw' 走 url.el,也需要代理
(with-proxy
  :http-server "127.0.0.1:7890"
  ;; 2. maven 下载命令由 `lsp-java--ensure-server' 生成,
  ;; 这里通过 `lsp-async-start-process' 追加代理参数
  (define-advice lsp-async-start-process
      (:around (fn callback error-callback &rest command) add-maven-proxy-option)
    (apply fn 
           callback
           error-callback
           (if (member (nth 1 command) '("mvnw" "mvnw.cmd"))
               (append command
                       `(,(format
                           "-DproxySet=true -DproxyHost=%s -DproxyPort=%s"
                           "127.0.0.1"
                           "7890")))
             command)))

  ;; 3. 开始下载
  (display-buffer
   (process-buffer
    (call-interactively 'lsp-install-server))))

并且已经下载好了:

Screenshot_2020-03-15_at_3.01.47_PM_eclipse.jdt.ls_download

这个 mvnw, mvnw.cmd 是不是 Maven在Windows下的命令名字?

– UPDATE –

试了下,v2ray和java进程还是没有流量波动,没在下载,虽然命令执行到下载部分了。我有点懵啊,,,, 我估计应该确实是 download-maven-plugin 组件的问题。

之前的这个说法有误,特此更正。

影响 wget 使用代理的因素有二:

  1. ~/.wgetrc 中禁止了:

    # ~/.wgetrc
    use_proxy = off
    
  2. 使用了大写的环境变量 HTTP_PROXY,而 wget 只认小写的 http_proxy。最新的 with-proxy 已修复该问题。现在可以不必如 #19 楼那般在命令行注入代理参数了,直接:

    (with-proxy
      (call-interactively 'lsp-install-server))
    
2 个赞

执行你的代码后,出现如下错误:

Debugger entered--Lisp error: (wrong-type-argument processp (((t lsp-java-progress-string)) ssh-deploy--mode-line-status-text org-mode-line-string))
  process-buffer((((t lsp-java-progress-string)) ssh-deploy--mode-line-status-text org-mode-line-string))
  (display-buffer (process-buffer (call-interactively 'lsp-install-server)))
  (let ((process-environment (cl-copy-list process-environment))) (setenv "http_proxy" "127.0.0.1:8118") (setenv "https_proxy" "127.0.0.1:8118") (display-buffer (process-buffer (call-interactively 'lsp-install-server))))
  (progn (let ((process-environment (cl-copy-list process-environment))) (setenv "http_proxy" "127.0.0.1:8118") (setenv "https_proxy" "127.0.0.1:8118") (display-buffer (process-buffer (call-interactively 'lsp-install-server)))))
  (unwind-protect (progn (let ((process-environment (cl-copy-list process-environment))) (setenv "http_proxy" "127.0.0.1:8118") (setenv "https_proxy" "127.0.0.1:8118") (display-buffer (process-buffer (call-interactively 'lsp-install-server))))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))
  (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (let ((process-environment (cl-copy-list process-environment))) (setenv "http_proxy" "127.0.0.1:8118") (setenv "https_proxy" "127.0.0.1:8118") (display-buffer (process-buffer (call-interactively 'lsp-install-server))))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))
  (let ((temp-buffer (generate-new-buffer " *temp*"))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (let ((process-environment (cl-copy-list process-environment))) (setenv "http_proxy" "127.0.0.1:8118") (setenv "https_proxy" "127.0.0.1:8118") (display-buffer (process-buffer (call-interactively ...))))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))))
  (let ((url-proxy-services '(("http" . "127.0.0.1:8118") ("https" . "127.0.0.1:8118") ("ftp" . "127.0.0.1:8118") ("no_proxy" . "^\\(localhost\\|127.0.0.1\\|192.168.*\\|10.*\\)")))) (let ((temp-buffer (generate-new-buffer " *temp*"))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (let ((process-environment ...)) (setenv "http_proxy" "127.0.0.1:8118") (setenv "https_proxy" "127.0.0.1:8118") (display-buffer (process-buffer ...)))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))))
  (progn (let ((url-proxy-services '(("http" . "127.0.0.1:8118") ("https" . "127.0.0.1:8118") ("ftp" . "127.0.0.1:8118") ("no_proxy" . "^\\(localhost\\|127.0.0.1\\|192.168.*\\|10.*\\)")))) (let ((temp-buffer (generate-new-buffer " *temp*"))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (let (...) (setenv "http_proxy" "127.0.0.1:8118") (setenv "https_proxy" "127.0.0.1:8118") (display-buffer ...))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))))))
  (unwind-protect (progn (let ((url-proxy-services '(("http" . "127.0.0.1:8118") ("https" . "127.0.0.1:8118") ("ftp" . "127.0.0.1:8118") ("no_proxy" . "^\\(localhost\\|127.0.0.1\\|192.168.*\\|10.*\\)")))) (let ((temp-buffer (generate-new-buffer " *temp*"))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (let ... ... ... ...)) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))
  (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (let ((url-proxy-services '(... ... ... ...))) (let ((temp-buffer (generate-new-buffer " *temp*"))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn ...) (and ... ...)))))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))
  (let ((temp-buffer (generate-new-buffer " *temp*"))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (let ((url-proxy-services '...)) (let ((temp-buffer ...)) (save-current-buffer (set-buffer temp-buffer) (unwind-protect ... ...))))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))))
  eval((let ((temp-buffer (generate-new-buffer " *temp*"))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (let ((url-proxy-services ...)) (let (...) (save-current-buffer ... ...)))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))) nil)
  elisp--eval-last-sexp(nil)
  eval-last-sexp(nil)
  eros-eval-last-sexp(nil)
  funcall-interactively(eros-eval-last-sexp nil)
  call-interactively(eros-eval-last-sexp nil nil)
  command-execute(eros-eval-last-sexp)

看了 lsp-install-server 的源代码,看不出是否返回的是一个 process 。你那边测试正常么?

这是内部用的 maven 的命令,你可以试试

mvn \
  -Djdt.js.server.root=/home/larry/.emacs.d/eclipse.jdt.ls/server \
  -Djunit.runner.root=/home/larry/.emacs.d/eclipse.jdt.ls/test-runner \
  -Djunit.runner.fileName=/home/larry/.emacs.d/eclipse.jdt.ls/test-runner/junit-platform-console-standalone.jar \
  -Djava.debug.root=/home/larry/.emacs.d/eclipse.jdt.ls/server/bundles \
  -Djdt.download.url=https://download.eclipse.org/jdtls/snapshots/jdt-language-server-latest.tar.gz \
  package

https://github.com/xqliu/dotfiles/tree/master/lsp/java

我这边测试正常。

我设置错误的代理才会出现你这个情况,而且如果把 (display-buffer (process-buffer 去掉,得到的真正错误信息是:

Contacting host: raw.githubusercontent.com:443
LSP :: Server jdtls install process failed with the following error message:
127.0.0.1/XXXX nodename nor servname provided, or not known.

我写了一个一键运行的最小配置:test-lsp-jdtls-installation.el

我在浏览器里访问了一下 raw.githubusercontent.com:443 无法访问,就算我开启浏览器代理插件也不行。估计是网络哪里设置了障碍。我代理也是一直访问不了google。之前一段时间还能看youtube,现在也打不开了。都是一样的报错。

– UPDATE – 算了,这个方案能执行就行。等我之后再处理代理的问题。

谢谢,mark

不想折腾代理的可以设置下这个变量

  (setq lsp-java--download-root "https://gitee.com/liujiacai/lsp-java/raw/master/install/")

其实就是把 lsp-java/install at master · emacs-lsp/lsp-java · GitHub 目录下载下来(利用 gitee 来做中转),然后执行

/usr/local/opt/jenv/versions/1.8/bin/java -classpath \ /usr/local/Cellar/maven/3.6.3/libexec/boot/plexus-classworlds-2.6.0.jar \ 
-Dclassworlds.conf=/usr/local/Cellar/maven/3.6.3/libexec/bin/m2.conf \
-Dmaven.home=/usr/local/Cellar/maven/3.6.3/libexec \
-Dlibrary.jansi.path=/usr/local/Cellar/maven/3.6.3/libexec/lib/jansi-native \
-Dmaven.multiModuleProjectDirectory=/var/folders/gr/6044y_957fl31k5j89f8pxtw0000gp/T/lsp-java-installLOqaag org.codehaus.plexus.classworlds.launcher.Launcher \
-Djdt.js.server.root=$HOME/.emacs.d/ignore/lsp-server/eclipse.jdt.ls/ \
-Djunit.runner.root=$HOME/.emacs.d/eclipse.jdt.ls/test-runner/ \
-Djunit.runner.fileName=junit-platform-console-standalone.jar \
-Djava.debug.root=$HOME/.emacs.d/ignore/lsp-server/eclipse.jdt.ls/bundles clean package \
-Djdt.download.url=https://download.eclipse.org/jdtls/snapshots/jdt-language-server-latest.tar.gz

大家仿照着改改就行。

可悲的是,jdt 现在只支持 jdk11+ 了。。。jdk8 只用能老版本的了

测试了下,最后一个版本支持 jdk8 的是 0.57.0,最终的配置

(use-package lsp-java
  :hook (java-mode . lsp-deferred)
  :init
  (setq lsp-java--download-root "https://gitee.com/liujiacai/lsp-java/raw/master/install/"
        lsp-java-workspace-dir (expand-file-name "workspace" my/ignore-directory)
        dap-java-test-runner (expand-file-name "eclipse.jdt.ls/test-runner/junit-platform-console-standalone.jar" my/ignore-directory)
        ;; jdk8 isn't supported in latest version
        ;; https://github.com/emacs-lsp/lsp-java/issues/249
        lsp-java-jdt-download-url "http://mirrors.ustc.edu.cn/eclipse/jdtls/milestones/0.57.0/jdt-language-server-0.57.0-202006172108.tar.gz")
  )
2 个赞