Lsp-mode: Add sonarlint language-server

Created on 3 Jun 2020  路  23Comments  路  Source: emacs-lsp/lsp-mode

I was trying to add the sonarlint-language-server, but i don't know exactly how to proceed, reading the atom sonarlint integration (now deprecated) and the source code creates a socket so the LSP can connect to, also there is this post from the sonarlint forum, with the guy explain it.
Any tips or ideas on how to continue?
Thank you :+1:

Most helpful comment

we can connect to tcp server and also we could act as tcp server and let the language server connect to us. check lsp-tcp-server-command and lsp-tcp-connection . The easies way to integrate with server is usually by starting it in vscode and checking what is the server process and then replicate that in emacs.

All 23 comments

we can connect to tcp server and also we could act as tcp server and let the language server connect to us. check lsp-tcp-server-command and lsp-tcp-connection . The easies way to integrate with server is usually by starting it in vscode and checking what is the server process and then replicate that in emacs.

... and if you have more questions don't hesitate to ask.

... and if you have more questions don't hesitate to ask.

Sure I'll give it a try, thanks for the answer :+1:

Ok I manage to "start" the lsp server, this is the code:

(defun lsp-sonarlint-server-start-fun (port)
`("java" " " "/home/username/sonarlint-server.jar " ,(number-to-string port) ))

(lsp-register-client
(make-lsp-client
:new-connection (lsp-tcp-server-command 'lsp-sonarlint-server-start-fun)
:major-modes '(php-mode)
:priority 1
:server-id 'sonarlint
:initialized-fn (lambda (workspace)
(with-lsp-workspace workspace
(lsp--set-configuration
(lsp-configuration-section "sonarlint"))))))

It tries to connect, but fails

LSP :: Waiting for connection for sonarlint, retries: 19
helm-M-x-execute-command: Failed to create connection to sonarlint on port 37755

And the stderr buffer:

Process sonarlint stderr finished
Error: Could not find or load main class
Caused by: java.lang.ClassNotFoundException:

Process sonarlint stderr finished

I tried the lsp server in the vscode file, and the compiled from source version, none of the work same exception.

Any clue?

Thanks!

I suspect that

(defun lsp-sonarlint-server-start-fun (port)
`("java" " " "/home/username/sonarlint-server.jar " ,(number-to-string port) ))

should be

