Skip to content

Commit bb4c277

Browse files
authored
Merge pull request oracle#547 from Achal1607/vm-options
VM Options support for Notebooks and fixed Enable Preview Option
2 parents 36e9e39 + de457b5 commit bb4c277

File tree

8 files changed

+135
-13
lines changed

8 files changed

+135
-13
lines changed

nbcode/notebooks/src/org/netbeans/modules/nbcode/java/notebook/NotebookConfigs.java

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2025, Oracle and/or its affiliates.
2+
* Copyright (c) 2025-2026, Oracle and/or its affiliates.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,12 +19,14 @@
1919
import com.google.gson.JsonObject;
2020
import java.io.File;
2121
import java.util.ArrayList;
22+
import java.util.Collections;
2223
import java.util.List;
2324
import java.util.concurrent.CompletableFuture;
2425
import java.util.logging.Level;
2526
import java.util.logging.Logger;
2627
import org.eclipse.lsp4j.ConfigurationItem;
2728
import org.eclipse.lsp4j.ConfigurationParams;
29+
import org.netbeans.api.annotations.common.NonNull;
2830
import org.netbeans.modules.java.lsp.server.protocol.NbCodeLanguageClient;
2931

3032
/**
@@ -39,12 +41,14 @@ public class NotebookConfigs {
3941
"notebook.addmodules",
4042
"notebook.enablePreview",
4143
"notebook.implicitImports",
42-
"notebook.projects.mapping"};
44+
"notebook.projects.mapping",
45+
"notebook.vmOptions"};
4346
private volatile String classPath = null;
4447
private volatile String modulePath = null;
4548
private volatile String addModules = null;
4649
private volatile boolean enablePreview = false;
4750
private volatile JsonObject notebookProjectMapping = new JsonObject();
51+
private volatile List<String> notebookVmOptions = Collections.emptyList();
4852
private volatile List<String> implicitImports = null;
4953
private volatile CompletableFuture<Void> initialized;
5054

@@ -75,6 +79,11 @@ public List<String> getImplicitImports() {
7579
public JsonObject getNotebookProjectMapping() {
7680
return notebookProjectMapping;
7781
}
82+
83+
@NonNull
84+
public List<String> getNotebookVmOptions() {
85+
return notebookVmOptions;
86+
}
7887

7988
private NotebookConfigs() {
8089

@@ -119,31 +128,50 @@ private CompletableFuture<Void> initializeConfigs() {
119128
JsonArray classPathConfig = NotebookUtils.getArgument(c, 0, JsonArray.class);
120129
if (classPathConfig != null) {
121130
classPath = String.join(File.pathSeparator,classPathConfig.asList().stream().map((elem) -> elem.getAsString()).toList());
131+
} else {
132+
classPath = null;
122133
}
123134

124135
JsonArray modulePathConfig = NotebookUtils.getArgument(c, 1, JsonArray.class);
125136
if (modulePathConfig != null) {
126137
modulePath = String.join(File.pathSeparator,modulePathConfig.asList().stream().map((elem) -> elem.getAsString()).toList());
138+
} else {
139+
modulePath = null;
127140
}
128141

129142
JsonArray addModulesConfig = NotebookUtils.getArgument(c, 2, JsonArray.class);
130143
if (addModulesConfig != null) {
131144
addModules = String.join(",",addModulesConfig.asList().stream().map((elem) -> elem.getAsString()).toList());
145+
} else {
146+
addModules = null;
132147
}
133148

134149
Boolean enablePreviewConfig = NotebookUtils.getArgument(c, 3, Boolean.class);
135150
if (enablePreviewConfig != null) {
136151
enablePreview = enablePreviewConfig;
152+
} else {
153+
enablePreview = false;
137154
}
138155

139156
JsonArray implicitImportsConfig = NotebookUtils.getArgument(c, 4, JsonArray.class);
140157
if (implicitImportsConfig != null) {
141158
implicitImports = implicitImportsConfig.asList().stream().map((elem) -> elem.getAsString()).toList();
159+
} else {
160+
implicitImports = null;
142161
}
143162

144163
JsonObject notebookProjectMappingConfig = NotebookUtils.getArgument(c, 5, JsonObject.class);
145164
if (notebookProjectMappingConfig != null) {
146165
notebookProjectMapping = notebookProjectMappingConfig;
166+
} else {
167+
notebookProjectMapping = new JsonObject();
168+
}
169+
170+
JsonArray notebookVmOptionsConfig = NotebookUtils.getArgument(c, 6, JsonArray.class);
171+
if (notebookVmOptionsConfig != null) {
172+
notebookVmOptions = notebookVmOptionsConfig.asList().stream().map(el -> el.getAsString()).toList();
173+
} else {
174+
notebookVmOptions = Collections.emptyList();
147175
}
148176
}
149177
});
@@ -154,7 +182,8 @@ private CompletableFuture<Void> initializeConfigs() {
154182
}
155183

156184
public String getJdkVersion() {
157-
return System.getProperty("java.version").split("\\.")[0];
185+
// As per JEP-223
186+
return System.getProperty("java.specification.version");
158187
}
159188

160189
public void notebookConfigsChangeListener(JsonObject settings) {

nbcode/notebooks/src/org/netbeans/modules/nbcode/java/notebook/NotebookSessionManager.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2025, Oracle and/or its affiliates.
2+
* Copyright (c) 2025-2026, Oracle and/or its affiliates.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -100,6 +100,9 @@ private JShell jshellBuildWithProject(String notebookUri, Project prj, JshellStr
100100
.err(streamsHandler.getPrintErrStream())
101101
.in(streamsHandler.getInputStream());
102102

103+
LOG.log(Level.FINE, "Initializing Notebook kernel for {0}", notebookUri);
104+
LOG.log(Level.FINE, "Compiler options being passed: {0}", compilerOptions);
105+
LOG.log(Level.FINE, "VM Options being passed to notebook kernel: {0}", remoteOptions);
103106
if (!compilerOptions.isEmpty()) {
104107
builder.compilerOptions(compilerOptions.toArray(new String[0]))
105108
.remoteVMOptions(remoteOptions.toArray(new String[0]));
@@ -226,6 +229,10 @@ private List<String> getRemoteVmOptions(Project prj) {
226229
if (enablePreview) {
227230
remoteOptions.add(ENABLE_PREVIEW);
228231
}
232+
233+
List<String> extraVmOptions = NotebookConfigs.getInstance().getNotebookVmOptions();
234+
remoteOptions.addAll(extraVmOptions);
235+
229236
return remoteOptions;
230237
}
231238

nbcode/notebooks/test/unit/src/org/netbeans/modules/nbcode/java/notebook/NotebookConfigsTest.java

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2025, Oracle and/or its affiliates.
2+
* Copyright (c) 2025-2026 Oracle and/or its affiliates.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818

1919
import com.google.gson.JsonObject;
2020
import com.google.gson.JsonArray;
21+
import com.google.gson.JsonElement;
2122
import com.google.gson.JsonPrimitive;
2223
import java.io.File;
2324
import java.util.ArrayList;
@@ -37,11 +38,6 @@
3738
2.Missing keys
3839
*/
3940

40-
/*
41-
Version 1 21/08/25
42-
Version 2 25/09/25 Inline with frontend sending arrays for CP,MP,Add modules
43-
*/
44-
4541
/**
4642
* Mock LSP Client sending sample configurations
4743
* Verifies that the NotebookConfigs class
@@ -59,6 +55,7 @@ public class NotebookConfigsTest {
5955
private static final String ADD_MODULES_KEY = "jdk.notebook.addmodules";
6056
private static final String ENABLE_PREVIEW_KEY = "jdk.notebook.enablePreview";
6157
private static final String MODULEPATH_KEY = "jdk.notebook.modulepath";
58+
private static final String VM_OPTIONS_KEY = "jdk.notebook.vmOptions";
6259

6360
public NotebookConfigsTest() {
6461
}
@@ -173,26 +170,105 @@ public void testGetImplicitImports() {
173170
fail("Configuration initialization failed");
174171
}
175172
}
173+
174+
/**
175+
* Test of getNotebookVmOptions method, of class NotebookConfigs.
176+
*/
177+
@Test
178+
public void testGetNotebookVmOptions() {
179+
System.out.println("getNotebookVmOptions");
180+
try {
181+
initialized.get(5, TimeUnit.SECONDS);
182+
183+
List<String> expResult = configsObj.get(VM_OPTIONS_KEY)
184+
.getAsJsonArray()
185+
.asList()
186+
.stream()
187+
.map(elem -> elem.getAsString())
188+
.toList();
189+
190+
List<String> result = instance.getNotebookVmOptions();
176191

192+
assertEquals(expResult, result);
193+
} catch (Exception ex) {
194+
fail("Configuration initialization failed");
195+
}
196+
}
197+
198+
/**
199+
* Test of getNotebookVmOptions method when the configuration key is
200+
* missing. Verifies that the system handles a null/missing key gracefully
201+
* (likely returning an empty list).
202+
*/
203+
@Test
204+
public void testGetNotebookVmOptionsWhenMissing() {
205+
try {
206+
updateConfigValue(VM_OPTIONS_KEY, null);
207+
List<String> result = instance.getNotebookVmOptions();
208+
assertNotNull("Result should not be null even if key is missing", result);
209+
assertTrue("Result should be empty when key is missing", result.isEmpty());
210+
211+
} catch (Exception ex) {
212+
fail("Failed to handle missing VM_OPTIONS_KEY: " + ex.getMessage());
213+
}
214+
}
215+
216+
/**
217+
* Test of getNotebookVmOptions with quoted spaces.
218+
* Verifies that options containing spaces (like directory paths) are preserved.
219+
*/
220+
@Test
221+
public void testGetNotebookVmOptionsWithQuotedSpaces() {
222+
try {
223+
String quotedOption = "\"-Djava.io.tmpdir=C:\\Temp Folder\\java\"";
224+
225+
JsonArray vmOptions = new JsonArray();
226+
vmOptions.add(new JsonPrimitive(quotedOption));
227+
updateConfigValue(VM_OPTIONS_KEY, vmOptions);
228+
List<String> result = instance.getNotebookVmOptions();
229+
230+
assertTrue("Result should contain the quoted option", result.contains(quotedOption));
231+
assertEquals("Should have exactly 1 option", 1, result.size());
232+
233+
} catch (Exception ex) {
234+
fail("Configuration with quoted spaces failed");
235+
}
236+
}
237+
177238
private void setConfigObject() {
178239
JsonArray imports = new JsonArray();
179240
imports.add(new JsonPrimitive("java.math.*"));
180241
imports.add(new JsonPrimitive("javafx.scene.control.*"));
181242
configsObj.add(IMPLICIT_IMPORTS_KEY, imports);
243+
182244
JsonArray classpath = new JsonArray();
183245
classpath.add(new JsonPrimitive(
184246
"path/to/javafx-sdk-24.0.1/lib/javafx.base.jar"));
185247
configsObj.add(CLASSPATH_KEY, classpath);
248+
186249
JsonArray modulepath = new JsonArray();
187250
modulepath.add(new JsonPrimitive("/path/to/javafx-sdk/lib"));
188251
configsObj.add(MODULEPATH_KEY, modulepath);
189252
configsObj.add(ENABLE_PREVIEW_KEY, new JsonPrimitive(false));
253+
190254
JsonArray addModules = new JsonArray();
191255
addModules.add(new JsonPrimitive("javafx.controls"));
192256
addModules.add(new JsonPrimitive("javafx.graphics"));
193257
configsObj.add(ADD_MODULES_KEY, addModules);
258+
259+
JsonArray vmOptions = new JsonArray();
260+
vmOptions.add(new JsonPrimitive("--add-opens=java.base/java.lang=ALL-UNNAMED"));
261+
vmOptions.add(new JsonPrimitive("--add-opens=java.base/java.util=ALL-UNNAMED"));
262+
vmOptions.add(new JsonPrimitive("-Xmx2G"));
263+
configsObj.add(VM_OPTIONS_KEY, vmOptions);
194264

195265
}
266+
267+
private void updateConfigValue(String key, JsonElement value){
268+
configsObj.add(key, value);
269+
instance.initConfigs();
270+
instance.getInitialized();
271+
}
196272

