Skip to content

Commit fdb9c10

Browse files
dkwon17angelozerr
authored andcommitted
Update contributing guide
Signed-off-by: David Kwon <dakwon@redhat.com>
1 parent 0d53754 commit fdb9c10

File tree

5 files changed

+138
-73
lines changed

5 files changed

+138
-73
lines changed

CONTRIBUTING.md

Lines changed: 138 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -5,70 +5,118 @@ If you have any questions or suggestions we are happy to hear them.
55

66
## Project Structure
77
For vscode-quarkus to work, it relies on the
8-
[Quarkus language server](https://github.com/redhat-developer/quarkus-ls/tree/master/quarkus.ls)
8+
[MicroProfile language server](https://github.com/redhat-developer/quarkus-ls/tree/master/microprofile.ls)
99
and the
10-
[Quarkus jdt.ls extension](https://github.com/redhat-developer/quarkus-ls/tree/master/quarkus.jdt)
11-
. The Quarkus language server is responsible for providing
10+
[MicroProfile jdt.ls extension](https://github.com/redhat-developer/quarkus-ls/tree/master/microprofile.jdt)
11+
. The MicroProfile language server is responsible for providing
1212
[LSP language features](https://microsoft.github.io/language-server-protocol/specification)
13-
to VSCode, while the Quarkus jdt.ls extension is responsible for listening
13+
to VSCode, while the MicroProfile jdt.ls extension is responsible
14+
for functionalities like listening
1415
to Java classpath changes and generating config setting metadata for
1516
the `application.properties` file.
1617
The reason why
1718
[vscode-java](https://github.com/redhat-developer/vscode-jav)
1819
is required for vscode-quarkus to work, is because vscode-java
1920
starts the [jdt.ls](https://github.com/eclipse/eclipse.jdt.ls)
20-
language server, which is required to run the Quarkus jdt.ls extension.
21+
language server, which is required to run the MicroProfile jdt.ls extension.
2122

2223
![](images/componentDiagram.png)
2324
The image above represents communication between the three components.
24-
As the image implies, the Quarkus Language Server cannot directly
25-
communicate with the Quarkus jdt.ls extension and vice-versa. They must
25+
As the image implies, the MicroProfile language server cannot directly
26+
communicate with the MicroProfile jdt.ls extension and vice-versa. They must
2627
communicate via vscode-quarkus.
2728

2829
Here is an example of how the components work together for
29-
`application.properties` completion.
30+
`application.properties` completion:
3031

31-
Step 1. A Quarkus project is open is VSCode, and completion has been
32+
**Step 1.** A Quarkus project is opened in VSCode, and completion has been
3233
invoked inside the `application.properties` file, which sends a
33-
`textDocument/completion` request to the Quarkus language server.
34+
`textDocument/completion` request to the MicroProfile language server.
3435

35-
Step 2. Quarkus language server checks its cache if completion options
36+
**Step 2.** MicroProfile language server checks its cache if completion options
3637
exist.
37-
* If it exists the Quarkus language server sends them to VSCode
38+
* If it exists the MicroProfile language server sends them to VSCode
3839
as the response to the `textDocument/completion` request.
3940
Communication is complete, and does not proceed to Step 3
4041
and onwards.
41-
* If it does not exist, the Quarkus language server sends a
42-
custom request, `quarkus/projectInfo` to vscode-quarkus.
42+
* If it does not exist, the MicroProfile language server sends a
43+
custom request, `microprofile/projectInfo` to vscode-quarkus.
4344
Proceed to Step 3.
4445

45-
Step 3. vscode-quarkus receives the `quarkus/projectInfo` request,
46-
and runs the `quarkus.java.projectInfo` command. This command was
47-
defined by the Quarkus jdt.ls extension.
46+
**Step 3.** vscode-quarkus receives the `microprofile/projectInfo` request,
47+
and delegates it to the MicroProfile jdt.ls extension.
4848

49-
Step 4. The Quarkus jdt.ls extension receives the command, determines
50-
information about the currently opened Quarkus project and returns
51-
the information to vscode-quarkus.
49+
**Step 4.** The MicroProfile jdt.ls extension receives the command, determines
50+
[project information](https://github.com/redhat-developer/quarkus-ls/blob/master/microprofile.jdt/com.redhat.microprofile.jdt.core/src/main/java/com/redhat/microprofile/commons/MicroProfileProjectInfo.java)
51+
(project URI, configuration properties, hints etc.)
52+
about the currently opened (MicroProfile or Quarkus) project and returns
53+
the information to vscode-quarkus. The project information is then sent to
54+
the MicroProfile language server
5255

53-
The information is computed by scanning all classes annotated with `@ConfigRoot` Quarkus annotation from all project classpath JARs and generating the proper Quarkus properties.
56+
**Step 5.** vscode-quarkus receives the project information and sends it
57+
to the MicroProfile language server.
5458

55-
For instance if the project has a `pom.xml` with this dependency:
59+
**Step 6.** MicroProfile language server receives the information, adds it
60+
to its cache, and returns the completion options stored in the
61+
project information as the response to the `textDocument/completion`
62+
request.
63+
64+
## Implementing language features for `application.properties`
65+
When an `application.properties` file sends a request (e.g. textDocument/completion) to the
66+
MicroProfile language server, the requests are accepted in
67+
[ApplicationPropertiesTextDocumentService#completion](https://github.com/redhat-developer/quarkus-ls/blob/9eb7718a6e0faa300f3937e607c3bfffc25c2f1d/microprofile.ls/com.redhat.microprofile.ls/src/main/java/com/redhat/microprofile/ls/ApplicationPropertiesTextDocumentService.java#L150).
68+
This class receives LSP requests for `application.properties` files.
69+
70+
Properties collected by the MicroProfile jdt.ls extension are cached to keep response times
71+
fast.
72+
Collecting properties will not be done unless absolutely necessary
73+
(ie, if cache doesn't exist, if project dependencies change).
74+
75+
When the completion is triggered,
76+
the MicroProfile LS checks the properties cache for the given `application.properties` file.
77+
If the cache does not exist, it calls the `microprofile/projectInfo` request to call the JDT LS Extension [projectInfo delegate command handler ](https://github.com/redhat-developer/quarkus-ls/blob/0ff91b4d0fe4670584a3ad23fe645c8141df7f3d/microprofile.jdt/com.redhat.microprofile.jdt.core/src/main/java/com/redhat/microprofile/jdt/internal/core/ls/MicroProfileDelegateCommandHandler.java#L99) which
78+
uses the
79+
[properties manager](https://github.com/redhat-developer/quarkus-ls/blob/master/microprofile.jdt/com.redhat.microprofile.jdt.core/src/main/java/com/redhat/microprofile/jdt/core/PropertiesManager.java)
80+
that collects MicroProfile and Quarkus properties for the given Java project.
81+
82+
This manager is extensible by the
83+
`com.redhat.microprofile.jdt.core.propertiesProviders`
84+
[extension point](https://github.com/redhat-developer/quarkus-ls/blob/0ff91b4d0fe4670584a3ad23fe645c8141df7f3d/microprofile.jdt/com.redhat.microprofile.jdt.quarkus/plugin.xml#L5):
85+
86+
* [com.redhat.microprofile.jdt.core](https://github.com/redhat-developer/quarkus-ls/blob/0ff91b4d0fe4670584a3ad23fe645c8141df7f3d/microprofile.jdt/com.redhat.microprofile.jdt.core/plugin.xml#L33) defines properties provider for MicroProfile.
87+
* [com.redhat.microprofile.jdt.quarkus](https://github.com/redhat-developer/quarkus-ls/blob/0ff91b4d0fe4670584a3ad23fe645c8141df7f3d/microprofile.jdt/com.redhat.microprofile.jdt.quarkus/plugin.xml#L5) define properties provider for Quarkus.
88+
89+
90+
Here are some providers and the annotation(s) they scan for:
91+
92+
| Class | Annotations |
93+
|-------|-------------|
94+
| [MicroProfileConfigPropertyProvider](https://github.com/redhat-developer/quarkus-ls/blob/master/microprofile.jdt/com.redhat.microprofile.jdt.core/src/main/java/com/redhat/microprofile/jdt/internal/core/providers/MicroProfileConfigPropertyProvider.java) | org.eclipse.microprofile.config.inject.ConfigProperty |
95+
| [MicroProfileRegisterRestClientProvider](https://github.com/redhat-developer/quarkus-ls/blob/master/microprofile.jdt/com.redhat.microprofile.jdt.core/src/main/java/com/redhat/microprofile/jdt/internal/core/providers/MicroProfileRegisterRestClientProvider.java) | org.eclipse.microprofile.rest.client.inject.RegisterRestClient |
96+
| [QuarkusConfigPropertiesProvider](https://github.com/redhat-developer/quarkus-ls/blob/master/microprofile.jdt/com.redhat.microprofile.jdt.quarkus/src/main/java/com/redhat/microprofile/jdt/internal/quarkus/providers/QuarkusConfigPropertiesProvider.java) | io.quarkus.arc.config.ConfigProperties |
97+
| [QuarkusConfigRootProvider](https://github.com/redhat-developer/quarkus-ls/blob/master/microprofile.jdt/com.redhat.microprofile.jdt.quarkus/src/main/java/com/redhat/microprofile/jdt/internal/quarkus/providers/QuarkusConfigRootProvider.java) | io.quarkus.runtime.annotations.ConfigRoot |
98+
| [QuarkusKubernetesProvider](https://github.com/redhat-developer/quarkus-ls/blob/master/microprofile.jdt/com.redhat.microprofile.jdt.quarkus/src/main/java/com/redhat/microprofile/jdt/internal/quarkus/providers/QuarkusKubernetesProvider.java) | io.dekorate.kubernetes.annotation.KubernetesApplication<br>io.dekorate.openshift.annotation.OpenshiftApplication<br>io.dekorate.s2i.annotation.S2iBuild<br>io.dekorate.docker.annotation.DockerBuild |
5699

57-
```xml
58-
<dependency>
59-
<groupId>io.quarkus</groupId>
60-
<artifactId>quarkus-core-deployment</artifactId>
61-
</dependency>
62-
```
63100

64-
The scanner will collect the [io.quarkus.deployment.ApplicationConfig](https://github.com/quarkusio/quarkus/blob/master/core/deployment/src/main/java/io/quarkus/deployment/ApplicationConfig.java) class annotated with `@ConfigRoot` and will generate a Quarkus property for each field:
101+
## Searching for properties in JARs not in the user's Quarkus project's classpath
102+
Some Quarkus properties like `quarkus.hibernate-orm.dialect` are not defined in JARs belonging
103+
to the current Quarkus project's classpath. Some Quarkus classpath JARs have deployment JARs.
104+
Generally speaking, deployment JARs are not present in the project's classpath.
65105

66-
* `quarkus.application.name` for the `name` field.
67-
* `quarkus.application.version` for the `version` field.
68-
69-
In addition, the Quarkus jdt.ls extension is able to manage `Quarkus deployment JAR`.
106+
If classpath JARs have a deployment JAR, it will be defined in the
107+
`META-INF/quarkus-extension.properties` file of the classpath JAR.
70108

71-
For instance if the project has a `pom.xml` with this dependency:
109+
For example, the `quarkus-hibernate-orm-1.2.0.Final.jar` has a deployment JAR with
110+
an artifactId of `quarkus-hibernate-orm-deployment`:
111+
![](images/deployment.png)
112+
113+
The MicroProfile jdt.ls extension creates a "fake" Java project with the deployment
114+
JARs in its classpath and performs a scan for properties for this fake project, in order
115+
to retreive the desired properties.
116+
117+
To make things more concrete:
118+
119+
Consider a Quarkus project with a `pom.xml` with this dependency:
72120

73121
```xml
74122
<dependency>
@@ -77,14 +125,23 @@ For instance if the project has a `pom.xml` with this dependency:
77125
</dependency>
78126
```
79127

80-
this JAR doesn't contain the classes annotated with `@ConfigRoot`. The JAR which contains those classes is `quarkus-hibernate-orm-deployment*.jar`. This information comes from
81-
the `META-INF/quarkus-extension.properties` of the `quarkus-hibernate-orm*.jar` as a property:
128+
Properties like `quarkus.hibernate-orm.dialect` and `quarkus.hibernate-orm.sql-load-script` are
129+
not defined (no classes annotated with `@ConfigRoot`) in the `quarkus-hibernate-orm*.jar` JAR.
130+
131+
Those properties are located in its deployment JAR: `quarkus-hibernate-orm-deployment*.jar`.
132+
133+
The deployment jar is listed in `META-INF/quarkus-extension.properties` from the `quarkus-hibernate-orm*.jar` as a property:
82134

83135
```
84-
deployment-artifact=io.quarkus\:quarkus-hibernate-orm-deployment\:0.21.1
136+
deployment-artifact=io.quarkus\:quarkus-hibernate-orm-deployment\:1.2.0.Final
85137
```
86138

87-
Under the hood, the quarkus jdt.ls extension delegates the resolution (i.e. download) of those deployment jars to Maven, regardless of the user project's build system. So, a project depending on:
139+
Note that in most cases, a Quarkus project would not have deployment JARs listed as dependencies in the project's
140+
`pom.xml`, which is why the deployment JARs would not be in the project's classpath.
141+
142+
Therefore in order to scan for the properties in the deployment JAR, under the hood, the MicroProfile jdt.ls extension delegates the resolution (i.e. download) of those deployment jars to Maven, regardless of the user project's build system.
143+
144+
In conclusion, a project depending on:
88145

89146
```xml
90147
<dependency>
@@ -93,28 +150,31 @@ Under the hood, the quarkus jdt.ls extension delegates the resolution (i.e. down
93150
</dependency>
94151
```
95152

96-
will generate some hibernate properties like:
153+
will generate the hibernate properties coming from the deployment JAR, like:
97154

98155
* `quarkus.hibernate-orm.dialect`
99156
* `quarkus.hibernate-orm.sql-load-script`
100-
101-
despite the fact that the following dependency was not declared in the `pom.xml`:
157+
158+
even if the deployment JAR itself, was not declared in the Quarkus project's `pom.xml` like so:
102159

103160
```xml
104161
<dependency>
105162
<groupId>io.quarkus</groupId>
106163
<artifactId>quarkus-hibernate-orm-deployment</artifactId>
107164
</dependency>
108165
```
109-
110-
Step 5. vscode-quarkus receives the project information and sends it
111-
to the Quarkus language server.
112166

113-
Step 6. Quarkus language server receives the information, adds it
114-
to its cache, and returns the completion options stored in the
115-
project information as the response to the `textDocument/completion`
116-
request.
167+
## Implementing language features for Java files
168+
When a Java file sends a request (e.g. textDocument/codeLens) to the
169+
MicroProfile language server, the requests are accepted in
170+
[ApplicationPropertiesTextDocumentService#completion](https://github.com/redhat-developer/quarkus-ls/blob/9eb7718a6e0faa300f3937e607c3bfffc25c2f1d/microprofile.ls/com.redhat.microprofile.ls/src/main/java/com/redhat/microprofile/ls/JavaTextDocumentService.java#L70).
171+
This class receives LSP requests for Java files.
172+
173+
Currently there is only support for textDocument/hover and textDocument/codeLens.
174+
Unlike application.properties features, there is no Eclipse extension point at the moment, to extend the hover or codelens feature.
117175

176+
The MicroProfile language server currently provides language features for `*.properties` and `*.java` files. Please see
177+
[quarkus-ls#215](https://github.com/redhat-developer/quarkus-ls/issues/215).
118178

119179
## Development Setup
120180

@@ -125,79 +185,84 @@ request.
125185
* [JDK 8+](http://www.oracle.com/technetwork/java/javase/downloads/index.html)
126186

127187
### Setup
128-
Step 1. Fork and clone this repository
188+
**Step 1.** Fork and clone this repository
129189

130-
Step 2. Fork and clone the Quarkus jdt.ls extension and Quarkus language server, both located
131-
in this [repository](https://github.com/redhat-developer/quarkus-ls).
190+
**Step 2.** Fork and clone this [repository](https://github.com/redhat-developer/quarkus-ls), which
191+
contains the MicroProfile jdt.ls extension and MicroProfile language server
132192

133-
**Note:** Ensure that the cloned repositories are siblings:
193+
**Note:** Ensure that the cloned repositories are under the same parent directory:
134194

135195
```
136196
YOUR_FOLDER/
137197
├──── vscode-quarkus/
138198
139199
├──── quarkus-ls/
140200
```
141-
Step 3. Navigate into `vscode-quarkus/`
201+
**Step 3.** Navigate into `vscode-quarkus/`
142202
```bash
143203
$ cd vscode-quarkus/
144204
```
145-
Step 4. Install npm dependencies
205+
**Step 4.** Install npm dependencies
146206
```bash
147207
$ npm install
148208
```
149209

150-
Step 5. Build the Quarkus language server and Quarkus jdt.ls extension
210+
**Step 5.** Build the MicroProfile language server and MicroProfile jdt.ls extension
151211
```bash
152212
$ npm run build
153213
```
154214
This script does two things.
155-
1. Builds the Quarkus language server and places the jar in
215+
1. Builds the MicroProfile language server and places the jar in
156216
`vscode-quarkus/server/`.
157-
2. Builds the Quarkus jdt.ls extension and places the jar in
217+
2. Builds the MicroProfile jdt.ls extension and places the jar in
158218
`vscode-quarkus/jars/`.
159219

160220
In addition to `npm run build`, there are two more build scripts:
161221
`npm run build-server` only builds the Quarkus language server and places the jar in `vscode-quarkus/server/`.
162222
`npm run build-ext` only builds the Quarkus jdt.ls extension and places the jar in `vscode-quarkus/jars/`.
163223

164224
### Running vscode-quarkus
165-
Step 1. Open `vscode-quarkus/` in VSCode.
225+
**Step 1.** Open `vscode-quarkus/` in VSCode.
166226

167-
Step 2. Open the Debugging tab, select and run
227+
**Step 2.** Open the Debugging tab, select and run
168228
"Launch Extension (vscode-quarkus)" at the top left.
169229
![](images/runExtension.png)
170230

171231
## Debugging
172-
### Debugging the Quarkus language server:
232+
### Debugging the MicroProfile language server:
173233
In an IDE of your choice, set the debugger configuration to connect
174-
to localhost, port 1064.
234+
to localhost, port 1064.
175235

176-
If using VSCode, open `quarkus-ls/quarkus.ls/` in VSCode. The proper
236+
If using VSCode, open `quarkus-ls/microprofile.ls/` in VSCode. The proper
177237
debugger configurations are already defined in `.vscode/`.
178-
There should be a "Debug (Attach) - Remote (quarkus.ls)" option
238+
There should be a "Debug (Attach) - Remote (microprofile.ls)" option
179239
at the top left of the Debugging tab.
180240
![](images/runDebugger.png)
181241

182-
The JVM arguments used to start the Quarkus language
242+
The JVM arguments used to start the MicroProfile language
183243
server are specified
184244
[here](https://github.com/redhat-developer/vscode-xml/blob/35c122edcce09038e853dfab112dd76813302034/src/javaServerStarter.ts#L26).
185245

186-
### Debugging the Quarkus jdt.ls extension:
187-
Only Eclipse can be used to debug the Quarkus jdt.ls extension.
246+
### Debugging the MicroProfile jdt.ls extension:
247+
Only Eclipse can be used to debug the MicroProfile jdt.ls extension.
188248

189-
Step 1. Open the jdt.ls source code in a new workspace in Eclipse by
249+
**Step 1.** Open the jdt.ls source code in a new workspace in Eclipse by
190250
following the setup
191251
steps in the jdt.ls GitHub repository
192252
[here](https://github.com/eclipse/eclipse.jdt.ls#first-time-setup).
193253

194-
Step 2. In the same workspace, import the projects in
195-
`quarkus-ls/quarkus.jdt`.
254+
**Step 2.** In the same workspace, import the projects from
255+
`quarkus-ls/microprofile.jdt/`.
196256

197-
Step 3. In the Debug dropdown menu, open "Debug Configurations...".
257+
**Step 3.** In the Debug dropdown menu, open "Debug Configurations...".
198258
![](images/debugConfigMenu.png)
199259

200-
Step 4. Create a new "Remote Java Application" launch configuration.
201-
Set the following settings and click "Apply".
260+
**Step 4.** Create a new "Remote Java Application" launch configuration.
261+
Set the following settings and click "Apply":
262+
```
263+
Project: com.redhat.microprofile.jdt.core
264+
Connection Type: Standard (Socket Attach)
265+
Host: localhost
266+
Port: 1044
267+
```
202268
![](images/debugConfig.png)
203-

images/componentDiagram.png

496 Bytes
Loading

images/debugConfig.png

61.3 KB
Loading

images/deployment.png

161 KB
Loading

images/runDebugger.png

4.15 KB
Loading

0 commit comments

Comments
 (0)