From d4cac43f5c978acbaf29d0089f3a2940e328880f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Oct 2025 13:02:19 +0000 Subject: [PATCH 1/4] Initial plan From 777c86c6ac9bb87b9029aff4fe71881dd0a095bf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Oct 2025 13:07:52 +0000 Subject: [PATCH 2/4] Add null checks to prevent NPE when opening MANIFEST.MF - Add null check in BundleInputContext.createModel() to handle case when document is not yet available - Add defensive null check in AbstractEditingModel.getInputStream() to prevent NPE - Both changes ensure graceful handling of timing/race conditions during editor initialization Co-authored-by: vogella <139910+vogella@users.noreply.github.com> --- .../eclipse/pde/internal/core/text/AbstractEditingModel.java | 4 ++++ .../pde/internal/ui/editor/plugin/BundleInputContext.java | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/ui/org.eclipse.pde.core/text/org/eclipse/pde/internal/core/text/AbstractEditingModel.java b/ui/org.eclipse.pde.core/text/org/eclipse/pde/internal/core/text/AbstractEditingModel.java index aad9625c10a..a75112de3db 100644 --- a/ui/org.eclipse.pde.core/text/org/eclipse/pde/internal/core/text/AbstractEditingModel.java +++ b/ui/org.eclipse.pde.core/text/org/eclipse/pde/internal/core/text/AbstractEditingModel.java @@ -159,6 +159,10 @@ public final void reconciled(IDocument document) { public abstract void adjustOffsets(IDocument document) throws CoreException; protected InputStream getInputStream(IDocument document) { + if (document == null) { + // Return empty stream if document is not available + return new ByteArrayInputStream(new byte[0]); + } return new ByteArrayInputStream(document.get().getBytes(getCharset())); } diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/BundleInputContext.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/BundleInputContext.java index b17d460312d..fdd857a6893 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/BundleInputContext.java +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/BundleInputContext.java @@ -68,6 +68,10 @@ public BundleInputContext(PDEFormEditor editor, IEditorInput input, boolean prim protected IBaseModel createModel(IEditorInput input) throws CoreException { boolean isReconciling = input instanceof IFileEditorInput; IDocument document = getDocumentProvider().getDocument(input); + if (document == null) { + // Document not available yet - this can happen during editor initialization + return null; + } BundleModel model = new BundleModel(document, isReconciling); if (input instanceof IFileEditorInput) { IFile file = ((IFileEditorInput) input).getFile(); From 6e9180a1a3720b4ff0a59cf276ddd9454a889308 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Oct 2025 13:10:51 +0000 Subject: [PATCH 3/4] Update null handling approach - allow model creation with null document - Allow BundleModel to be created even when document is null - Add explanatory comments about the defensive null handling strategy - The null check in AbstractEditingModel.getInputStream() ensures graceful degradation Co-authored-by: vogella <139910+vogella@users.noreply.github.com> --- .../pde/internal/ui/editor/plugin/BundleInputContext.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/BundleInputContext.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/BundleInputContext.java index fdd857a6893..9310ea1f806 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/BundleInputContext.java +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/BundleInputContext.java @@ -70,7 +70,8 @@ protected IBaseModel createModel(IEditorInput input) throws CoreException { IDocument document = getDocumentProvider().getDocument(input); if (document == null) { // Document not available yet - this can happen during editor initialization - return null; + // The defensive null check in AbstractEditingModel.getInputStream() will handle this gracefully + // by returning an empty stream, and the model will be marked as not loaded } BundleModel model = new BundleModel(document, isReconciling); if (input instanceof IFileEditorInput) { From 323d7714388ee52343e89ae76d50c1b2da5665fb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Oct 2025 13:44:02 +0000 Subject: [PATCH 4/4] Validate document availability after connect() to provide better error Instead of treating the NPE symptom, validate that the document is available after connect() and throw a descriptive CoreException if not. This helps identify the root cause: - File deleted/moved during editor initialization - Race condition with workspace events - Document provider failing silently The CoreException will be logged with context about which input failed, making it easier to diagnose the actual issue. Co-authored-by: laeubi <1331477+laeubi@users.noreply.github.com> --- .../pde/internal/core/text/AbstractEditingModel.java | 4 ---- .../pde/internal/ui/editor/context/InputContext.java | 10 ++++++++++ .../internal/ui/editor/plugin/BundleInputContext.java | 5 ----- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/ui/org.eclipse.pde.core/text/org/eclipse/pde/internal/core/text/AbstractEditingModel.java b/ui/org.eclipse.pde.core/text/org/eclipse/pde/internal/core/text/AbstractEditingModel.java index a75112de3db..aad9625c10a 100644 --- a/ui/org.eclipse.pde.core/text/org/eclipse/pde/internal/core/text/AbstractEditingModel.java +++ b/ui/org.eclipse.pde.core/text/org/eclipse/pde/internal/core/text/AbstractEditingModel.java @@ -159,10 +159,6 @@ public final void reconciled(IDocument document) { public abstract void adjustOffsets(IDocument document) throws CoreException; protected InputStream getInputStream(IDocument document) { - if (document == null) { - // Return empty stream if document is not available - return new ByteArrayInputStream(new byte[0]); - } return new ByteArrayInputStream(document.get().getBytes(getCharset())); } diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/context/InputContext.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/context/InputContext.java index 1db4b1e10c3..03bd2818c26 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/context/InputContext.java +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/context/InputContext.java @@ -162,6 +162,16 @@ protected void create() { fDocumentProvider = createDocumentProvider(fEditorInput); try { fDocumentProvider.connect(fEditorInput); + // Verify that the document is available after connect() + // This can fail if the file was deleted/moved during editor initialization + // or if there's a race condition with workspace events + IDocument document = fDocumentProvider.getDocument(fEditorInput); + if (document == null) { + throw new CoreException(new org.eclipse.core.runtime.Status( + org.eclipse.core.runtime.IStatus.ERROR, + "org.eclipse.pde.ui", //$NON-NLS-1$ + "Document not available after connecting to document provider for input: " + fEditorInput.getName())); //$NON-NLS-1$ + } fModel = createModel(fEditorInput); if (fModel instanceof IModelChangeProvider) { fModelListener = e -> { diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/BundleInputContext.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/BundleInputContext.java index 9310ea1f806..b17d460312d 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/BundleInputContext.java +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/BundleInputContext.java @@ -68,11 +68,6 @@ public BundleInputContext(PDEFormEditor editor, IEditorInput input, boolean prim protected IBaseModel createModel(IEditorInput input) throws CoreException { boolean isReconciling = input instanceof IFileEditorInput; IDocument document = getDocumentProvider().getDocument(input); - if (document == null) { - // Document not available yet - this can happen during editor initialization - // The defensive null check in AbstractEditingModel.getInputStream() will handle this gracefully - // by returning an empty stream, and the model will be marked as not loaded - } BundleModel model = new BundleModel(document, isReconciling); if (input instanceof IFileEditorInput) { IFile file = ((IFileEditorInput) input).getFile();