197273
private class MockNbClientConfigs extends MockNbClient {
198274

vscode/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,11 @@
300300
"default": {},
301301
"description": "%jdk.notebook.projects.mapping.description%"
302302
},
303+
"jdk.notebook.vmOptions": {
304+
"type": "array",
305+
"default": [],
306+
"description": "%jdk.notebook.vmOptions.description%"
307+
},
303308
"jdk.telemetry.enabled": {
304309
"type": "boolean",
305310
"description": "%jdk.configuration.telemetry.enabled.description%",

vscode/package.nls.ja.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
"jdk.notebook.implicitImports.description": "Javaノートブックで暗黙的にインポートする要素のリスト。空のときのデフォルトはjava.util、java.ioおよびjava.mathパッケージのスター・インポート。",
7979
"jdk.notebook.implicitImports.markdownDescription": "Javaノートブックで暗黙的にインポートする要素のリスト。空のときのデフォルトは`java.util`、`java.io`および`java.math`パッケージのスター・インポート。",
8080
"jdk.notebook.projects.mapping.description": "Javaノートブック・パスの、コンテキストを提供するプロジェクトのパスへのマッピング。",
81+
"jdk.notebook.vmOptions.description": "The specific Java VM options for use in Java notebooks. These options are added in addition to the project configuration, including class-path, module-path, preview features, and added modules.",
8182
"jdk.configuration.java.completion.commit.chars": "コード補完の提案の受入れをトリガーする文字を指定します。たとえば、ピリオド(.)を入力したときに提案を受け入れるには、これを[\".\"]に設定します",
8283
"jdk.initialConfigurations.launchJavaApp.name": "Javaアプリケーションの起動",
8384
"jdk.configurationSnippets.name": "Javaアプリケーションの起動",

vscode/package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
"jdk.notebook.implicitImports.description": "List of elements to implicitly import in Java notebooks. Defaults to star-imports of java.util, java.io and java.math packages, when empty.",
7979
"jdk.notebook.implicitImports.markdownDescription": "List of elements to implicitly import in Java notebooks. Defaults to star-imports of `java.util`, `java.io` and `java.math` packages, when empty.",
8080
"jdk.notebook.projects.mapping.description": "Mapping of Java notebook paths to the path of the project that provides it context.",
81+
"jdk.notebook.vmOptions.description": "The specific Java VM options for use in Java notebooks. These options are added in addition to the project configuration, including class-path, module-path, preview features, and added modules.",
8182
"jdk.configuration.java.completion.commit.chars": "Specifies the characters that trigger accepting a code completion suggestion. For example, to accept suggestions when typing a dot (.), set this to [\".\"]",
8283
"jdk.initialConfigurations.launchJavaApp.name": "Launch Java App",
8384
"jdk.configurationSnippets.name": "Launch Java App",

vscode/package.nls.zh-cn.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
"jdk.notebook.implicitImports.description": "要在 Java 记事本中隐式导入的元素列表。为空时,默认为 java.util、java.io 和 java.math 程序包的星型导入。",
7979
"jdk.notebook.implicitImports.markdownDescription": "要在 Java 记事本中隐式导入的元素列表。为空时,默认为 `java.util`、`java.io` 和 `java.math` 程序包的星型导入。",
8080
"jdk.notebook.projects.mapping.description": "将 Java 记事本路径映射到提供记事本上下文的项目的路径。",
81+
"jdk.notebook.vmOptions.description": "The specific Java VM options for use in Java notebooks. These options are added in addition to the project configuration, including class-path, module-path, preview features, and added modules.",
8182
"jdk.configuration.java.completion.commit.chars": "指定用于触发接受代码补全建议的字符。例如,要在键入点 (.) 时接受建议,请将该字符设为 [\".\"]",
8283
"jdk.initialConfigurations.launchJavaApp.name": "启动 Java 应用程序",
8384
"jdk.configurationSnippets.name": "启动 Java 应用程序",

vscode/src/configurations/configuration.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2023-2024, Oracle and/or its affiliates.
2+
Copyright (c) 2023-2026, Oracle and/or its affiliates.
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -36,8 +36,9 @@ export const configKeys = {
3636
notebookAddModules: "notebook.addmodules",
3737
notebookEnablePreview: "notebook.enablePreview",
3838
notebookImplicitImports: "notebook.implicitImports",
39-
telemetryEnabled: 'telemetry.enabled',
40-
notebookProjectMapping: "notebook.projects.mapping"
39+
notebookProjectMapping: "notebook.projects.mapping",
40+
notebookVmOptions: "notebook.vmOptions",
41+
telemetryEnabled: 'telemetry.enabled'
4142
};
4243

4344
export const builtInConfigKeys = {
@@ -56,6 +57,7 @@ export const userConfigsListened: string[] = [
5657
appendPrefixToCommand(configKeys.notebookEnablePreview),
5758
appendPrefixToCommand(configKeys.notebookImplicitImports),
5859
appendPrefixToCommand(configKeys.notebookProjectMapping),
60+
appendPrefixToCommand(configKeys.notebookVmOptions),
5961
builtInConfigKeys.vscodeTheme,
6062
];
6163

0 commit comments

Comments
 (0)