Skip to content
This repository has been archived by the owner on May 4, 2022. It is now read-only.

Commit

Permalink
Add the Java DAP implementation (+LSP uprev)
Browse files Browse the repository at this point in the history
This change bundles a pre-built binary of the Java DAP with
microsoft/java-debug#379 applied, so that we can
specify what port it should bind to.

In order for this to function correctly, it also needs to be running a
more recent version of the Java LSP, so we will upgrade that too.
  • Loading branch information
lhchavez committed Jun 8, 2021
1 parent 0bb3692 commit 1efebdb
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 18 deletions.
117 changes: 117 additions & 0 deletions extra/java-dap
Original file line number Diff line number Diff line change
@@ -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()
2 changes: 2 additions & 0 deletions gen/Dockerfile.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ COPY ./run_dir /run_dir/
RUN ln -sf /usr/lib/chromium-browser/chromedriver /usr/local/bin

COPY ./extra/apt-install /usr/bin/install-pkg
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
Expand Down
2 changes: 1 addition & 1 deletion gen/run-language-server.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions languages/java.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 '<project> <modelVersion>4.0.0</modelVersion> <groupId>mygroupid</groupId> <artifactId>myartifactid</artifactId> <version>0.0-SNAPSHOT</version> <build><plugins> <plugin> <groupId>de.qaware.maven</groupId> <artifactId>go-offline-maven-plugin</artifactId> <version>1.2.5</version> <configuration> <dynamicDependencies> <DynamicDependency> <groupId>org.apache.maven.surefire</groupId> <artifactId>surefire-junit4</artifactId> <version>2.20.1</version> <repositoryType>PLUGIN</repositoryType> </DynamicDependency> <DynamicDependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-apt</artifactId> <version>4.2.1</version> <classifier>jpa</classifier> <repositoryType>MAIN</repositoryType> </DynamicDependency> </dynamicDependencies> </configuration> </plugin> </plugins></build> </project>' > /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"
Expand Down Expand Up @@ -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",
Expand Down
2 changes: 2 additions & 0 deletions out/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,8 @@ COPY ./run_dir /run_dir/
RUN ln -sf /usr/lib/chromium-browser/chromedriver /usr/local/bin

COPY ./extra/apt-install /usr/bin/install-pkg
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
Expand Down
28 changes: 14 additions & 14 deletions out/run-language-server
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -222,7 +222,7 @@ case "$LANGUAGE" in
exit 1
;;
"ruby")
solargraph stdio
exec solargraph stdio
;;
"rust")
echo "No language server configured for rust" >&2
Expand Down
2 changes: 1 addition & 1 deletion out/share/polygott/phase2.d/java
Original file line number Diff line number Diff line change
Expand Up @@ -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 '<project> <modelVersion>4.0.0</modelVersion> <groupId>mygroupid</groupId> <artifactId>myartifactid</artifactId> <version>0.0-SNAPSHOT</version> <build><plugins> <plugin> <groupId>de.qaware.maven</groupId> <artifactId>go-offline-maven-plugin</artifactId> <version>1.2.5</version> <configuration> <dynamicDependencies> <DynamicDependency> <groupId>org.apache.maven.surefire</groupId> <artifactId>surefire-junit4</artifactId> <version>2.20.1</version> <repositoryType>PLUGIN</repositoryType> </DynamicDependency> <DynamicDependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-apt</artifactId> <version>4.2.1</version> <classifier>jpa</classifier> <repositoryType>MAIN</repositoryType> </DynamicDependency> </dynamicDependencies> </configuration> </plugin> </plugins></build> </project>' > /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
Expand Down
Binary file not shown.

0 comments on commit 1efebdb

Please sign in to comment.