2025年1月23日木曜日

emacs に lsp-java をインストールする方法

emacs に lsp-java をインストールする方法

概要

eclipse なしで Java を開発したい場合に lsp-java は必須かなと思います
ポイントは lsp-java とプロジェクトで動作する Java を同一にする点です

環境

  • macOS 15.2
  • emacs 29.4
  • lsp-java 3.1 (20240524.2207)

lsp-java のインストール

package-list-packages から lsp-java を選択してインストールすれば OK です

init.el の設定

; for java lsp with Eclipse JDT Language Server
(require 'lsp-java)
(add-hook 'java-mode-hook #'lsp)

Java のバージョンを指定したい場合は以下のように設定します

(require 'lsp-java)
(add-hook 'java-mode-hook
  (lambda ()
    (setq lsp-java-java-path "/opt/homebrew/Cellar/openjdk@21/21.0.5/libexec/openjdk.jdk/Contents/Home/bin/java")
    (lsp)))

初回起動: Eclipse JDT Language Server のダウンロード

lsp-java 初回起動時は以下のようなメッセージが表示され自動で Eclipse JDT Language Server がインストールされます
エンターを押せば自動でダウンロードされます

Unable to find installed server supporting this file. The following servers could be installed automatically

lsp-install.sh のバッファにダウンロードログが記録されるので確認しましょう

インストールパスは ~/.emacs.d/.cache/lsp/eclipse.jdt.ls/ でサイズが101MBと結構大きいのでディスク容量に注意しましょう

eclipse.jdt.ls % pwd
/Users/user01/.emacs.d/.cache/lsp/eclipse.jdt.ls
eclipse.jdt.ls % du -h -s
101M    .

動作確認

java ファイルを開いて lsp-java が起動することを確認しましょう
lsp-log のバッファにもエラーログがないことを確認します

completion-at-point などでクラス名などを補完したり M-. で jump できることを確認しましょう

トラブルシューティング

いくつかハマリポイントがあったので紹介します

java のパスとバージョンを確認する

lsp-log のバッファに「Unsupported class file major 67」が出ていて lsp-java でジャンプするときに「No definitions found for」など出る場合は lsp-java は起動していて emacs との接続はできているがうまく動作していません

確認する点は以下です

  • emacs を起動しているターミナルに正しい java コマンドが通っているか
  • jenv など使っている場合に zshrc を再度読み込ませているか
  • emacs を起動するパスがプロジェクトのルートパスになっているか
  • lsp-java が使用している java のバージョンが正しいバージョンになっているか (lsp-java-java-path の設定ミス)

あたりを確認していましょう
java のバージョンが 23 になっていたりすると該当のエラーが発生したりします

Gradle Daemon を再起動する

一度どこかのプロジェクトで gradle build しているバックエンドで Gradle Daemon というプロセス (org.gradle.launcher.daemon.bootstrap.GradleDaemon) が起動してしまいます
これが Java23 で動作していると lsp-java の gradle build も Java23 になってしまいます

  • ./gradlew --stop
  • rm -rf ~/.gradle/daemon

一度プロジェクトで gradle daemon を停止しgradle.properties に以下を追記します

org.gradle.java.home=/opt/homebrew/Cellar/openjdk@21/21.0.5/libexec/openjdk.jdk/Contents/Home
  • ./gradlew build

これで gradle daemon が起動する Java も 21 になり lsp-java が参照する Java も 21 になるはずです

それでもダメな場合はシステムで使用する Java を変更しましょう

  • jenv remove 23 23.0 23.0.1 openjdk64-23.0.1
  • sudo rm /Library/Java/JavaVirtualMachines/openjdk-*.jdk
  • sudo ln -sfn /opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk
  • jenv add "$(/usr/libexec/java_home)"

Eclipse JDT Language Server のバージョンを固定する

(setq lsp-java-jdt-download-url "https://www.eclipse.org/downloads/download.php?file=/jdtls/milestones/1.37.0/jdt-language-server-1.37.0-202406271335.tar.gz")
Cannot convert string value 'VERSION_21' to an enum value of type 'org.gradle.api.JavaVersion'

というエラーログが出る場合はバージョンを固定することで解決することもあります

最後に

lsp-java を emacs に導入してみました
Java のバージョンや JDT のバージョンで結構苦戦するところが多かったです

これで eclipse などの IDE なしで java の開発ができそうです

参考サイト

0 件のコメント:

コメントを投稿