Skip to content

Export public API in LightWeight mode #1480

Closed

Description

@jdneo

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, isTestFile and onDidClasspathUpdate will return an empty-like value in LightWeight mode, since so far there is no scenarios shows these APIs need to work in LightWeight mode. (We can change the impelmentation when necessary)
  • In LightWeight mode, all the calls to the command: java.execute.workspaceCommand will just show a warning message in the console and directly return.
  • It's recommended for all the the third-party extensions to consume the serverMode field in the APIs set and change the behavior if it's LightWeightServiceReady.

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
        }));
    }
}

@fbricon @snjeza @akaroml @testforstephen @Eskibear

Activity

  1. jdneo commented on Jun 2, 2020

    @jdneo
    CollaboratorAuthor

    This is the proposed change at client side: jdneo@2052f43

    We 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.

  2. akaroml commented on Jun 2, 2020

    @akaroml
    Contributor

    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.

    {
      serverMode: ServerMode
      willChangeServerMode: Event
      didChangeServerMode: Event
    }
  3. jdneo commented on Jun 2, 2020

    @jdneo
    CollaboratorAuthor

    @akaroml

    this makes the first 2 points in your note section not possible. Please correct me if I miss anything.

    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.)

  4. fbricon commented on Jun 16, 2020

    @fbricon
    Collaborator

    @jdneo can we close this or do you still need to add more stuff?

  5. jdneo commented on Jun 16, 2020

    @jdneo
    CollaboratorAuthor

    How about close this issue and pin it in the issue list?

  6. jdneo commented on Jun 16, 2020

    @jdneo
    CollaboratorAuthor

    @henryju Just FYI, we proposed these new APIs in the Syntax mode. I guess the sonarlint-vscode may need to have some update to adopt the new APIs.

  7. henryju commented on Jun 16, 2020

    @henryju

    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?

  8. jdneo commented on Jun 16, 2020

    @jdneo
    CollaboratorAuthor

    @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.switch to 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.

  9. added this to the Mid June 2020 milestone on Jun 17, 2020
  10. fbricon commented on Jun 17, 2020

    @fbricon
    Collaborator

    Releasing on June 18th, 2020

  11. jblievremont commented on Jul 16, 2020

    @jblievremont

    Hello @jdneo, I started the work on sonarlint-vscode to properly handle LightWeight mode. 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.launchMode require a restart, or at least a reload of the current window. Is there a case when onDidServerModeChange is called without a restart?

  12. jdneo commented on Jul 16, 2020

    @jdneo
    CollaboratorAuthor

    @jblievremont Yes, so far VS Code Java supports switch from LightWeight mode to Standard mode without a restart. User can achieve this by for example, click the 🚀 button in the status bar(when the user is in LightWeight).

  13. jblievremont commented on Jul 16, 2020

    @jblievremont

    Thank you @jdneo, I can indeed see the server switching to Hybrid and then Standard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions