This is an automated email from the ASF dual-hosted git repository.
tbonelee pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zeppelin.git
The following commit(s) were added to refs/heads/master by this push:
new 9b42f2654b [ZEPPELIN-6462] Close interpreter-setting.json streams with
try-with-resources
9b42f2654b is described below
commit 9b42f2654be2fea9fdddf310686270ebc005d4d6
Author: dae won <[email protected]>
AuthorDate: Thu Aug 6 11:02:46 2026 +0900
[ZEPPELIN-6462] Close interpreter-setting.json streams with
try-with-resources
### What is this PR for?
`InterpreterSettingManager` discovers interpreters by reading each
interpreter's `interpreter-setting.json`. Two helpers do this, and neither
closes the stream it opens:
```java
// registerInterpreterFromResource
getInterpreterListFromJson(url.openStream());
// registerInterpreterFromPath
getInterpreterListFromJson(new
FileInputStream(interpreterJsonPath.toFile()));
```
The shared sink wraps the stream in an `InputStreamReader` and hands it to
`gson.fromJson(...)`. Gson does not close a reader passed to it — the caller
owns it — so the descriptor leaks on the normal path. There is no `finally` or
try-with-resources either, so it also leaks when parsing throws, for example a
`JsonSyntaxException` from a malformed setting file.
This is not limited to startup. After installing an interpreter through
`POST /api/interpreter/install`, `InterpreterService.downloadInterpreter()`
calls `refreshInterpreterTemplates()`, which re-runs the whole directory scan.
Every install therefore leaks one descriptor per interpreter directory, and the
leaks accumulate on a long-running server.
This PR wraps each stream in a try-with-resources at the call site that
opens it. Parsing and registration behaviour is unchanged. No signatures or
access modifiers change.
### What type of PR is it?
Bug Fix
### Todos
* [x] Close the stream opened in `registerInterpreterFromResource`
* [x] Close the stream opened in `registerInterpreterFromPath`
### What is the Jira issue?
* https://issues.apache.org/jira/browse/ZEPPELIN-6462
### How should this be tested?
```bash
./mvnw package -pl zeppelin-server --am \
-Dtest='InterpreterSettingManagerTest,InterpreterFactoryTest,InterpreterSettingTest'
\
-DfailIfNoTests=false
```
`Tests run: 26, Failures: 0, Errors: 0, Skipped: 0`, and `zeppelin-server`
builds.
No tests accompany this change. Asserting that a stream is closed requires
a seam in production code to inject a tracked stream, and an earlier revision
of this PR added one — that is not worth carrying for a two-line fix, so it has
been removed along with the tests that used it. The remaining change is the
try-with-resources itself.
### Screenshots (if appropriate)
N/A
### Questions:
* Does the license files need to update? No
* Is there breaking changes for older versions? No
* Does this needs documentation? No
Closes #5355 from big-cir/ZEPPELIN-6462.
Signed-off-by: ChanHo Lee <[email protected]>
---
.../zeppelin/interpreter/InterpreterSettingManager.java | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git
a/zeppelin-server/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java
b/zeppelin-server/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java
index e295938220..f6086f4d06 100644
---
a/zeppelin-server/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java
+++
b/zeppelin-server/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java
@@ -486,9 +486,10 @@ public class InterpreterSettingManager implements
NoteEventListener {
}
LOGGER.debug("Reading interpreter-setting.json from {} as Resource", url);
- List<RegisteredInterpreter> registeredInterpreterList =
- getInterpreterListFromJson(url.openStream());
- registerInterpreterSetting(registeredInterpreterList, interpreterDir,
override);
+ try (InputStream stream = url.openStream()) {
+ List<RegisteredInterpreter> registeredInterpreterList =
getInterpreterListFromJson(stream);
+ registerInterpreterSetting(registeredInterpreterList, interpreterDir,
override);
+ }
return true;
}
@@ -498,9 +499,10 @@ public class InterpreterSettingManager implements
NoteEventListener {
Path interpreterJsonPath = Paths.get(interpreterDir, interpreterJson);
if (Files.exists(interpreterJsonPath)) {
LOGGER.debug("Reading interpreter-setting.json from file {}",
interpreterJsonPath);
- List<RegisteredInterpreter> registeredInterpreterList =
- getInterpreterListFromJson(new
FileInputStream(interpreterJsonPath.toFile()));
- registerInterpreterSetting(registeredInterpreterList, interpreterDir,
override);
+ try (InputStream stream = new
FileInputStream(interpreterJsonPath.toFile())) {
+ List<RegisteredInterpreter> registeredInterpreterList =
getInterpreterListFromJson(stream);
+ registerInterpreterSetting(registeredInterpreterList, interpreterDir,
override);
+ }
return true;
}
return false;