SonarQube for IDE - CORE - Technology SDK

If your question is about SonarLint in the IntelliJ Platform, VS Code, Visual Studio, or Eclipse, please post it in that sub-category.

Otherwise, please provide:

  • Operating system: Mac OS Sequoia 15.3
  • IDE name and flavor/env: Intellij IDEA Ultimate 2024.1.7

And a thorough description of the problem / question:

I’m currently investigating and working on a custom version of the SonarQube for IDE CORE and JetBrains plugin.
My objective is to retrieve the Quality Profiles and Rules from a custom API that works as a proxy between the IDE and the SonarQube Server to obtain metrics and usage information.

From the JetBrains project i can easily obtain the SDKTechnology using the ProjectRootManager but im struggling at finding any kind of option to obtain the project from the Core.

Is there any option using any Git library?

Thanks!

Hey @Felipe_Lucas_Otero :wave:

SLCORE is a project acting as a standalone Java application entirely out of context from the IDE platforms. Its role is to factorize all the common logic used by each implementation of SonarLint on IDEs supported by Sonar (IntelliJ, Eclipse, VS Code, and Visual Studio). This means you cannot directly acquire information about the IntelliJ platform from this project.

However, since SLCORE can communicate via RPC with SonarLint clients (such as SonarLint IntelliJ), you should be able to pass the information you want to it.

A simple flow could be the following.

In SLCORE:

  • Create your service class inside backend > core module
  • Define the endpoint for the RPC communication inside rpc-protocol module

In SonarLint IntelliJ:

  • Call the new endpoint you created by using the new service inside BackendService.kt, and pass the required information (from here, you should have access to the IntelliJ platform information)

You can take an example of the existing methods to understand the flow; it should be very similar to what is already existing.

Let me know if you have further questions!

1 Like

Hello! Thank you very much for the information and sorry for the late response.

One more question about this:

So in order to obtain the information from the JetBrains plugin i need to publish an event and then receive it from the Backend Service?

Im currently watching the org.sonarsource.sonarlint.core.issue.IssueService inside the CORE for learning pourpouses

Thanks!

So in order to obtain the information from the JetBrains plugin i need to publish an event and then receive it from the Backend Service?

Yes, from the RPC service point of view, you need to define your endpoint as @JsonNotification (RPC notification), meaning that it’s a one-way discussion; no return value is expected.

From the client side (IntelliJ), you can call your service method with notifyBackend { }.

Again, I think you can take an example of other methods; it should be pretty standard.

Thank you for the explanation.

One more question, since im modifying and adding files on several sub projects (such as backend-rpc-impl or core-rpc-protocol) is there any easy way to move all generated JARs from SLCORE to a folder to build the folder for “sloop” ?

Thanks!

I’m not sure I understood, but for instance, if I want to build locally, I will do the following.

First, you should be able to build SLCORE with mvn clean install -P dist-no-arch from the root folder (we can also build against specific distributions: dist-no-arch,dist-windows_x64,dist-linux_x64,dist-linux_aarch64,dist-macosx_x64,dist-macosx_aarch64). JARs should be generated for all the modules.

Now, in sonarlint-intellij, you will want to use the artifact you just built before. For this, I usually do the following:

Add mavenLocal() inside build.gradle.kts:

allprojects {
   repositories {
      mavenLocal()
      [...]
   }
}

Then, inside libs.versions.toml, I change the sonarlint-core version to the one built before, for example, sonarlint-core = "10.15-SNAPSHOT".

You can then refresh your project; you should have access to your changes.

1 Like

Sorry for the bad explanation.

I want to replicate how it works today in the JetBrains Plugin.

The “rpc-java-client” and “rpc-impl” JARs are added as a dependency on the “build.gradle.kts” but all the other ones are bundled on the Sloop ZIP.

If i want to upload to a Registry this JARs and ZIP, is there a simple way or should i collect all files individuately?

btw I’ve also noted that “rpc-impl” is present in both dependency and Sloop.

Thanks for the information and the quick answers!

You can dismiss my last reply.

I finally understood what you meant.

It’s a lot easier this way. Thank you very much for help!

Hello Felipe,

There is no easy way to get this information, so I collected it for you :slight_smile:

