Repository navigation
Export public API in LightWeight mode #1480
Description
Background
We recently introduced LightWeight mode in VS Code Java. The LightWeight mode is used for those who just want to do some 'easy' work in VS Code, for example: reading the code...
But the users might find that if they take a certain action (i.e. starting a debug session) in LightWeight mode, nothing happens...
Root Cause
In the activate() method of VS Code Java, we will return the public APIs as a promise, which will only be resolved when the Standard language server is ready. That means the promise will never be resolved if VS Code Java is in LightWeight mode. Thus, the extension will be in an inactivated status (You can tell it by triggerring the command Developer: Show Running Extensions). All the third-party extensions which depend on VS Code Java will then, keep waiting.
Proposed change
Also resolve the public API in whatever server mode, besides that, adding the following new API:
{
serverMode: ServerMode
onDidServerModeChange: Event<ServerMode>
}Note:
- The APIs like:
getProjectSettings,getClasspaths,isTestFileandonDidClasspathUpdatewill return an empty-like value inLightWeightmode, since so far there is no scenarios shows these APIs need to work inLightWeightmode. (We can change the impelmentation when necessary) - In
LightWeightmode, all the calls to the command:java.execute.workspaceCommandwill just show a warning message in the console and directly return. - It's recommended for all the the third-party extensions to consume the
serverModefield in the APIs set and change the behavior if it'sLightWeightServiceReady.
How to adopt the new APIs
Check the serverMode when get the resolved extension API, and run properly. For example, you may not want to provide some features when Java Language Server is in lightweight mode.
Also do not forget to register a listener to listen the server mode changing event:
const extension: Extension<any> | undefined = extensions.getExtension('redhat.java');
if (extension && extension.isActive) {
const extensionApi: any = extension.exports;
if (!extensionApi) {
return;
}
if (extensionApi.onDidChangeServerMode) {
const onDidChangeServerMode: Event<string> = extensionApi.onDidChangeServerMode;
context.subscriptions.push(onDidChangeServerMode(async (mode: string) => {
// do something according to current server mode
}));
}
}
Activity
jdneo commentedon Jun 2, 2020
This is the proposed change at client side: jdneo@2052f43We can first do the migration for all the extension in VS Code Java Extension Pack, and notify others, like SonarLint, SpingSTS before we check in the change.
akaroml commentedon Jun 2, 2020
Thanks for the writeup @jdneo.
The goal here is to allow users to have the chance to switch to Full mode to use other features that depend on the full language server (e.g. debugging). Allowing other extensions to also work in Lightweight mode in non-goal at the moment.
Let's start with the use case of debugging. In lightweight mode, when users press F5, the debugger needs to check whether the LS is fully loaded. If no, the debugger needs to hint the users and help them switch to Full mode. Today, nothing would happen when users press F5 because the debugger extension is not activated (because the activate() never resolves in Lightweight mode).
To solve the problem, we need to make sure vscode-java resolves the activate() call, and then other extensions can be activated correctly. Since we cannot resolve activate() twice, we only have one shot to return a set of APIs. So as a side effect, no matter what mode LS is in, they share the same set of APIs. Again, this is non-goal but we have to deal with it. And to @jdneo, this makes the first 2 points in your note section not possible. Please correct me if I miss anything.
To mitigate, the current is to also implement those APIs in Lightweight mode. But the implementation will either return empty values (like LSP4J) or through exceptions.
And on top of the existing APIs, we will need to have these extras to allow extensions to deal with different sever modes.
jdneo commentedon Jun 2, 2020
@akaroml
Ok if it's to make it possible to switch between different mode without restart, then we should contain all the available APIs in the resolved promise and deal with the different modes inside their implementation. (Makes sense to me.)
fbricon commentedon Jun 16, 2020
@jdneo can we close this or do you still need to add more stuff?
jdneo commentedon Jun 16, 2020
How about close this issue and pin it in the issue list?
jdneo commentedon Jun 16, 2020
@henryju Just FYI, we proposed these new APIs in the Syntax mode. I guess the
sonarlint-vscodemay need to have some update to adopt the new APIs.henryju commentedon Jun 16, 2020
Thanks for the notification @jdneo. I will create a task on our side. I guess SonarLint should simply not run on Java files when the LS is in lightweight mode right? I'm a bit worried about the user experience. I'm anticipating users complaining that SonarLint is not reporting any diagnostics. Should we plan to advertise LightWeight mode, or will you take care on your side to make it clear that Java related features will be in a 'degraded' mode?
Do you have any estimation on when this new mode/API will be publicly released?
jdneo commentedon Jun 16, 2020
@henryju Yes, since currently the LightWeight mode does not have the capability to provide the complete classpath information, I think the sonarlint should not run in lightweight mode.
For the UX, I think sonarlint could provide some hint to the users, telling that sonarlint is not working because Java Language Server is in lightweight mode.
Meanwhile, we also provide a command
java.server.mode.switchto switch the server mode. (so far the command can only be used to switch from lightweight to standard once).So in your implementation, for example, you can show a node in the rule explorer, telling user why sonarlint is not working, and user can click that node to switch the Java Language Server to the standard mode by executing that command. Anyway, you can also have your own UX design according to your own needs.
The new API should be in the next release. I guess @fbricon may provide a rough ETA for that.
fbricon commentedon Jun 17, 2020
Releasing on June 18th, 2020
jblievremont commentedon Jul 16, 2020
Hello @jdneo, I started the work on
sonarlint-vscodeto properly handleLightWeightmode. So far so good, we are able to gracefully disable analysis of Java code and notify the user in our extension's output console.As far as I can see, changes to
java.server.launchModerequire a restart, or at least a reload of the current window. Is there a case whenonDidServerModeChangeis called without a restart?jdneo commentedon Jul 16, 2020
@jblievremont Yes, so far VS Code Java supports switch from
LightWeightmode toStandardmode without a restart. User can achieve this by for example, click the 🚀 button in the status bar(when the user is in LightWeight).jblievremont commentedon Jul 16, 2020
Thank you @jdneo, I can indeed see the server switching to
Hybridand thenStandard.