@@ 1,77 1,131 @@
-#!/usr/bin/env bash
-core_version="v0.69.0"
-debug_version="0.30.1"
-java_test_version="0.28.1"
+#! /bin/bash
-if ! command -v java &>/dev/null; then echo "java not installed" && exit 1; fi
-if ! command -v git &>/dev/null; then echo "git not installed" && exit 1; fi
+set -o errexit
+set -o nounset
+
+# If the build fails, switching eclipse_core_version to "master" may help.
+# See https://github.com/eclipse/eclipse.jdt.ls/issues/1370
+jdtls_version="v0.69.0"
+java_debug_version="0.30.1"
+java_test_version="0.29.0"
install_only=false
+debug=false
+max_heap_size=1G
+
+usage() {
+ echo "usage: java-language-server [options]
-while [[ $# -ne 0 ]]; do
- case "$1" in
- --install) install_only=true; shift;;
- *) echo "unknown argument: $1" >&2; exit 1;;
- esac
+ --install Install the selected language server, but don't run it
+ --debug Add debug logging; eclipse server only
+ --heap-max Specify the heap max size; eclipse server only"
+ exit 0
+}
+
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ --install) install_only=true; shift;;
+ --debug) debug=true; shift;;
+ --heap-max) max_heap_size="$2"; shift 2;;
+ --help) usage;;
+ *) usage;;
+ esac
done
-home="$(dirname "${BASH_SOURCE[0]}")/language-servers/java"
-mkdir -p "${home}"
+cache_dir="${XDG_CACHE_HOME:-${HOME}/.cache}"
+language_server_home="${cache_dir}/java-language-server"
-core_home="${home}/core"
-debug_home="${home}/debug"
-java_test_home="${home}/java-test"
+language_server_core="${language_server_home}/eclipse.jdt.ls"
+language_server_debug="${language_server_home}/extensions/java-debug"
+language_server_test="${language_server_home}/extensions/java-test"
{
- if [[ ! -d "${core_home}" ]]; then
- echo "$(tput bold)Installing eclipse.jdt.ls version ${core_version}...$(tput sgr0)"
- git -c advice.detachedHead=false clone --depth 1 --single-branch --branch "${core_version}" \
- https://github.com/eclipse/eclipse.jdt.ls.git "${core_home}"
- pushd "${core_home}"
- ./mvnw package
- popd
- fi
-
- if [[ ! -d "${debug_home}" ]]; then
- echo "$(tput bold)Installing debug extension version ${debug_version}...$(tput sgr0)"
- git -c advice.detachedHead=false clone --single-branch --branch "${debug_version}" \
- https://github.com/microsoft/java-debug.git "${debug_home}"
-
- pushd "${debug_home}"
- ./mvnw package
- ln -s "$(pwd)/com.microsoft.java.debug.plugin/target/com.microsoft.java.debug.plugin-"*.jar ../debug.jar
- popd
- fi
-
- if [[ ! -d "${java_test_home}" ]]; then
- echo "$(tput bold)Installing java-test extension version ${java_test_version}...$(tput sgr0)"
- git -c advice.detachedHead=false clone --single-branch --branch "${java_test_version}" \
- https://github.com/microsoft/vscode-java-test.git "${java_test_home}"
- pushd "${java_test_home}/java-extension"
- ./mvnw package
- ln -s "$(pwd)/com.microsoft.java.test.plugin/target/com.microsoft.java.test.plugin-"*.jar ../../java-test.jar
- popd
- fi
-} >&2
-
-if [[ "${install_only}" = true ]]; then
- exit 0
-fi
-
-cd "${core_home}/org.eclipse.jdt.ls.product/target/repository"
-# TODO: add debug parameter?
-exec java \
- -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,quiet=y \
- -Declipse.application=org.eclipse.jdt.ls.core.id1 \
- -Dosgi.bundles.defaultStartLevel=4 \
- -Declipse.product=org.eclipse.jdt.ls.core.product \
- -Dlog.level=ALL \
- -noverify \
- -Xmx1G \
- -jar ./plugins/org.eclipse.equinox.launcher_*.jar \
- -configuration ./config_linux \
- -data "${home}/workspaces" \
- --add-modules=ALL-SYSTEM \
- --add-opens java.base/java.util=ALL-UNNAMED \
- --add-opens java.base/java.lang=ALL-UNNAMED
+ if command -v java >/dev/null; then
+ java=java
+ elif [[ -n "${JAVA_HOME}" ]] && [[ -x "${JAVA_HOME}/bin/java" ]]; then
+ java="${JAVA_HOME}/bin/java"
+ else
+ echo "[java-language-server] java not found"
+ exit 1
+ fi
+
+ java_version="$("${java}" -version 2>&1 | grep ' version ' | awk '{print $3}' | sed 's/"//g')"
+ java_major_version="$(echo "${java_version}" | awk -F. '{print $1}')"
+ java_minor_version="$(echo "${java_version}" | awk -F. '{print $2}')"
+
+ # Require Java 1.11
+ if [[ "${java_major_version}" -eq 1 ]] && [[ "${java_minor_version}" -lt 11 ]]; then
+ echo "[java-language-server] unsupported java version: ${java_version}"
+ exit 2
+ fi
+
+ if [[ "${install_only}" = true ]]; then
+ rm -rf "${language_server_home}"
+ fi
+
+ if [ ! -d "${language_server_core}" ]; then
+ echo 'Installing java-language-server core on first use... (will take a moment)'
+ mkdir -p "$(dirname "${language_server_home}")"
+ git clone --depth=1 --single-branch --branch "${jdtls_version}" \
+ https://github.com/eclipse/eclipse.jdt.ls.git "${language_server_core}"
+ pushd "${language_server_core}"
+ ./mvnw clean package
+ popd
+ fi
+
+ if [[ ! -d "${language_server_debug}" ]]; then
+ echo 'Installing java-debug extension on first use... (will take a moment)'
+ mkdir -p "$(dirname "${language_server_debug}")"
+ git clone --depth=1 --single-branch --branch "${java_debug_version}" \
+ https://github.com/microsoft/java-debug.git "${language_server_debug}"
+ pushd "${language_server_debug}"
+ ./mvnw clean package \
+ && ln -s "${language_server_debug}/com.microsoft.java.debug.plugin/target/com.microsoft.java.debug.plugin-${java_debug_version}.jar" ../debug.jar
+ popd
+ fi
+
+ if [[ ! -d "${language_server_test}" ]]; then
+ echo 'Installing java-test extension on first use... (will take a moment)'
+ mkdir -p "${language_server_test}"
+ pushd "${language_server_test}"
+ wget -O extension.zip "https://vscjava.gallery.vsassets.io/_apis/public/gallery/publisher/vscjava/extension/vscode-java-test/${java_test_version}/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage"
+ unzip extension.zip
+ popd
+ fi
+
+ if [[ "${install_only}" = true ]]; then
+ exit 0
+ fi
+
+ echo "[java-language-server] debug mode: ${debug}"
+ echo "[java-language-server] max heap size: ${max_heap_size}"
+ echo "[java-language-server] using java: ${java}"
+
+ workspace="$(mktemp --directory --tmpdir jdt.ls-workspace-XXXXXXXXXX)"
+ echo "[java-language-server] using workspace: ${workspace}"
+ cleanup() {
+ echo "[java-language-server] cleaning up..."
+ rm -r "${workspace}"
+ }
+ trap cleanup EXIT
+} 1>&2
+
+# 👆 during install redirect stdout to stderr so that this script can be called
+# from language-server-protocol clients and the install process will not be
+# outputted to stdout which clients use as input/responses to requests
+# See https://github.com/eclipse/eclipse.jdt.ls/wiki/Running-the-JAVA-LS-server-from-the-command-line
+"${java}" \
+ -Declipse.application=org.eclipse.jdt.ls.core.id1 \
+ -Dosgi.bundles.defaultStartLevel=4 \
+ -Declipse.product=org.eclipse.jdt.ls.core.product \
+ -Dlog.level=ALL \
+ -Djdt.ls.debug="${debug}" \
+ -noverify \
+ "-Xmx${max_heap_size}" \
+ -jar ${language_server_core}/org.eclipse.jdt.ls.product/target/repository/plugins/org.eclipse.equinox.launcher_*.jar \
+ -configuration "${language_server_core}/org.eclipse.jdt.ls.product/target/repository/config_linux" \
+ -data "${workspace}" \
+ --add-modules=ALL-SYSTEM \
+ --add-opens java.base/java.util=ALL-UNNAMED \
+ --add-opens java.base/java.lang=ALL-UNNAMED