59 строки
5.3 KiB
Markdown
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.
|