You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Prevents newlines from causing unnecessary JShell wrapper redefinitions and losing previously initialized variables.
The normalization is applied immediately before each snippet is evaluated by JShell, while the original source remains available for completion analysis and snippet processing.
Details
JShell preserves the newline separating snippets when returning CompletionInfo.source(). Passing that leading newline directly to JShell changes the generated wrapper source layout and its class file line-number metadata.
For imports that do not alter executable code, this creates a bytecode difference that incorrectly triggers ExecutionControl.redefine(). Since JJavaExecutionControl does not support in-place redefinition, JShell creates a replacement wrapper with default-initialized fields, causing previously assigned variables to become null.
Stripping surrounding whitespace characters before evaluation removes the accidental source-layout difference while preserving the actual import and code semantics. Legitimate changes to executable bytecode remain unaffected.
The regression test for later imports is enabled, and coverage for variable redeclaration remains intact.
Testing
Verified with existing integration tests and manual testing in Jupyter Notebook.
@m-dzianishchyts , @stariy95 : guys, I tried to understand how this PR is different from the original #120. So I manually reverted all #120 commits (already pushed to "main") and then did a merge --squash of this one on top. The only change that I see is introduction of KernelExecutionIT.java test. But the original problem is still there when I run it manually. It was not fixed.
Ok, I was able to rewrite KernelExecutionIT in a way that reproduces the issue. It is committed to main (see a @Disabled test). The reason the original test didn't fail was that each line was executed in a separate cell. Somehow combining things in cells in a certain way causes this problem. Here are Claude findings on which combos work and which don't:
┌──────────────────────────────────────────────────────────┬────────┐
│ cells │ result │
├──────────────────────────────────────────────────────────┼────────┤
│ 5 separate cells (what the IT does) │ ✅ ok │
├──────────────────────────────────────────────────────────┼────────┤
│ all 5 in one cell │ ❌ NPE │
├──────────────────────────────────────────────────────────┼────────┤
│ %maven alone, then remaining 4 lines in one cell │ ❌ NPE │
├──────────────────────────────────────────────────────────┼────────┤
│ %maven / import+var om+import / om.getClass() │ ❌ NPE │
├──────────────────────────────────────────────────────────┼────────┤
│ %maven / import+var om / import+om.getClass() │ ✅ ok │
└──────────────────────────────────────────────────────────┴────────┘
One little thing left - figure out how to fix it 🙂
m-dzianishchyts
changed the title
Revert #120 "Prevent variable nullification on later imports"
Prevent variable nullification on later imports
Aug 17, 2026
It works for me now. Amazing how trimming the code would make a difference. Thanks for digging it up! 🎉
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Prevents newlines from causing unnecessary JShell wrapper redefinitions and losing previously initialized variables.
The normalization is applied immediately before each snippet is evaluated by JShell, while the original source remains available for completion analysis and snippet processing.
Details
JShell preserves the newline separating snippets when returning
CompletionInfo.source(). Passing that leading newline directly to JShell changes the generated wrapper source layout and its class file line-number metadata.For imports that do not alter executable code, this creates a bytecode difference that incorrectly triggers
ExecutionControl.redefine(). SinceJJavaExecutionControldoes not support in-place redefinition, JShell creates a replacement wrapper with default-initialized fields, causing previously assigned variables to becomenull.Stripping surrounding whitespace characters before evaluation removes the accidental source-layout difference while preserving the actual import and code semantics. Legitimate changes to executable bytecode remain unaffected.
The regression test for later imports is enabled, and coverage for variable redeclaration remains intact.
Testing
Verified with existing integration tests and manual testing in Jupyter Notebook.