The Java dependencies you would need for your plugin are:

  • sonarlint-java-client-utils
  • sonarlint-rpc-java-client
  • Transitively, for those 2 you will also need sonarlint-rpc-protocol
  • sonarlint-rpc-impl is not directly needed, but it brings 3 transitive dependencies that are needed today: sonarlint-commons, sonarlint-plugin-api and sonarlint-analysis-engine. Please note that these dependencies should normally soon be removed.

So you will need 6 dependencies (soon only the first 3). On top of that, as you figured out you need the Sloop distribution, built for various architectures if needed.

Out of curiosity, may I ask 2 things:

  • are you building this custom plugin because you lack some kind of feature in SonarQube for IDE or SonarQube Server? If yes, could you explain your need? What kind of statistics are you interested into?
  • why not building a transparent proxy server between SonarQube for IDE and Server using the same API contracts? This way you don’t need a custom plugin but you can intercept the traffic and collect statistics. But maybe I misunderstood your context.

Let us know if you need any more help!

1 Like

Hello!

For this proof of concept im trying to obtain the Project name and technology for the opened project (Using ProjectManager and ProjectRootManager) and dont use the Configured project on “Connected mode” since i think it could be better to obtain the latest Quality Profiles and Rules without accessing the Configuration Panel.

If i can do this and redirect those petitions to a custom API that works as a proxy, i could evaluate the traffic generated by all people using the custom Plugin.

Thanks for the help!

@nicolas.quinquenel I was able to create the following:

– SL CORE: –
Backend - Core: Service that calls the SonarLintRpcClient to ask for information and await the response

Backend - RPC Impl:

Added a new Delegate with the following method:

    @Override
    public CompletableFuture<GetProjectInformationResponse> getProjectInformation() {
        return requestAsync(it -> getBean(ProjectInformationService.class).getProjectInformation());
    }

Client - RPC Java Client: Added the implementation to a method from SonarLintRPCClientImpl that calls the previous delegate

RPC Protocol: Added CompletableFuture method to SonarLintRPCClient

– SL Intellij –
Implemented the method on SonarLintIntellijClient

Main Question: From the SL CORE → How can i interact with this newly created method to the RPC and obtain this information?

I’ve looked through the other services implemented on the backend (files / issues / hotspots) and i can’t understand how the information is sent or requested through RPC since there is no reference to that methods

Thanks for the help and the long reading

@Damien_Urruty Hello, is there any docs that i can use in order to figure how this RPC client works out and is called?

Thanks!

Hi Felipe,

Unfortunately we don’t have any documentation for that. We rely on the LSP4J library, you can find some very basic docs in their documentation folder.

Usually, backend services that need to request something from the client get a SonarLintRpcClient instance via constructor injection. For this to work, the service needs to be registered in the Spring context, in SonarLintSpringAppConfig. A similar use case as yours can be found in this class.

Hope this helps

Thank you very much for your answer. I’ll keep trying and post updates or more questions.

Have a nice weekend!

1 Like

Do not hesitate to ask further questions, @Felipe_Lucas_Otero; it’s always appreciated! Also, if you enjoy using SonarQube for IDE, feel free to leave a review on our marketplace page. Thank you!

@nicolas.quinquenel @Damien_Urruty Thanks to both for your help. I’ve finally been able to send and receive information between SLCORE and JetBrains plugin.

I’ll leave all changes that needs to be made in order to achieve this in case someone comes looking for the same thing in the future.

Backend → Core: SonarLintSpringAppConfig: If you need to add a service to be managed by Spring

RPC Protocol: SonarLintRPCClient: Add method definition

  @JsonRequest
  CompletableFuture<GetProjectInformationResponse> getProjectInformation();

Client → RPC Java Client:

  • SonarLintRPCClientDelegate: Add definition of method that will be implemented on JetBrains plugin
    GetProjectInformationResponse getProjectInformation();

  • SonarLintRPCClientImpl: Async Request to Delegate to obtain the information from Plugin

    @Override
    public CompletableFuture<GetProjectInformationResponse> getProjectInformation() {
        return requestAsync(cancelChecker -> delegate.getProjectInformation());
    }

With all this modifications to SLCORE, whenever you build and import it on SL JetBrains, you will need to implement your new method on SonarLintIntellijClient

Have a nice week.

2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.