vscode-gradle/ARCHITECTURE.md

59 строки
5.3 KiB
Markdown

# Architecture Overview
This extension contains three major components:
- [A Gradle server](./gradle-server) that runs in the background and provides project & task information, and runs Gradle tasks.
- [A Gradle language server](./gradle-language-server) that provides language features such as code completion and diagnostics for gradle script files.
- [A Gradle project importer](./extension/jdtls.ext/com.microsoft.gradle.bs.importer) that imports Gradle projects detected by the [Gradle Build Server](https://github.com/microsoft/build-server-for-gradle) into the workspace. This importer works with the Language Support for Java extension.
# Gradle Server
<img src="images/gradle-server-architecture.svg" />
The gradle server is a long-running Java process that include three threads: 1. Build Server 2. Task Server 3. Language Server
## Build Server
The Gradle Build Server communicates with the Build Client using the [Build Server Protocol](https://build-server-protocol.github.io/) through named pipes.
Due to Java's limited support for named pipes on Windows, a TypeScript layer named [BspProxy](./extension/src/bs/BspProxy.ts) was introduced. This layer acts as a middleware and it helps by sending messages back and forth and creating a safer named pipe JSON-RPC connection between the Gradle Build Server and the Build Client.
For information about the Build Server itself, visit the [Gradle Build Server](https://github.com/microsoft/build-server-for-gradle).
## Language Server
Language Server provides language features such as code completion and diagnostics for Gradle script files. It communicates with the Language Client using the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) through named pipe.
## Task Server
The task server and client using [gRPC](https://grpc.io/) as the interface between each other. It uses TypeScript (Node.js) on the client and Java on the server. A long running server provides very good performance.
On extension activate, the client starts the Java gRPC server which remains running for the period the extension is activated. The server is packaged with the extension as a fat `.jar` file and is started by Node.js via executables generated by Gradle [CreateStartScripts](https://docs.gradle.org/current/dsl/org.gradle.jvm.application.tasks.CreateStartScripts.html).
[Protocol buffers](https://developers.google.com/protocol-buffers) are used to define the gRPC service & messages. The Java & JavaScript message classes, as well as the client and server interfaces, are generated from the Protobuf files via the `protoc` compiler. TypeScript type definitions are generated from the JavaScript classes.
The Java server uses the [Gradle Tooling Api](https://docs.gradle.org/current/userguide/third_party_integration.html#embedding) to discover projects & tasks, and to run Gradle tasks.
### Discovering Projects & Tasks
Tasks belong to projects and projects are hierarchical, meaning projects can have sub-projects, and any/all projects in the tree can have tasks.
The gRPC server provides a `getBuild` method to provide this hierarchical data structure, and accepts a `projectDir` argument, which the client provides.
A root project (`projectDir`) is defined by having a gradle wrapper script at the root (`gradlew` or `gradlew.bat`). By default the extension will search for wrapper scripts at the root of the workspaces, but you can control this behaviour by setting `gradle.nestedProjects` to allow the extension to discover Gradle projects at other locations.
Once the client has discovered the root projects for all workspaces, it requests project data for each root project via separate gRPC method calls using `getBuild`. Gradle progress and output (`STDERR` & `STDOUT`) are streamed to the client. Once the tasks have been discovered and returned to the client, it builds a single-dimensional list of vscode tasks from the Gradle project tasks. These vscode tasks have definitions that contain all the relevant task & project information.
The extension models the project hierarchical structure using the vscode tree view. The tree view data provider consumes the vscode tasks, and builds a tree of projects & tasks using the information provided in the task definitions.
### Running Tasks
Gradle tasks can be run through either the [Tree View](https://code.visualstudio.com/api/extension-guides/tree-view) or the Command Palette.
Tasks are run via the `runBuild` gRPC method. Similar to getting project data, Gradle progress and output (`STDERR` & `STDOUT`) is streamed to the client. Tasks are run in a custom vscode terminal. The `runBuild` gRPC method accepts a list of arguments which are passed to the `BuildLauncher`.
## The Build System
Gradle is used as the build system for the extension, for both the client and the server. Gradle compiles the Java & Protobuf files and runs the relevant tasks to download & build all the dependencies of the project. The builds should work on Linux/MacOS & Windows.
Getting started on this extension is as simple as `./gradlew build`.
# Gradle Project Importer
The Gradle project importer works as a client of the [Gradle Build Server](https://github.com/microsoft/build-server-for-gradle). The importer communicates with the Gradle build server via Build Server Protocol, and convert the build targets into Java Projects of JDT Language Server.