Skip to content

Commit 5b02554

Browse files
committed
Restore supplier-disposal link in ClassRequestor without jakarta
PR eclipse-platform#2649 decoupled the E4 injector from jakarta annotations by replacing the ClassRequestor pseudo-dependency descriptor with an empty array. That pseudo-link is what notifies an injected object when its supplier is disposed. With an empty descriptor the link is no longer established, so @PreDestroy of objects that only use constructor/@PostConstruct injection (no @Inject links) is no longer guaranteed to run before the supplying context is disposed. This broke disposal ordering and surfaced as a failure of PartRenderingEngineTests.testBut336225 ("The shell should not have been disposed first"), reported in eclipse-platform#2700. Restore a non-empty, optional descriptor without re-introducing jakarta: use a private marker interface InjectionLink that is never available from any supplier together with e4's own @optional annotation. This keeps the injector free of specific jakarta annotation classes (the goal of eclipse-platform#2649) while re-establishing the supplier-disposal link. Fixes eclipse-platform#2700
1 parent b721651 commit 5b02554

1 file changed

Lines changed: 26 additions & 1 deletion

File tree

runtime/bundles/org.eclipse.e4.core.di/src/org/eclipse/e4/core/internal/di/ClassRequestor.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
*******************************************************************************/
1414
package org.eclipse.e4.core.internal.di;
1515

16+
import java.lang.reflect.Field;
1617
import org.eclipse.e4.core.di.IInjector;
1718
import org.eclipse.e4.core.di.InjectionException;
19+
import org.eclipse.e4.core.di.annotations.Optional;
1820
import org.eclipse.e4.core.di.suppliers.IObjectDescriptor;
1921
import org.eclipse.e4.core.di.suppliers.PrimaryObjectSupplier;
2022

@@ -26,7 +28,30 @@
2628
*/
2729
public class ClassRequestor extends Requestor<Class<?>> {
2830

29-
private static IObjectDescriptor[] pseudoVariableDescriptor = {};
31+
/**
32+
* Marker type for the pseudo dependency. It is intentionally never available
33+
* from any supplier, so the (optional) dependency never resolves to a value.
34+
* Its sole purpose is to provide a non-empty, optional descriptor that
35+
* establishes the link between the supplier and the injected object, so that
36+
* the injected object is notified on the supplier's disposal.
37+
*/
38+
private interface InjectionLink {
39+
// marker interface
40+
}
41+
42+
@Optional
43+
private static final InjectionLink PSEUDO_VARIABLE = null;
44+
45+
private static final IObjectDescriptor[] pseudoVariableDescriptor = createDescriptor();
46+
47+
private static IObjectDescriptor[] createDescriptor() {
48+
try {
49+
Field field = ClassRequestor.class.getDeclaredField("PSEUDO_VARIABLE"); //$NON-NLS-1$
50+
return new IObjectDescriptor[] { new ObjectDescriptor(field.getGenericType(), field.getAnnotations()) };
51+
} catch (NoSuchFieldException e) {
52+
throw new IllegalStateException(e); // the field is declared right above, this cannot happen
53+
}
54+
}
3055

3156
public ClassRequestor(Class<?> clazz, IInjector injector, PrimaryObjectSupplier primarySupplier, PrimaryObjectSupplier tempSupplier, Object requestingObject, boolean track) {
3257
super(clazz, injector, primarySupplier, tempSupplier, requestingObject, track);

0 commit comments

Comments
 (0)