diff --git a/extra/java-dap b/extra/java-dap
new file mode 100755
index 00000000..74fae9e0
--- /dev/null
+++ b/extra/java-dap
@@ -0,0 +1,117 @@
+#!/usr/bin/env python3
+"""Small wrapper to correctly initialize the Java DAP."""
+
+import json
+import logging
+import os
+import signal
+import subprocess
+import sys
+import time
+
+from typing import Any, IO, Dict, List, Optional
+
+_JAVA_DAP_BUNDLE = '/run_dir/com.microsoft.java.debug.plugin-0.32.0.jar'
+
+
+def _send_lsp_message(msg: Dict[str, Any], lsp: IO[bytes]) -> None:
+ serialized_msg = json.dumps({
+ 'jsonrpc': '2.0',
+ **msg,
+ })
+ payload = len(serialized_msg)
+ lsp.write((f'Content-Length: {len(serialized_msg)}\r\n\r\n' +
+ serialized_msg).encode('utf-8'))
+ lsp.flush()
+
+
+def _receive_lsp_message(lsp: IO[bytes]) -> Optional[Dict[str, Any]]:
+ headers = b''
+ while not headers.endswith(b'\r\n\r\n'):
+ byte = lsp.read(1)
+ if len(byte) == 0:
+ return None
+ headers += byte
+ content_length = 0
+ for header in headers.strip().split(b'\r\n'):
+ name, value = header.split(b':', maxsplit=2)
+ if name.strip().lower() == b'content-length':
+ content_length = int(value.strip())
+ serialized = b''
+ while content_length:
+ chunk = lsp.read(content_length)
+ if not chunk:
+ raise Exception(f'short read: {serialized!r}')
+ content_length -= len(chunk)
+ serialized += chunk
+ return json.loads(serialized)
+
+
+def _main() -> None:
+ with subprocess.Popen(['/usr/bin/run-language-server', '-l', 'java'],
+ stdout=subprocess.PIPE,
+ stdin=subprocess.PIPE) as dap:
+ try:
+ _send_lsp_message(
+ {
+ 'id': 1,
+ 'method': 'initialize',
+ 'params': {
+ 'processId': None,
+ 'initializationOptions': {
+ 'bundles': [
+ _JAVA_DAP_BUNDLE,
+ ],
+ },
+ 'trace': 'verbose',
+ 'capabilities': {},
+ },
+ }, dap.stdin)
+ # Wait for the initialize message has been acknowledged.
+ # This maximizes the probability of success.
+ while True:
+ message = _receive_lsp_message(dap.stdout)
+ assert message
+ if message.get('method') == 'window/logMessage':
+ print(message.get('params', {}).get('message'),
+ file=sys.stderr)
+ if message.get('id') == 1:
+ break
+ _send_lsp_message(
+ {
+ 'id': 2,
+ 'method': 'workspace/executeCommand',
+ 'params': {
+ 'command': 'vscode.java.startDebugSession',
+ },
+ }, dap.stdin)
+ # Wait for the reply. If the request errored out, exit early to
+ # send a clear signal to the caller.
+ while True:
+ message = _receive_lsp_message(dap.stdout)
+ assert message
+ if message.get('method') == 'window/logMessage':
+ print(message.get('params', {}).get('message'),
+ file=sys.stderr)
+ if message.get('id') == 2:
+ if 'error' in message:
+ print(message['error'].get('message'), file=sys.stderr)
+ return
+ break
+ # Keep reading to drain the queue.
+ while True:
+ message = _receive_lsp_message(dap.stdout)
+ if not message:
+ break
+ if message.get('method') == 'window/logMessage':
+ print(message.get('params', {}).get('message'),
+ file=sys.stderr)
+ except Exception:
+ logging.exception('failed')
+ finally:
+ pgrp = os.getpgid(dap.pid)
+ os.killpg(pgrp, signal.SIGINT)
+
+
+if __name__ == '__main__':
+ _main()
diff --git a/gen/Dockerfile.ejs b/gen/Dockerfile.ejs
index 50c1581d..16e48f99 100644
--- a/gen/Dockerfile.ejs
+++ b/gen/Dockerfile.ejs
@@ -95,6 +95,9 @@ COPY ./run_dir /run_dir/
RUN ln -sf /usr/lib/chromium-browser/chromedriver /usr/local/bin
COPY ./extra/apt-install /usr/bin/install-pkg
+RUN mkdir -p /opt/dap/java/
+COPY ./extra/java-dap /opt/dap/java/run
+RUN chmod +x /opt/dap/java/run
COPY ./extra/_test_runner.py /home/runner/_test_runner.py
COPY ./extra/cquery11 /opt/homes/cpp11/.cquery
diff --git a/gen/run-language-server.ejs b/gen/run-language-server.ejs
index 541e71ec..d1f48071 100644
--- a/gen/run-language-server.ejs
+++ b/gen/run-language-server.ejs
@@ -21,7 +21,7 @@ case "$LANGUAGE" in
<% for ( let lang of languages ) { -%>
<%- lang.names.map(x => `"${x}"`).join('|') %>)
<% if ( lang.languageServer ) { -%>
- <%- c(lang.languageServer.command) %>
+ exec <%- c(lang.languageServer.command) %>
<% } else { -%>
echo "No language server configured for <%= lang.name %>" >&2
exit 1
diff --git a/languages/java.toml b/languages/java.toml
index 651e74a5..56878c80 100644
--- a/languages/java.toml
+++ b/languages/java.toml
@@ -8,7 +8,7 @@ packages = [
"openjdk-11-jdk"
]
setup = [
- "mkdir -p /config/language-server && cd /config/language-server && wget http://download.eclipse.org/jdtls/milestones/0.21.0/jdt-language-server-0.21.0-201806152234.tar.gz && tar -xzf jdt-language-server-0.21.0-201806152234.tar.gz && rm jdt-language-server-0.21.0-201806152234.tar.gz && chown runner:runner -R /config/language-server",
+ "mkdir -p /config/language-server && cd /config/language-server && wget https://download.eclipse.org/jdtls/milestones/1.1.2/jdt-language-server-1.1.2-202105191944.tar.gz && tar -xzf jdt-language-server-1.1.2-202105191944.tar.gz && rm jdt-language-server-1.1.2-202105191944.tar.gz && chown runner:runner -R /config/language-server",
"echo ' 4.0.0 mygroupid myartifactid 0.0-SNAPSHOT de.qaware.maven go-offline-maven-plugin 1.2.5 org.apache.maven.surefire surefire-junit4 2.20.1 PLUGIN com.querydsl querydsl-apt 4.2.1 jpa MAIN ' > /tmp/emptypom.xml",
"mvn -f /tmp/emptypom.xml -Dmaven.repo.local=/home/runner/.m2/repository de.qaware.maven:go-offline-maven-plugin:resolve-dependencies dependency:copy-dependencies",
"rm /tmp/emptypom.xml"
@@ -43,11 +43,12 @@ command = [
"-Declipse.application=org.eclipse.jdt.ls.core.id1",
"-Dosgi.bundles.defaultStartLevel=4",
"-Declipse.product=org.eclipse.jdt.ls.core.product",
+ "-Dcom.microsoft.java.debug.serverAddress=localhost:41010",
"-noverify",
"-Xmx256m",
"-XX:+UseConcMarkSweepGC",
"-jar",
- "/config/language-server/plugins/org.eclipse.equinox.launcher_1.5.0.v20180512-1130.jar",
+ "/config/language-server/plugins/org.eclipse.equinox.launcher_1.6.100.v20201223-0822.jar",
"-configuration",
"/config/language-server/config_linux",
"-data",
diff --git a/out/Dockerfile b/out/Dockerfile
index 742b075f..aa1348fd 100755
--- a/out/Dockerfile
+++ b/out/Dockerfile
@@ -817,6 +817,9 @@ COPY ./run_dir /run_dir/
RUN ln -sf /usr/lib/chromium-browser/chromedriver /usr/local/bin
COPY ./extra/apt-install /usr/bin/install-pkg
+RUN mkdir -p /opt/dap/java/
+COPY ./extra/java-dap /opt/dap/java/run
+RUN chmod +x /opt/dap/java/run
COPY ./extra/_test_runner.py /home/runner/_test_runner.py
COPY ./extra/cquery11 /opt/homes/cpp11/.cquery
diff --git a/out/run-language-server b/out/run-language-server
index 901b5cfa..e117c0b3 100755
--- a/out/run-language-server
+++ b/out/run-language-server
@@ -23,7 +23,7 @@ case "$LANGUAGE" in
exit 1
;;
"java")
- java -Declipse.application=org.eclipse.jdt.ls.core.id1 -Dosgi.bundles.defaultStartLevel=4 -Declipse.product=org.eclipse.jdt.ls.core.product -noverify -Xmx256m -XX:+UseConcMarkSweepGC -jar /config/language-server/plugins/org.eclipse.equinox.launcher_1.5.0.v20180512-1130.jar -configuration /config/language-server/config_linux -data /home/runner
+ exec java -Declipse.application=org.eclipse.jdt.ls.core.id1 -Dosgi.bundles.defaultStartLevel=4 -Declipse.product=org.eclipse.jdt.ls.core.product -Dcom.microsoft.java.debug.serverAddress=localhost:41010 -noverify -Xmx256m -XX:+UseConcMarkSweepGC -jar /config/language-server/plugins/org.eclipse.equinox.launcher_1.6.100.v20201223-0822.jar -configuration /config/language-server/config_linux -data /home/runner
;;
"ballerina")
echo "No language server configured for ballerina" >&2
@@ -34,7 +34,7 @@ case "$LANGUAGE" in
exit 1
;;
"c")
- cquery '--init={"progressReportFrequencyMs": -1,"cacheDirectory":"/tmp/cquery"}'
+ exec cquery '--init={"progressReportFrequencyMs": -1,"cacheDirectory":"/tmp/cquery"}'
;;
"common lisp"|"clisp"|"lisp")
echo "No language server configured for common lisp" >&2
@@ -45,10 +45,10 @@ case "$LANGUAGE" in
exit 1
;;
"cpp"|"c++")
- cquery '--init={"progressReportFrequencyMs": -1,"cacheDirectory":"/tmp/cquery", "extraClangArguments": ["-std=c++17", "-pthread"]}'
+ exec cquery '--init={"progressReportFrequencyMs": -1,"cacheDirectory":"/tmp/cquery", "extraClangArguments": ["-std=c++17", "-pthread"]}'
;;
"cpp11")
- cquery '--init={"progressReportFrequencyMs": -1,"cacheDirectory":"/tmp/cquery", "extraClangArguments": ["-std=c++11", "-pthread"]}'
+ exec cquery '--init={"progressReportFrequencyMs": -1,"cacheDirectory":"/tmp/cquery", "extraClangArguments": ["-std=c++11", "-pthread"]}'
;;
"crystal")
echo "No language server configured for crystal" >&2
@@ -63,10 +63,10 @@ case "$LANGUAGE" in
exit 1
;;
"dart")
- /usr/lib/dart/bin/dart /usr/lib/dart/bin/snapshots/analysis_server.dart.snapshot --lsp
+ exec /usr/lib/dart/bin/dart /usr/lib/dart/bin/snapshots/analysis_server.dart.snapshot --lsp
;;
"deno")
- deno lsp
+ exec deno lsp
;;
"elisp")
echo "No language server configured for elisp" >&2
@@ -93,7 +93,7 @@ case "$LANGUAGE" in
exit 1
;;
"flow")
- flow-language-server --stdio
+ exec flow-language-server --stdio
;;
"forth")
echo "No language server configured for forth" >&2
@@ -112,7 +112,7 @@ case "$LANGUAGE" in
exit 1
;;
"go"|"golang")
- /bin/bash -c /opt/homes/go/go/bin/bingo
+ exec /bin/bash -c /opt/homes/go/go/bin/bingo
;;
"guile"|"scheme")
echo "No language server configured for guile" >&2
@@ -123,7 +123,7 @@ case "$LANGUAGE" in
exit 1
;;
"haxe")
- haxe --server-listen stdio
+ exec haxe --server-listen stdio
;;
"jest")
echo "No language server configured for jest" >&2
@@ -186,16 +186,16 @@ case "$LANGUAGE" in
exit 1
;;
"python3")
- pyls -v
+ exec pyls -v
;;
"pygame")
- pyls -v
+ exec pyls -v
;;
"python")
- pyls -v
+ exec pyls -v
;;
"pyxel")
- pyls -v
+ exec pyls -v
;;
"quil")
echo "No language server configured for quil" >&2
@@ -222,7 +222,7 @@ case "$LANGUAGE" in
exit 1
;;
"ruby")
- solargraph stdio
+ exec solargraph stdio
;;
"rust")
echo "No language server configured for rust" >&2
diff --git a/out/share/polygott/phase2.d/java b/out/share/polygott/phase2.d/java
index be12bb8a..7a92ecab 100755
--- a/out/share/polygott/phase2.d/java
+++ b/out/share/polygott/phase2.d/java
@@ -10,7 +10,7 @@ chown -R $(id -u):$(id -g) /home/runner
echo 'Setup java'
cd "${HOME}"
-mkdir -p /config/language-server && cd /config/language-server && wget http://download.eclipse.org/jdtls/milestones/0.21.0/jdt-language-server-0.21.0-201806152234.tar.gz && tar -xzf jdt-language-server-0.21.0-201806152234.tar.gz && rm jdt-language-server-0.21.0-201806152234.tar.gz && chown runner:runner -R /config/language-server
+mkdir -p /config/language-server && cd /config/language-server && wget https://download.eclipse.org/jdtls/milestones/1.1.2/jdt-language-server-1.1.2-202105191944.tar.gz && tar -xzf jdt-language-server-1.1.2-202105191944.tar.gz && rm jdt-language-server-1.1.2-202105191944.tar.gz && chown runner:runner -R /config/language-server
echo ' 4.0.0 mygroupid myartifactid 0.0-SNAPSHOT de.qaware.maven go-offline-maven-plugin 1.2.5 org.apache.maven.surefire surefire-junit4 2.20.1 PLUGIN com.querydsl querydsl-apt 4.2.1 jpa MAIN ' > /tmp/emptypom.xml
mvn -f /tmp/emptypom.xml -Dmaven.repo.local=/home/runner/.m2/repository de.qaware.maven:go-offline-maven-plugin:resolve-dependencies dependency:copy-dependencies
rm /tmp/emptypom.xml
diff --git a/run_dir/com.microsoft.java.debug.plugin-0.32.0.jar b/run_dir/com.microsoft.java.debug.plugin-0.32.0.jar
new file mode 100644
index 00000000..44436186
Binary files /dev/null and b/run_dir/com.microsoft.java.debug.plugin-0.32.0.jar differ