diff --git a/apitools/org.eclipse.pde.api.tools.tests/src/org/eclipse/pde/api/tools/comparator/tests/ClassDeltaSealedTests.java b/apitools/org.eclipse.pde.api.tools.tests/src/org/eclipse/pde/api/tools/comparator/tests/ClassDeltaSealedTests.java
new file mode 100644
index 00000000000..7270c395157
--- /dev/null
+++ b/apitools/org.eclipse.pde.api.tools.tests/src/org/eclipse/pde/api/tools/comparator/tests/ClassDeltaSealedTests.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2025 SAP SE and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * SAP SE - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.api.tools.comparator.tests;
+
+import static org.assertj.core.api.Assertions.fail;
+import static org.junit.Assert.assertNotNull;
+
+import org.eclipse.pde.api.tools.internal.provisional.VisibilityModifiers;
+import org.eclipse.pde.api.tools.internal.provisional.comparator.ApiComparator;
+import org.eclipse.pde.api.tools.internal.provisional.comparator.IDelta;
+import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
+import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
+import org.junit.Test;
+
+/**
+ * Observes what deltas the API comparator produces for three scenarios,
+ * all starting from a baseline with a {@code final} GC class with a
+ * {@code @noreference} handle field:
+ *
+ *
+ * - test100: final GC + handle → final GC + handle (no modifier change)
+ * - test101: final GC + handle → sealed GC + handle + GCExtension
+ * - test102: final GC + handle → normal GC + handle + GCExtension
+ *
+ *
+ * All tests compile with Java 17.
+ * The tests never fail — they print the resulting deltas to System.out.
+ */
+public class ClassDeltaSealedTests extends DeltaTestSetup {
+
+ @Override
+ public String getTestRoot() {
+ return "class"; //$NON-NLS-1$
+ }
+
+ @Override
+ protected String[] getCompilerOptions() {
+ return new String[] { "-17", "-preserveAllLocals", "-nowarn" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ /**
+ * Scenario 1: final GC + handle → final GC + handle (no modifier change).
+ */
+ @Test
+ public void test100() {
+ observeDeltas("test100"); //$NON-NLS-1$
+ fail("show"); //$NON-NLS-1$
+ }
+
+ /**
+ * Scenario 2: final GC + handle → sealed GC + handle + GCExtension.
+ */
+ @Test
+ public void test101() {
+ observeDeltas("test101"); //$NON-NLS-1$
+ fail("show"); //$NON-NLS-1$
+ }
+
+ /**
+ * Scenario 3: final GC + handle → normal GC + handle + GCExtension.
+ */
+ @Test
+ public void test102() {
+ observeDeltas("test102"); //$NON-NLS-1$
+ fail("show"); //$NON-NLS-1$
+
+ }
+
+ private void observeDeltas(String testName) {
+ deployBundles(testName);
+ IApiBaseline before = getBeforeState();
+ IApiBaseline after = getAfterState();
+ IApiComponent beforeComp = before.getApiComponent(BUNDLE_NAME);
+ assertNotNull("no before api component", beforeComp); //$NON-NLS-1$
+ IApiComponent afterComp = after.getApiComponent(BUNDLE_NAME);
+ assertNotNull("no after api component", afterComp); //$NON-NLS-1$
+
+ IDelta delta = ApiComparator.compare(beforeComp, afterComp, before, after,
+ VisibilityModifiers.ALL_VISIBILITIES, null);
+ assertNotNull("No delta", delta); //$NON-NLS-1$
+
+ System.out.println("=== Deltas for " + testName + " ==="); //$NON-NLS-1$ //$NON-NLS-2$
+ if (delta == ApiComparator.NO_DELTA) {
+ System.out.println(" NO_DELTA"); //$NON-NLS-1$
+ return;
+ }
+ IDelta[] leaves = collectLeaves(delta);
+ System.out.println(" count=" + leaves.length); //$NON-NLS-1$
+ for (IDelta leaf : leaves) {
+ System.out.println(" kind=" + leaf.getKind() //$NON-NLS-1$
+ + " flags=" + leaf.getFlags() //$NON-NLS-1$
+ + " elementType=" + leaf.getElementType() //$NON-NLS-1$
+ + " key=" + leaf.getKey() //$NON-NLS-1$
+ + " msg=" + leaf.getMessage()); //$NON-NLS-1$
+ }
+ }
+}
diff --git a/apitools/org.eclipse.pde.api.tools.tests/src/org/eclipse/pde/api/tools/comparator/tests/DeltaTestSetup.java b/apitools/org.eclipse.pde.api.tools.tests/src/org/eclipse/pde/api/tools/comparator/tests/DeltaTestSetup.java
index 5206a10a7b8..1b3dce8abc3 100644
--- a/apitools/org.eclipse.pde.api.tools.tests/src/org/eclipse/pde/api/tools/comparator/tests/DeltaTestSetup.java
+++ b/apitools/org.eclipse.pde.api.tools.tests/src/org/eclipse/pde/api/tools/comparator/tests/DeltaTestSetup.java
@@ -166,13 +166,21 @@ protected void deployBundle(String testName, String name, String bundleName) {
TestSuiteHelper.getPluginDirectoryPath().append(TESTS_DELTAS_NAME).append(getTestRoot()).append(testName).append(name).toOSString()
};
IPath destinationPath = WORKSPACE_ROOT.append(name).append(bundleName);
- String[] compilerOptions = TestSuiteHelper.getCompilerOptions();
+ String[] compilerOptions = getCompilerOptions();
assertTrue(TestSuiteHelper.compile(sourceFilePaths, destinationPath.toOSString(), compilerOptions));
// copy the MANIFEST in the workspace folder
copyResources(testName, name, destinationPath.toOSString());
}
+ /**
+ * Returns the compiler options to use when compiling test bundles.
+ * Subclasses may override to use a different Java compliance level.
+ */
+ protected String[] getCompilerOptions() {
+ return TestSuiteHelper.getCompilerOptions();
+ }
+
protected void deployBundles(String testName) {
deployBundle(testName, BEFORE);
deployBundle(testName, AFTER);
diff --git a/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test100/after/GC.java b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test100/after/GC.java
new file mode 100644
index 00000000000..3a5a387d921
--- /dev/null
+++ b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test100/after/GC.java
@@ -0,0 +1,8 @@
+public final class GC {
+
+ /**
+ * @noreference This field is not intended to be referenced by clients.
+ */
+ public long handle;
+
+}
diff --git a/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test100/after/X.java b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test100/after/X.java
deleted file mode 100644
index 08eb779d9b1..00000000000
--- a/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test100/after/X.java
+++ /dev/null
@@ -1,15 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-public class X {
-}
\ No newline at end of file
diff --git a/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test100/before/GC.java b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test100/before/GC.java
new file mode 100644
index 00000000000..3a5a387d921
--- /dev/null
+++ b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test100/before/GC.java
@@ -0,0 +1,8 @@
+public final class GC {
+
+ /**
+ * @noreference This field is not intended to be referenced by clients.
+ */
+ public long handle;
+
+}
diff --git a/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test100/before/X.java b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test100/before/X.java
deleted file mode 100644
index a5dc8b825a1..00000000000
--- a/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test100/before/X.java
+++ /dev/null
@@ -1,16 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-public class X {
- protected int i;
-}
\ No newline at end of file
diff --git a/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test100/resources/.api_description b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test100/resources/.api_description
deleted file mode 100644
index 07b3bd40de6..00000000000
--- a/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test100/resources/.api_description
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test100/resources/META-INF/MANIFEST.MF b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test100/resources/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..8675fc98fe9
--- /dev/null
+++ b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test100/resources/META-INF/MANIFEST.MF
@@ -0,0 +1,8 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: deltatest Plug-in
+Bundle-SymbolicName: deltatest
+Bundle-Version: 1.0.0
+Bundle-RequiredExecutionEnvironment: JavaSE-17
+Export-Package: .,
+ p
diff --git a/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test101/after/GC.java b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test101/after/GC.java
new file mode 100644
index 00000000000..7ef34801e8f
--- /dev/null
+++ b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test101/after/GC.java
@@ -0,0 +1,8 @@
+public sealed class GC permits GCExtension {
+
+ /**
+ * @noreference This field is not intended to be referenced by clients.
+ */
+ public long handle;
+
+}
diff --git a/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test101/after/GCExtension.java b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test101/after/GCExtension.java
new file mode 100644
index 00000000000..b26a4f10253
--- /dev/null
+++ b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test101/after/GCExtension.java
@@ -0,0 +1,3 @@
+public final class GCExtension extends GC {
+
+}
diff --git a/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test101/before/GC.java b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test101/before/GC.java
new file mode 100644
index 00000000000..3a5a387d921
--- /dev/null
+++ b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test101/before/GC.java
@@ -0,0 +1,8 @@
+public final class GC {
+
+ /**
+ * @noreference This field is not intended to be referenced by clients.
+ */
+ public long handle;
+
+}
diff --git a/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test101/resources/META-INF/MANIFEST.MF b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test101/resources/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..8675fc98fe9
--- /dev/null
+++ b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test101/resources/META-INF/MANIFEST.MF
@@ -0,0 +1,8 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: deltatest Plug-in
+Bundle-SymbolicName: deltatest
+Bundle-Version: 1.0.0
+Bundle-RequiredExecutionEnvironment: JavaSE-17
+Export-Package: .,
+ p
diff --git a/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test101/resources/after/META-INF/MANIFEST.MF b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test101/resources/after/META-INF/MANIFEST.MF
index 1ef4a178cf8..1c29692403a 100644
--- a/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test101/resources/after/META-INF/MANIFEST.MF
+++ b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test101/resources/after/META-INF/MANIFEST.MF
@@ -6,5 +6,5 @@ Bundle-Name: deltatest Plug-in
Bundle-SymbolicName: deltatest
Bundle-Version: 1.0.0
Bundle-RequiredExecutionEnvironment: J2SE-1.4
-Export-Package: p
-
+Export-Package: .,
+ p
diff --git a/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test102/after/GC.java b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test102/after/GC.java
new file mode 100644
index 00000000000..af4b764c95a
--- /dev/null
+++ b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test102/after/GC.java
@@ -0,0 +1,8 @@
+public class GC {
+
+ /**
+ * @noreference This field is not intended to be referenced by clients.
+ */
+ public long handle;
+
+}
diff --git a/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test102/after/GCExtension.java b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test102/after/GCExtension.java
new file mode 100644
index 00000000000..6af0277170e
--- /dev/null
+++ b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test102/after/GCExtension.java
@@ -0,0 +1,3 @@
+public class GCExtension extends GC {
+
+}
diff --git a/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test102/before/GC.java b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test102/before/GC.java
new file mode 100644
index 00000000000..3a5a387d921
--- /dev/null
+++ b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test102/before/GC.java
@@ -0,0 +1,8 @@
+public final class GC {
+
+ /**
+ * @noreference This field is not intended to be referenced by clients.
+ */
+ public long handle;
+
+}
diff --git a/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test102/resources/META-INF/MANIFEST.MF b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test102/resources/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..8675fc98fe9
--- /dev/null
+++ b/apitools/org.eclipse.pde.api.tools.tests/tests-deltas/class/test102/resources/META-INF/MANIFEST.MF
@@ -0,0 +1,8 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: deltatest Plug-in
+Bundle-SymbolicName: deltatest
+Bundle-Version: 1.0.0
+Bundle-RequiredExecutionEnvironment: JavaSE-17
+Export-Package: .,
+ p