SublimeDebugger
SublimeDebugger copied to clipboard
Java adapter
Connection to the debugger works. But I am getting a "missing mainClass..." error.
Connection to the debugger works. But I am getting a "missing mainClass..." error.
Thats fixed by supplying:
"mainClass": "${file}",
"modulePaths": ["${folder}"]
Now the Debugger fails with:
jdtls: 08.03.2021, 15:28:47 [error response][launch]: Failed to launch debuggee in terminal. Reason: Failed to launch debuggee in terminal. Reason: java.util.concurrent.TimeoutException: timeout
Failed to launch debuggee in terminal. Reason: Failed to launch debuggee in terminal. Reason: java.util.concurrent.TimeoutException: timeout
com.microsoft.java.debug.core.DebugException: Failed to launch debuggee in terminal. Reason: Failed to launch debuggee in terminal. Reason: java.util.concurrent.TimeoutException: timeout
at com.microsoft.java.debug.core.adapter.handler.LaunchWithDebuggingDelegate.lambda$launchInTerminal$0(LaunchWithDebuggingDelegate.java:157)
at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:859)
at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:837)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506)
at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2152)
at com.microsoft.java.debug.core.protocol.AbstractProtocolServer$1.run(AbstractProtocolServer.java:192)
at java.base/java.util.TimerThread.mainLoop(Timer.java:556)
at java.base/java.util.TimerThread.run(Timer.java:506)
Debugger does not reply to runInTerminal. Is this a known issue? (I am running Windows 10, ST 4098)
Okey, I found the comment in terminal_process.py. Seems like ST4 does not support runInTerminal?
Okey, I found the comment in
terminal_process.py. Seems like ST4 does not support runInTerminal?
It relies on winpty and dependencies don't work on the 3.8 environment
Okey, I found the comment in
terminal_process.py. Seems like ST4 does not support runInTerminal?
@LDAP for now you can probably change your configuration to not use the integrated terminal.
"console": "internalConsole"
"console": "internalConsole"
In this case the Server errors with:
jdtls: 08.03.2021, 23:12:44 Error parsing message: com.google.gson.JsonSyntaxException: Expected a com.google.gson.JsonObject but was com.google.gson.JsonNull
Expected a com.google.gson.JsonObject but was com.google.gson.JsonNull
com.google.gson.JsonSyntaxException: Expected a com.google.gson.JsonObject but was com.google.gson.JsonNull
at com.google.gson.internal.bind.TypeAdapters$35$1.read(TypeAdapters.java:897)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:131)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:222)
at com.google.gson.Gson.fromJson(Gson.java:932)
at com.google.gson.Gson.fromJson(Gson.java:897)
at com.google.gson.Gson.fromJson(Gson.java:846)
at com.google.gson.Gson.fromJson(Gson.java:817)
at com.microsoft.java.debug.core.protocol.JsonUtils.fromJson(JsonUtils.java:26)
at com.microsoft.java.debug.core.protocol.AbstractProtocolServer.processData(AbstractProtocolServer.java:219)
at com.microsoft.java.debug.core.protocol.AbstractProtocolServer.run(AbstractProtocolServer.java:98)
at com.microsoft.java.debug.core.adapter.ProtocolServer.run(ProtocolServer.java:61)
at com.microsoft.java.debug.plugin.internal.JavaDebugServer$2.run(JavaDebugServer.java:136)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at java.base/java.lang.Thread.run(Thread.java:832)
jdtls: 08.03.2021, 23:12:44 Error parsing message: com.google.gson.JsonSyntaxException: Expected a com.google.gson.JsonObject but was com.google.gson.JsonNull
Expected a com.google.gson.JsonObject but was com.google.gson.JsonNull
com.google.gson.JsonSyntaxException: Expected a com.google.gson.JsonObject but was com.google.gson.JsonNull
at com.google.gson.internal.bind.TypeAdapters$35$1.read(TypeAdapters.java:897)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:131)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:222)
at com.google.gson.Gson.fromJson(Gson.java:932)
at com.google.gson.Gson.fromJson(Gson.java:897)
at com.google.gson.Gson.fromJson(Gson.java:846)
at com.google.gson.Gson.fromJson(Gson.java:817)
at com.microsoft.java.debug.core.protocol.JsonUtils.fromJson(JsonUtils.java:26)
at com.microsoft.java.debug.core.protocol.AbstractProtocolServer.processData(AbstractProtocolServer.java:219)
at com.microsoft.java.debug.core.protocol.AbstractProtocolServer.run(AbstractProtocolServer.java:98)
at com.microsoft.java.debug.core.adapter.ProtocolServer.run(ProtocolServer.java:61)
at com.microsoft.java.debug.plugin.internal.JavaDebugServer$2.run(JavaDebugServer.java:136)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at java.base/java.lang.Thread.run(Thread.java:832)
What request is this failing on? If its the initialize request its likely there are additional required parameters in the configuration that get patched in.
https://github.com/microsoft/java-debug/blob/64d42435b9913ad39f49f8700e0c046abdc12dd5/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Requests.java#L103
I would try adding "env":{}
What request is this failing on? If its the initialize request its likely there are additional required parameters in the configuration that get patched in.
https://github.com/microsoft/java-debug/blob/64d42435b9913ad39f49f8700e0c046abdc12dd5/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Requests.java#L103
I would try adding
"env":{}
Still erroring,
this is the Debugger Protocol:
⟸ process/started
⟸ request/initialize(1) :: {'clientID': 'sublime', 'clientName': 'Sublime Text', 'adapterID': 'java', 'pathFormat': 'path', 'linesStartAt1': True, 'columnsStartAt1': True, 'supportsVariableType': True, 'supportsVariablePaging': False, 'supportsRunInTerminalRequest': True, 'locale': 'en-us'}
⟹ response/initialize(1) :: {'supportsConfigurationDoneRequest': True, 'supportsHitConditionalBreakpoints': True, 'supportsConditionalBreakpoints': True, 'supportsEvaluateForHovers': True, 'supportsCompletionsRequest': True, 'supportsRestartFrame': True, 'supportsSetVariable': True, 'supportsRestartRequest': False, 'supportTerminateDebuggee': True, 'supportsDelayedStackTraceLoading': False, 'supportsLogPoints': True, 'supportsExceptionInfoRequest': True, 'exceptionBreakpointFilters': [{'label': 'Uncaught Exceptions', 'filter': 'uncaught'}, {'label': 'Caught Exceptions', 'filter': 'caught'}], 'supportsDataBreakpoints': True, 'supportsClipboardContext': True}
⟸ request/launch(2) :: {'console': 'internalConsole', 'cwd': 'D:\\Local_Repositories\\Development\\Java\\Projects\\TimeSheetGenerator', 'env': {}, 'mainClass': 'D:\\Local_Repositories\\Development\\Java\\Projects\\TimeSheetGenerator\\src\\main\\java\\main\\Main.java', 'modulePaths': ['D:\\Local_Repositories\\Development\\Java\\Projects\\TimeSheetGenerator'], 'name': 'Launch Current File', 'request': 'launch', 'stopOnEntry': False, 'type': 'java'}
⟹ event/initialized :: {'type': 'initialized'}
⟸ request/setDataBreakpoints(3) :: {'breakpoints': []}
⟸ request/setExceptionBreakpoints(4) :: {'filters': [], 'filterOptions': []}
⟸ request/setBreakpoints(5) :: {'source': {'path': 'D:\\Local_Repositories\\Development\\Java\\Projects\\TimeSheetGenerator\\src\\main\\java\\main\\Main.java'}, 'breakpoints': [{'line': 29}]}
⟹ response/launch(2) :: None
⟸ request/threads(6) :: None
⟹ response/setDataBreakpoints(3) :: {'breakpoints': []}
⟹ response/setExceptionBreakpoints(4) :: None
⟹ response/setBreakpoints(5) :: {'breakpoints': [{'id': 1, 'verified': False, 'line': 29, 'message': ''}]}
⟸ request/configurationDone(7) :: None
Config:
{
"type": "java",
"name": "Launch Current File",
"request": "launch",
"mainClass": "${file}",
"modulePaths": ["${folder}"],
"cwd": "${folder}",
"console": "internalConsole",
"env": {},
"stopOnEntry": false
},
Looks to be way past the initialize request. From the looks of it they are just not handling the configurationDone request correctly and treating the arguments as none optional.
https://github.com/daveleroy/sublime_debugger/blob/2b5f0a5860027a0f2ad9b9fcd791b41a3179da57/modules/dap/session.py#L672
Try changing await self.request('configurationDone', None) to await self.request('configurationDone', {})
Looks to be way past the initialize request. From the looks of it they are just not handling the configurationDone request correctly and treating the arguments as none optional.
https://github.com/daveleroy/sublime_debugger/blob/2b5f0a5860027a0f2ad9b9fcd791b41a3179da57/modules/dap/session.py#L672
Try changing
await self.request('configurationDone', None)toawait self.request('configurationDone', {})
That did the trick. Now the command gets executed, but fails too...
It's working now. Although I am still getting
Error parsing message: com.google.gson.JsonSyntaxException: Expected a com.google.gson.JsonObject but was com.google.gson.JsonNull
Settings:
{
"type": "java",
"name": "Launch",
"request": "launch",
"mainClass": "main.Main",
"classPaths": ["${folder}/target/classes", "${folder}/target/lib/*"],
"cwd": "${folder}",
"console": "internalConsole",
},
(Its a Maven Project)
Fixed that too. Since I changed the Protocol to {} instead of None, this may break other things?
@daveleroy How would an adapter add/set configuration variables? I would like to fetch classpath, mainclass,... with the Language Server because for example classpath can get very complicated on a big maven Project.
Fixed that too. Since I changed the Protocol to
{}instead ofNone, this may break other things?
Unlikely to break anything and is probably what vscode does despite the threads request not having any arguments specified in the spec https://microsoft.github.io/debug-adapter-protocol/specification
@daveleroy How would an adapter add/set configuration variables? I would like to fetch classpath, mainclass,... with the Language Server because for example classpath can get very complicated on a big maven Project.
You can adjust a configuration after the variables are expanded but before it is sent to the adapter using async def configuration_resolve(self, configuration). See https://github.com/daveleroy/sublime_debugger/blob/2b5f0a5860027a0f2ad9b9fcd791b41a3179da57/modules/adapters/go.py#L29
If you are talking about adding custom variables that can't currently be done and would need support added for it
@daveleroy How would an adapter add/set configuration variables? I would like to fetch classpath, mainclass,... with the Language Server because for example classpath can get very complicated on a big maven Project.
You can adjust a configuration after the variables are expanded but before it is sent to the adapter using
async def configuration_resolve(self, configuration). Seehttps://github.com/daveleroy/sublime_debugger/blob/2b5f0a5860027a0f2ad9b9fcd791b41a3179da57/modules/adapters/go.py#L29
That should work :)
Implemented auto-configuration of mainClass and classPaths allowing for a plug & play solution together with sublimelsp/LSP-jdtls#7
@daveleroy I get errors in the client. Error:
<Future pending cb=[<TaskWakeupMethWrapper object at 0x000001C9BE368340>()]>
Debugger: error: adapter failed hover evaluation Evaluation failed because the thread is not suspended.
<Future pending cb=[<TaskWakeupMethWrapper object at 0x000001C9BE39DA90>()]>
Traceback (most recent call last):
File "C:\Users\Lucas Alber\AppData\Roaming\Sublime Text 3\Packages\Debugger\modules\core\sublime_event_loop.py", line 105, in call_exception_handler
raise context['exception']
File "C:\Users\Lucas Alber\AppData\Roaming\Sublime Text 3\Packages\Debugger\modules\dap\session.py", line 739, in refresh_threads
threads = array_from_json(dap.Thread.from_json, response['threads'])
KeyError: 'threads'
Protocol:
⟸ process/started
⟸ request/initialize(1) :: {'clientID': 'sublime', 'clientName': 'Sublime Text', 'adapterID': 'java', 'pathFormat': 'path', 'linesStartAt1': True, 'columnsStartAt1': True, 'supportsVariableType': True, 'supportsVariablePaging': False, 'supportsRunInTerminalRequest': True, 'locale': 'en-us'}
⟹ response/initialize(1) :: {'supportsConfigurationDoneRequest': True, 'supportsHitConditionalBreakpoints': True, 'supportsConditionalBreakpoints': True, 'supportsEvaluateForHovers': True, 'supportsCompletionsRequest': True, 'supportsRestartFrame': True, 'supportsSetVariable': True, 'supportsRestartRequest': False, 'supportTerminateDebuggee': True, 'supportsDelayedStackTraceLoading': False, 'supportsLogPoints': True, 'supportsExceptionInfoRequest': True, 'exceptionBreakpointFilters': [{'label': 'Uncaught Exceptions', 'filter': 'uncaught'}, {'label': 'Caught Exceptions', 'filter': 'caught'}], 'supportsDataBreakpoints': True, 'supportsClipboardContext': True}
⟸ request/launch(2) :: {'mainClass': 'org.lalber.tools.checkstyle.Main', 'name': 'Launch Java Program', 'request': 'launch', 'type': 'java', 'cwd': 'D:\\Local_Repositories\\Development\\Java\\Projects\\checkstylecompatibilitytest', 'classPaths': ['D:\\Local_Repositories\\Development\\Java\\Projects\\checkstylecompatibilitytest\\target\\classes', 'C:\\Users\\Lucas Alber\\.m2\\repository\\commons-io\\commons-io\\2.6\\commons-io-2.6.jar', 'C:\\Users\\Lucas Alber\\.m2\\repository\\org\\fusesource\\jansi\\jansi\\1.18\\jansi-1.18.jar', 'C:\\Users\\Lucas Alber\\.m2\\repository\\org\\antlr\\antlr4-runtime\\4.7.2\\antlr4-runtime-4.7.2.jar', 'C:\\Users\\Lucas Alber\\.m2\\repository\\net\\sf\\saxon\\Saxon-HE\\9.9.1-5\\Saxon-HE-9.9.1-5.jar', 'C:\\Users\\Lucas Alber\\.m2\\repository\\info\\picocli\\picocli\\4.1.1\\picocli-4.1.1.jar', 'C:\\Users\\Lucas Alber\\.m2\\repository\\commons-beanutils\\commons-beanutils\\1.9.4\\commons-beanutils-1.9.4.jar', 'C:\\Users\\Lucas Alber\\.m2\\repository\\commons-logging\\commons-logging\\1.2\\commons-logging-1.2.jar', 'C:\\Users\\Lucas Alber\\.m2\\repository\\commons-collections\\commons-collections\\3.2.2\\commons-collections-3.2.2.jar', 'C:\\Users\\Lucas Alber\\.m2\\repository\\com\\google\\guava\\guava\\28.1-jre\\guava-28.1-jre.jar', 'C:\\Users\\Lucas Alber\\.m2\\repository\\com\\google\\guava\\failureaccess\\1.0.1\\failureaccess-1.0.1.jar', 'C:\\Users\\Lucas Alber\\.m2\\repository\\com\\google\\guava\\listenablefuture\\9999.0-empty-to-avoid-conflict-with-guava\\listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar', 'C:\\Users\\Lucas Alber\\.m2\\repository\\com\\google\\code\\findbugs\\jsr305\\3.0.2\\jsr305-3.0.2.jar', 'C:\\Users\\Lucas Alber\\.m2\\repository\\org\\checkerframework\\checker-qual\\2.8.1\\checker-qual-2.8.1.jar', 'C:\\Users\\Lucas Alber\\.m2\\repository\\com\\google\\errorprone\\error_prone_annotations\\2.3.2\\error_prone_annotations-2.3.2.jar', 'C:\\Users\\Lucas Alber\\.m2\\repository\\com\\google\\j2objc\\j2objc-annotations\\1.3\\j2objc-annotations-1.3.jar', 'C:\\Users\\Lucas Alber\\.m2\\repository\\org\\codehaus\\mojo\\animal-sniffer-annotations\\1.18\\animal-sniffer-annotations-1.18.jar', 'C:\\Users\\Lucas Alber\\.m2\\repository\\antlr\\antlr\\2.7.7\\antlr-2.7.7.jar', 'C:\\Users\\Lucas Alber\\.m2\\repository\\org\\apache\\commons\\commons-lang3\\3.9\\commons-lang3-3.9.jar'], 'console': 'internalConsole'}
⟹ event/initialized :: {'type': 'initialized'}
⟹ response/launch(2) :: None
⟸ request/threads(3) :: {}
⟸ request/setBreakpoints(4) :: {'source': {'path': 'D:\\Local_Repositories\\Development\\Java\\Projects\\checkstylecompatibilitytest\\src\\main\\java\\org\\lalber\\tools\\checkstyle\\Main.java'}, 'breakpoints': [{'line': 40}]}
⟸ request/setExceptionBreakpoints(5) :: {'filters': [], 'filterOptions': []}
⟸ request/setDataBreakpoints(6) :: {'breakpoints': []}
⟹ response/threads(3) :: {'threads': [{'id': 1, 'name': 'Thread [main]'}, {'id': 2, 'name': 'Thread [Reference Handler]'}, {'id': 3, 'name': 'Thread [Finalizer]'}, {'id': 4, 'name': 'Thread [Signal Dispatcher]'}, {'id': 5, 'name': 'Thread [Attach Listener]'}]}
⟹ response/setBreakpoints(4) :: {'breakpoints': [{'id': 1, 'verified': True, 'line': 40, 'message': ''}]}
⟹ response/setExceptionBreakpoints(5) :: None
⟹ response/setDataBreakpoints(6) :: {'breakpoints': []}
⟸ request/configurationDone(7) :: {}
⟹ response/configurationDone(7) :: None
⟹ event/thread :: {'reason': 'started', 'threadId': 6, 'type': 'thread'}
⟹ event/thread :: {'reason': 'started', 'threadId': 1, 'type': 'thread'}
⟸ request/threads(8) :: {}
⟸ request/threads(9) :: {}
⟹ event/thread :: {'reason': 'started', 'threadId': 7, 'type': 'thread'}
⟸ request/threads(10) :: {}
⟹ response/threads(8) :: {'threads': [{'id': 1, 'name': 'Thread [main]'}, {'id': 2, 'name': 'Thread [Reference Handler]'}, {'id': 3, 'name': 'Thread [Finalizer]'}, {'id': 4, 'name': 'Thread [Signal Dispatcher]'}, {'id': 5, 'name': 'Thread [Attach Listener]'}, {'id': 6, 'name': 'Thread [Notification Thread]'}, {'id': 7, 'name': 'Thread [Common-Cleaner]'}]}
⟹ event/breakpoint :: {'reason': 'new', 'breakpoint': {'id': 1, 'verified': True, 'line': 40, 'message': ''}, 'type': 'breakpoint'}
⟹ response/threads(9) :: {'threads': [{'id': 1, 'name': 'Thread [main]'}, {'id': 2, 'name': 'Thread [Reference Handler]'}, {'id': 3, 'name': 'Thread [Finalizer]'}, {'id': 4, 'name': 'Thread [Signal Dispatcher]'}, {'id': 5, 'name': 'Thread [Attach Listener]'}, {'id': 6, 'name': 'Thread [Notification Thread]'}, {'id': 7, 'name': 'Thread [Common-Cleaner]'}]}
⟹ response/threads(10) :: {'threads': [{'id': 1, 'name': 'Thread [main]'}, {'id': 2, 'name': 'Thread [Reference Handler]'}, {'id': 3, 'name': 'Thread [Finalizer]'}, {'id': 4, 'name': 'Thread [Signal Dispatcher]'}, {'id': 5, 'name': 'Thread [Attach Listener]'}, {'id': 6, 'name': 'Thread [Notification Thread]'}, {'id': 7, 'name': 'Thread [Common-Cleaner]'}]}
⟹ event/stopped :: {'threadId': 1, 'reason': 'breakpoint', 'allThreadsStopped': False, 'type': 'stopped'}
⟹ event/output :: {'category': 'stdout', 'output': 'Checkstyle-Kompatibilitätstest, null', 'variablesReference': 0, 'line': 0, 'column': 0, 'type': 'output'}
⟹ event/output :: {'category': 'stdout', 'output': '.\r\n', 'variablesReference': 0, 'line': 0, 'column': 0, 'type': 'output'}
⟸ request/threads(11) :: {}
⟸ request/stackTrace(12) :: {'threadId': 1}
⟹ response/threads(11) :: {'threads': [{'id': 1, 'name': 'Thread [main]'}, {'id': 2, 'name': 'Thread [Reference Handler]'}, {'id': 3, 'name': 'Thread [Finalizer]'}, {'id': 4, 'name': 'Thread [Signal Dispatcher]'}, {'id': 5, 'name': 'Thread [Attach Listener]'}, {'id': 6, 'name': 'Thread [Notification Thread]'}, {'id': 7, 'name': 'Thread [Common-Cleaner]'}]}
⟹ response/stackTrace(12) :: {'stackFrames': [{'id': 1, 'source': {'name': 'Main.java', 'path': 'D:\\Local_Repositories\\Development\\Java\\Projects\\checkstylecompatibilitytest\\src\\main\\java\\org\\lalber\\tools\\checkstyle\\Main.java', 'sourceReference': 0}, 'line': 40, 'column': 1, 'name': 'Main.main(String[])'}], 'totalFrames': 1}
⟸ request/scopes(13) :: {'frameId': 1}
⟹ response/scopes(13) :: {'scopes': [{'name': 'Local', 'variablesReference': 2, 'expensive': False}]}
⟸ request/variables(14) :: {'variablesReference': 2}
⟹ response/variables(14) :: {'variables': [{'name': 'args', 'value': 'String[0]@9', 'type': 'String[]', 'variablesReference': 0, 'namedVariables': 0, 'indexedVariables': 0, 'evaluateName': 'args'}]}
⟸ request/next(15) :: {'threadId': 1}
@daveleroy The Java Language Server returns URIs like:
jdt://contents/java.base/java.lang/Integer.class?=jdt.ls-java-project/D:%5C/Local_Repositories%5C/windows-dev-tools%5C/bins%5C/jdk%5C/lib%5C/jrt-fs.jar%60java.base=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/en%5C/java%5C/javase%5C/15%5C/docs%5C/api%5C/=/%3Cjava.lang(Integer.class
leading to an empty view. JDT.LS can actually provide the contents of the class file, does Debugger support that the server resolves the content itself?
@daveleroy I get errors in the client.
This looks like another off spec thing. They are returning {} from the threads command when the response is supposed to be {'threads': [...]} and is not optional.
You can change threads = array_from_json(dap.Thread.from_json, response['threads']) to threads = array_from_json(dap.Thread.from_json, response.get('threads', [])) to handle their malformed response
@daveleroy The Java Language Server returns URIs like:
jdt://contents/java.base/java.lang/Integer.class?=jdt.ls-java-project/D:%5C/Local_Repositories%5C/windows-dev-tools%5C/bins%5C/jdk%5C/lib%5C/jrt-fs.jar%60java.base=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/en%5C/java%5C/javase%5C/15%5C/docs%5C/api%5C/=/%3Cjava.lang(Integer.classleading to an empty view. JDT.LS can actually provide the contents of the class file, does Debugger support that the server resolves the content itself?
This seems like something they should probably change on their side. If the adapter is supposed to supply the contents of a source they should be adding a sourceReference not giving us a URI so that we can perform a SourceRequest for the contents.
https://microsoft.github.io/debug-adapter-protocol/specification#Types_Source
If they are not going to do that then we probably need to add an additional configuration function that lets you optionally return the contents of a path before we assume it should be opened in a view. That way the java adapter can ask jdt.ls for the contents.
Ideally would be something like this sublimehq/sublime_text#3989. But yes until that is ready asking the LS for content is probably the easiest option.
Ideally would be something like this sublimehq/sublime_text#3989. But yes until that is ready asking the LS for content is probably the easiest option.
Ideally java-debug would fix this because what they are doing does not conform to the protocol and makes integrating their adapter pretty convoluted. This issue appears to have been brought up already https://github.com/microsoft/java-debug/issues/259#issuecomment-695199086
With version 1.5 of LSP, plugins can now define an on_open_uri_async callback.
https://github.com/sublimelsp/LSP/blob/97e138e8e3300e52140569f3ada95e05d5b8d9bc/plugin/core/sessions.py#L603-L614
The LSP-jdtls helper package can override this method and define what to do with jdt: schemes.
I guess we would still need a window command like lsp_open_uri that takes an URI and optionally a config name.
@daveleroy does sublime_debugger expect anything special of a sublime View in particular to be able to attach to it or recognize it? the way this view with "virtual content" is made is:
https://github.com/sublimelsp/LSP/blob/97e138e8e3300e52140569f3ada95e05d5b8d9bc/plugin/core/sessions.py#L1106-L1113
With version 1.5 of LSP, plugins can now define an on_open_uri_async callback.
https://github.com/sublimelsp/LSP/blob/97e138e8e3300e52140569f3ada95e05d5b8d9bc/plugin/core/sessions.py#L603-L614
The LSP-jdtls helper package can override this method and define what to do with
jdt:schemes.I guess we would still need a window command like
lsp_open_urithat takes an URI and optionally a config name.
Nice! I'll look into this next week
@daveleroy does sublime_debugger expect anything special of a sublime View in particular to be able to attach to it or recognize it? the way this view with "virtual content" is made is:
https://github.com/sublimelsp/LSP/blob/97e138e8e3300e52140569f3ada95e05d5b8d9bc/plugin/core/sessions.py#L1106-L1113
Not really no but currently breakpoints aren't supported in views that are not associated with a file (this includes generated views from the dap protocol which is probably an oversight).
This is where dap views are generated (when a source is not associated with an actual file) https://github.com/daveleroy/sublime_debugger/blob/ce44c963ac746e4ee1fc3b4fae66a7ba060a9a65/modules/source_navigation.py#L98
If breakpoints are supposed allowed in these views the view probably needs to have a uri setting or some way to check if a view is associated with a uri. It also seems like open_uri should return the generated view so that anyone who calls it can wait on the promise to resolve to get the view.
Somewhat Related: All the LSP packages seem to access the LSP api directly. I wonder if it makes sense to have debugger be the one that creates the 3.3 python bridge to interact with LSP/LSP-jdtls and add any command shims for LSP api's it needs to interact with (until/if LSP switches over to 3.8).
until/if LSP switches over to 3.8
We're blocked on dependencies: https://github.com/sublimelsp/LSP/issues/1389 https://github.com/wbond/package_control/issues/1518
I've enabled LSP-jdtls to understand jdt: URI schemes. But the actual opening of the URI should be done from the DAP side. See: https://github.com/sublimelsp/LSP-jdtls/pull/15#issuecomment-900191073
The jar you are looking for is available at https://mvnrepository.com/artifact/com.microsoft.java/com.microsoft.java.debug.plugin and is exactly the same VSCode use to debug Java applications.
