Skip to content

Commit 8b69428

Browse files
committed
Allow setting JDK path via a java.home JSON setting.
Update the documentation.
1 parent 0f4eda8 commit 8b69428

7 files changed

Lines changed: 87 additions & 40 deletions

File tree

README.md

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -128,26 +128,37 @@ Note: This tool is not compatible with [vim-lsp](https://github.com/prabirshrest
128128

129129
## Usage
130130

131-
The language server will provide autocomplete and other features using:
132-
* .java files anywhere in your workspace
131+
The language server provides autocomplete and other features using:
132+
* Java source files anywhere in your workspace
133133
* Java platform classes
134-
* External dependencies specified using `pom.xml`, Bazel, or [settings](#Settings)
134+
* External dependencies specified using `pom.xml`, Bazel, or via explicit [settings](#Settings)
135135

136136
## Settings
137137

138-
If the language server doesn't detect your external dependencies automatically, you can specify them using [.vscode/settings.json](https://code.visualstudio.com/docs/getstarted/settings)
138+
Generally, the language server infers the location of the JDK and external
139+
dependency jar files. If this process does not work correctly, you can specify
140+
them explicitly
141+
using [.vscode/settings.json](https://code.visualstudio.com/docs/getstarted/settings).
142+
143+
### Location of the JDK
144+
145+
The location of the JDK is determined by reading the JAVA_HOME environment
146+
variable. If JAVA_HOME is unset, then the language server searches operating
147+
system specific locations for a JDK. The JDK location can be explicitly set
148+
with:
139149

140150
```json
141151
{
142-
"java.externalDependencies": [
143-
"junit:junit:jar:4.12:test", // Maven format
144-
"junit:junit:4.12" // Gradle-style format is also allowed
145-
]
152+
"java.home": "/file/path/of/the/jdk"
146153
}
147154
```
148155

149-
If all else fails, you can specify the Java class path and the locations of
150-
source jars manually:
156+
### External dependency jar files
157+
158+
By default the language server infers the Java classpath and finds source code
159+
jars for external dependencies by running Maven or Bazel. The inference
160+
process can be diabled by explicitly specifying classpath. Both paths may be
161+
set explicitly with:
151162

152163
```json
153164
{
@@ -160,6 +171,17 @@ source jars manually:
160171
}
161172
```
162173

174+
External dependencies can also be specified in Maven or Gradle format with:
175+
176+
```json
177+
{
178+
"java.externalDependencies": [
179+
"junit:junit:jar:4.12:test", // Maven format
180+
"junit:junit:4.12" // Gradle-style format is also allowed
181+
]
182+
}
183+
```
184+
163185
You can generate a list of external dependencies using your build tool:
164186
* Maven: `mvn dependency:list`
165187
* Gradle: `gradle dependencies`

src/main/java/org/javacs/Docs.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ public class Docs {
1414
/** File manager with source-path + platform sources, which we will use to look up individual source files */
1515
final SourceFileManager fileManager = new SourceFileManager();
1616

17-
Docs(Set<Path> docPath) {
18-
var srcZipPath = srcZip();
17+
Docs(Set<Path> docPath, Path javaHome) {
18+
var srcZipPath = srcZip(javaHome);
1919
// Path to source .jars + src.zip
2020
var sourcePath = new ArrayList<Path>(docPath);
2121
if (srcZipPath != NOT_FOUND) {
@@ -34,9 +34,9 @@ public class Docs {
3434
static final Path NOT_FOUND = Paths.get("");
3535
private static Path cacheSrcZip;
3636

37-
private static Path srcZip() {
37+
private static Path srcZip(Path javaHome) {
3838
if (cacheSrcZip == null) {
39-
cacheSrcZip = findSrcZip();
39+
cacheSrcZip = findSrcZip(javaHome);
4040
}
4141
if (cacheSrcZip == NOT_FOUND) {
4242
return NOT_FOUND;
@@ -49,15 +49,23 @@ private static Path srcZip() {
4949
}
5050
}
5151

52-
static Path findSrcZip() {
53-
var javaHome = JavaHomeHelper.javaHome();
52+
static Path findSrcZip(Path javaHome) {
53+
if (javaHome == NOT_FOUND) {
54+
javaHome = JavaHomeHelper.javaHome();
55+
}
56+
57+
if (javaHome == NOT_FOUND) {
58+
LOG.warning("Couldn't find Java home.");
59+
return NOT_FOUND;
60+
}
61+
5462
String[] locations = {
5563
"lib/src.zip", "src.zip", "libexec/openjdk.jdk/Contents/Home/lib/src.zip"
5664
};
5765
for (var rel : locations) {
5866
var abs = javaHome.resolve(rel);
5967
if (Files.exists(abs)) {
60-
LOG.info("Found " + abs);
68+
LOG.info("Found src.zip " + abs);
6169
return abs;
6270
}
6371
}

src/main/java/org/javacs/JavaCompilerService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class JavaCompilerService implements CompilerProvider {
2121
// TODO intercept files that aren't in the batch and erase method bodies so compilation is faster
2222
final SourceFileManager fileManager;
2323

24-
JavaCompilerService(Set<Path> classPath, Set<Path> docPath, Set<String> addExports) {
24+
JavaCompilerService(Set<Path> classPath, Set<Path> docPath, Set<String> addExports, Path javaHome) {
2525
System.err.println("Class path:");
2626
for (var p : classPath) {
2727
System.err.println(" " + p);
@@ -34,7 +34,7 @@ class JavaCompilerService implements CompilerProvider {
3434
this.classPath = Collections.unmodifiableSet(classPath);
3535
this.docPath = Collections.unmodifiableSet(docPath);
3636
this.addExports = Collections.unmodifiableSet(addExports);
37-
this.docs = new Docs(docPath);
37+
this.docs = new Docs(docPath, javaHome);
3838
this.classPathClasses = ScanClassPath.classPathTopLevelClasses(classPath);
3939
this.fileManager = new SourceFileManager();
4040
}

src/main/java/org/javacs/JavaLanguageServer.java

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -93,24 +93,25 @@ private JavaCompilerService createCompiler() {
9393
var externalDependencies = externalDependencies();
9494
var classPath = classPath();
9595
var addExports = addExports();
96+
var javaHome = javaHome();
97+
9698
// If classpath is specified by the user, don't infer anything
9799
if (!classPath.isEmpty()) {
98100
javaEndProgress();
99-
return new JavaCompilerService(classPath, docPath(), addExports);
101+
return new JavaCompilerService(classPath, docPath(), addExports, javaHome);
100102
}
101-
// Otherwise, combine inference with user-specified external dependencies
102-
else {
103-
var infer = new InferConfig(workspaceRoot, externalDependencies);
104103

105-
javaReportProgress(new JavaReportProgressParams("Inferring class path"));
106-
classPath = infer.classPath();
104+
// Otherwise, combine inference with user-specified external dependencies.
105+
var infer = new InferConfig(workspaceRoot, externalDependencies);
107106

108-
javaReportProgress(new JavaReportProgressParams("Inferring doc path"));
109-
var docPath = infer.buildDocPath();
107+
javaReportProgress(new JavaReportProgressParams("Inferring class path"));
108+
classPath = infer.classPath();
110109

111-
javaEndProgress();
112-
return new JavaCompilerService(classPath, docPath, addExports);
113-
}
110+
javaReportProgress(new JavaReportProgressParams("Inferring doc path"));
111+
var docPath = infer.buildDocPath();
112+
113+
javaEndProgress();
114+
return new JavaCompilerService(classPath, docPath, addExports, javaHome);
114115
}
115116

116117
private Set<String> externalDependencies() {
@@ -153,6 +154,13 @@ private Set<String> addExports() {
153154
return strings;
154155
}
155156

157+
private Path javaHome() {
158+
if (settings.has("home")) {
159+
return Paths.get(settings.get("home").getAsString());
160+
}
161+
return Docs.NOT_FOUND;
162+
}
163+
156164
@Override
157165
public InitializeResult initialize(InitializeParams params) {
158166
this.workspaceRoot = Paths.get(params.rootUri);

src/test/java/org/javacs/BenchmarkPruner.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
package org.javacs;
22

3+
import org.javacs.completion.PruneMethodBodies;
4+
import org.openjdk.jmh.annotations.*;
5+
36
import java.nio.file.Paths;
47
import java.time.Instant;
58
import java.util.Collections;
69
import java.util.List;
710
import java.util.Set;
811
import java.util.concurrent.TimeUnit;
912
import java.util.logging.Logger;
10-
import org.javacs.completion.PruneMethodBodies;
11-
import org.openjdk.jmh.annotations.*;
1213

1314
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
1415
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@@ -38,7 +39,8 @@ private static JavaCompilerService createCompiler() {
3839
var workspaceRoot = Paths.get(".").normalize().toAbsolutePath();
3940
FileStore.setWorkspaceRoots(Set.of(workspaceRoot));
4041
var classPath = new InferConfig(workspaceRoot).classPath();
41-
return new JavaCompilerService(classPath, Collections.emptySet(), Collections.emptySet());
42+
return new JavaCompilerService(
43+
classPath, Collections.emptySet(), Collections.emptySet(), Docs.NOT_FOUND);
4244
}
4345
}
4446

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
package org.javacs;
22

3-
import static org.hamcrest.Matchers.*;
43
import static org.hamcrest.MatcherAssert.assertThat;
4+
import static org.hamcrest.Matchers.*;
55
import static org.junit.Assert.assertTrue;
66

7+
import org.junit.Test;
8+
79
import java.nio.file.Files;
810
import java.nio.file.Path;
9-
import org.junit.Test;
1011

1112
public class FindSrcZipTest {
1213
@Test
1314
public void testFindSrcZip() {
14-
// This test is not run in the CI pipeline, but it can be run locally to check if the src.zip file is found correctly.
15-
Path srcZip = Docs.findSrcZip();
15+
// This test is not run in the CI pipeline, but it can be run locally to check if the
16+
// src.zip file is found correctly.
17+
Path srcZip = Docs.findSrcZip(Docs.NOT_FOUND);
1618
assertThat(srcZip, not(equalTo(Docs.NOT_FOUND)));
1719
assertTrue(Files.exists(srcZip));
1820
}
19-
}
21+
}

src/test/java/org/javacs/JavaCompilerServiceTest.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,22 @@
33
import static org.hamcrest.Matchers.*;
44
import static org.junit.Assert.*;
55

6+
import org.junit.*;
7+
68
import java.nio.file.*;
79
import java.util.*;
8-
import org.junit.*;
910

1011
public class JavaCompilerServiceTest {
1112
static {
1213
Main.setRootFormat();
1314
}
1415

1516
private JavaCompilerService compiler =
16-
new JavaCompilerService(Collections.emptySet(), Collections.emptySet(), Collections.emptySet());
17+
new JavaCompilerService(
18+
Collections.emptySet(),
19+
Collections.emptySet(),
20+
Collections.emptySet(),
21+
Docs.NOT_FOUND);
1722

1823
static Path simpleProjectSrc() {
1924
return Paths.get("src/test/examples/simple-project").normalize();

0 commit comments

Comments
 (0)