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

通过 lsp-java (lsp-mode) 自带的下载server,这个 eclipse.jdt.ls 需要从githubusercontent.com 域名下载压缩包,这个域名要么下载极其慢,只有1k不到,要么索性压根下载不下来,只能上梯子,于是设置了Emacs 的proxy:

(setq url-proxy-services
      '(;; Privoxy
        ("http"  . "127.0.0.1:8118")
        ("https" . "127.0.0.1:8118")
        ;; ("ftp"   . "b.qypac.net:57008")
        ;; don't proxy for localhost, avoid robe server (For Ruby) can't response.
        ("no_proxy" . "^\\(localhost\\|192.168.*\\|10.*\\)")
        ;; no proxy for baidu.com, sina.com etc. proxy for all others.
        ;; ("no_proxy" . "^.*\\(baidu\\|sina)\\.com")
        ))

(setq url-using-proxy "http://127.0.0.1:8118")
(setq url-gateway-method 'socks
      socks-noproxy '("localhost")
      socks-server '("Default server" "127.0.0.1" 1086 5))

也尝试过设置Maven的代理:

<?xml version="1.0"?>
<settings>
  <mirrors>
    <mirror>
      <id>clojars</id>
      <mirrorOf>clojars</mirrorOf>
      <name>cnnic</name>
      <url>https://mirrors.cnnic.cn/clojars/</url>
    </mirror>
  </mirrors>
  <profiles>
    <profile>
      <!-- clojars.org for Clojure -->
      <id>clojars</id>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
      <repositories>
        <repository>
          <id>clojars</id>
          <name>clojars</name>
          <url>http://clojars.org/repo</url>
        </repository>
      </repositories>
    </profile>
  </profiles>
  
  <proxies>
    <proxy>
      <id>localhost</id>
      <active>true</active>
      <protocol>http</protocol>
      <host>localhost</host>
      <port>1086</port>
    </proxy>
  </proxies>
</settings>

都不行。还是下载失败。maven timeout或者其他什么之类的。就是没法安装成功。

不知道哪位大神有什么好的办法?

export http_proxy="http://127.0.0.1:8118"
export https_proxy=$http_proxy
emacs -nw

在终端里试试

试试 with-proxy

(with-proxy
 :http-server "127.0.0.1:XXXX"
 (call-interactively 'lsp-install-server))

楼上两个朋友的办法都试了,都不行,和我之前设置Emacs代理一样的结果。还是很感谢二位。 我用了手动下载的办法,然后手动解压。用Firefox下载比较稳定。wget老是掉timeout。 因为以前也有Arch AUR包下载用到githubusercontent.com 下载的情况,现在想到,于是也用手动下载到指定目标位置的办法。终于ok了。网络环境不好真是好蛋疼。

Emacs 什么版本的?26.3 或之前的版本有可能是 url.el / gnutls 的问题。

Emacs 28,前几天刚从master branch 编译的。

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赞