(defun lsp-sonarlint-server-start-fun (port)
`("java" "-jar" "/home/username/sonarlint-server.jar " ,(number-to-string port) ))

Ok it seems like it need some init options:

Jun 03, 2020 6:51:40 PM org.eclipse.lsp4j.jsonrpc.RemoteEndpoint fallbackResponseError

The atom version have this:

getInitializeParams (projectPath, process) {

const config = this.config();
return Object.assign(
  super.getInitializeParams(projectPath, process),
  {
    initializationOptions: {
      testFilePattern: config.testFilePattern,
      analyzerProperties: config.analyzerProperties,
      productKey: 'atom',
      productName: 'SonarLint Atom',
      productVersion: this._version(),
      disableTelemetry: config.disableTelemetry,
      typeScriptLocation: findTypeScriptLocation()
    }
  }
);

}
Probably I have to install atom and check those options and use

:initialization-options (lambda ()
(list :productKey "atom"
:productName "SonarLint Atom")...
But not so sure

yes, that is the right way to pass initialization options.

Hello again, I've been trying to set the correct initialization option without success.
Even copy the Atom options, it gives me a parse error:

[Error - 20:53:25.335] Unable to update configuration
[Error - 20:53:25.338] java.lang.NullPointerException
at org.sonarsource.sonarlint.ls.settings.SettingsManager.parseSettings(SettingsManager.java:199)
at org.sonarsource.sonarlint.ls.settings.SettingsManager.lambda$didChangeConfiguration$1(SettingsManager.java:127)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)

These are the options I'm using:
(lsp-register-client
(make-lsp-client
:new-connection (lsp-tcp-server-command 'lsp-sonarlint-server-start-fun)
:major-modes '(java-mode)
:priority 1
:server-id 'sonarlint
:initialization-options (lambda ()
(list
:productKey "emacs"
:productName "Emacs"
:disableTelemetry t
)
)
:initialized-fn (lambda (workspace)
(with-lsp-workspace workspace
(lsp--set-configuration
(lsp-configuration-section "sonarlint"))))))

And the parse line error is here
Any clue?
Thanks!

The issue is that you are sending empty configuration via

(lsp--set-configuration
(lsp-configuration-section "sonarlint"))

You should use lsp-register-custom-settings and register property "sonarlint.disableTelemetry". There are lot of examples for that in lsp-mode/lsp-java source code.

Hello again, sorry for the delay.
I made it work!
Screenshot from 2020-06-10 11-03-47

At least with almost all the analyser extensions, except for the java one, that doesn't apparently trigger any error, maybe is my java configuration.

The last thing left to do maybe is to configure code actions, like atom does:
sonarlint-atom

Thank you!

The last thing left to do maybe is to configure code actions, like atom does:

I guess this is some kind of protocol extension. AFAIK there is no such feature in core spec.

The last thing left to do maybe is to configure code actions, like atom does:

I guess this is some kind of protocol extension. AFAIK there is no such feature in core spec.

I tried to copy the atom code but without luck
connection.onCustom('sonarlint/openRuleDescription', this.openRuleDescription.bind(this));
Seems like the returned value is just a JSON object.

When I click in the "open description" gives me this message
Jun 10, 2020 8:40:30 PM org.eclipse.lsp4j.jsonrpc.RemoteEndpoint handleCancellation WARNING: Unmatched cancel notification for request id 52

I'm sorry for all the questions, if you think this is unrelated or out the scope, if fine, really thanks!

Hello @yyoncho , these days I've been working on the implementation.
Right now, except for the code actions, is quite usable, and works with all the languages. It still need some development to be "production ready", I'm interested in the possibility to add it to the emacs-lsp family.
Repository url

Thank you!

The last thing left to do maybe is to configure code actions, like atom does:

I guess this is some kind of protocol extension. AFAIK there is no such feature in core spec.

I tried to copy the atom code but without luck
connection.onCustom('sonarlint/openRuleDescription', this.openRuleDescription.bind(this));
Seems like the returned value is just a JSON object.

When I click in the "open description" gives me this message
Jun 10, 2020 8:40:30 PM org.eclipse.lsp4j.jsonrpc.RemoteEndpoint handleCancellation WARNING: Unmatched cancel notification for request id 52

I'm sorry for all the questions, if you think this is unrelated or out the scope, if fine, really thanks!

can you provide a bit more context?

The last thing left to do maybe is to configure code actions, like atom does:

I guess this is some kind of protocol extension. AFAIK there is no such feature in core spec.

I tried to copy the atom code but without luck
connection.onCustom('sonarlint/openRuleDescription', this.openRuleDescription.bind(this));
Seems like the returned value is just a JSON object.
When I click in the "open description" gives me this message
Jun 10, 2020 8:40:30 PM org.eclipse.lsp4j.jsonrpc.RemoteEndpoint handleCancellation WARNING: Unmatched cancel notification for request id 52
I'm sorry for all the questions, if you think this is unrelated or out the scope, if fine, really thanks!

can you provide a bit more context?

Hello again, I made it work! seems like it was the server version, now the code action works and render the html response:
ezgif com-gif-maker(6)

Hello again, I'm currently open a request on Melpa for the repository, right now all the basic functionality works, it even support more languages than some of the official ones, there still some things TODO like the connection with sonarqube, but I think this is out of the scope of this issue.
Again, thank you @yyoncho !

@yyoncho Don't you think it makes sense we create a repository lsp-sonarlint on emacs-lsp?

It is up to the author of the package.

@yyoncho Don't you think it makes sense we create a repository lsp-sonarlint on emacs-lsp?

it have some plug-ins to configure, and the main file may become too large, and in the future i want to connect to an external service.
I think a separate repository is the right option

I can add the repository to the emacs-lsp group, but I don't know if that is possible @yyoncho @ericdallo

If you agree, we can create a repository on emacs-lsp organization and make you admin of the repository, then you can migrate the code from GitLab to that repository, what do you think @Sasanidas?

If you agree, we can create a repository on emacs-lsp organization and make you admin of the repository, then you can migrate the code from GitLab to that repository, what do you think @Sasanidas?

That would be great! :smile:

Sent you the invite to https://github.com/emacs-lsp/lsp-sonarlint

Welcome to emacs-lsp @Sasanidas :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rsuhada picture rsuhada  路  3Comments

michaelpj picture michaelpj  路  4Comments

cprussin picture cprussin  路  3Comments

dennismayr picture dennismayr  路  4Comments

glepnir picture glepnir  路  4Comments