From cc0f1012f58ab254cfedba23da771f4b865ae4a7 Mon Sep 17 00:00:00 2001 From: Oleg Samarin Date: Sat, 23 May 2026 17:23:04 +0300 Subject: [PATCH] Fixed ConcurrentModificationException in getScreenLines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The EDT screen-poll timer read JediTerm's TerminalTextBuffer without holding the buffer lock while the PTY thread was writing to it, causing ConcurrentModificationException inside TerminalLine.getText(). Fixed by acquiring TerminalTextBuffer.tryLock() before reading the screen buffer. tryLock() (non-blocking) is used instead of lock() so the EDT timer never blocks waiting for a PTY write to finish — it simply returns an empty list and retries on the next tick. Co-Authored-By: Claude Sonnet 4.6 --- CHANGELOG.md | 1 + pom.xml | 2 +- .../github/nbplugins/claudecodegui/ui/ClaudeSessionTab.java | 6 +++++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 171a3d4b..92db04e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ +- Fixed occasional ConcurrentModificationException when the screen-poll timer reads the terminal buffer concurrently with PTY writes - Fixed tab title showing "Claude Code" for sessions opened in non-project directories — now shows the directory name - Added OpenAI-compatible proxy: profiles can now route Claude Code through any OpenAI-compatible API provider (OpenAI, Azure, Groq, DeepSeek, Ollama, local models, etc.) diff --git a/pom.xml b/pom.xml index aebe314a..e31a8c64 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.nbplugins netbeans-plugin-claude-code-gui - 1.2.9-SNAPSHOT + 1.2.10-SNAPSHOT nbm Netbeans Plugin Claude Code GUI NetBeans plugin that provides a GUI for Claude Code CLI — run claude code sessions directly inside the IDE. diff --git a/src/main/java/io/github/nbplugins/claudecodegui/ui/ClaudeSessionTab.java b/src/main/java/io/github/nbplugins/claudecodegui/ui/ClaudeSessionTab.java index 7ee18931..10bb86ab 100644 --- a/src/main/java/io/github/nbplugins/claudecodegui/ui/ClaudeSessionTab.java +++ b/src/main/java/io/github/nbplugins/claudecodegui/ui/ClaudeSessionTab.java @@ -1470,13 +1470,17 @@ private void walkScrollComponents(java.awt.Container c, StringBuilder sb, int de private List getScreenLines() { if (terminalWidget == null) return java.util.Collections.emptyList(); + TerminalTextBuffer buf = terminalWidget.getTerminalTextBuffer(); + if (buf == null) return java.util.Collections.emptyList(); + if (!buf.tryLock()) return java.util.Collections.emptyList(); try { - TerminalTextBuffer buf = terminalWidget.getTerminalTextBuffer(); return buf.getScreenBuffer().getLineTexts(); } catch (NullPointerException e) { // JediTerm's LinesStorage may return null entries during terminal // initialization. Return empty so pollScreenState retries next tick. return java.util.Collections.emptyList(); + } finally { + buf.unlock(); } }