Skip to content

Commit 30f301b

Browse files
authored
Delete LegacyInstancesAreScopedToHudson and associated machinery (#11225)
* Deleting `LegacyInstancesAreScopedToHudson` and associated machinery * In fact we can deprecate external use of the `ExtensionList.<init>(Jenkins, Class, CopyOnWriteArrayList)` constructor #11225 (comment) * Adjusting Javadoc to guide developers to simpler APIs like `ExtensionList.lookup`
1 parent 1c38fe6 commit 30f301b

File tree

6 files changed

+21
-96
lines changed

6 files changed

+21
-96
lines changed

core/src/main/java/hudson/DescriptorExtensionList.java

Lines changed: 7 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,10 @@
3434
import hudson.model.ViewDescriptor;
3535
import hudson.slaves.NodeDescriptor;
3636
import hudson.tasks.Publisher;
37-
import hudson.util.AdaptedIterator;
38-
import hudson.util.Iterators.FlattenIterator;
3937
import java.util.ArrayList;
4038
import java.util.Collection;
4139
import java.util.Collections;
42-
import java.util.Iterator;
4340
import java.util.List;
44-
import java.util.Map;
45-
import java.util.concurrent.ConcurrentHashMap;
46-
import java.util.concurrent.CopyOnWriteArrayList;
4741
import java.util.logging.Level;
4842
import java.util.logging.Logger;
4943
import jenkins.ExtensionComponentSet;
@@ -106,7 +100,7 @@ protected DescriptorExtensionList(Hudson hudson, Class<T> describableType) {
106100
}
107101

108102
protected DescriptorExtensionList(Jenkins jenkins, Class<T> describableType) {
109-
super(jenkins, (Class) Descriptor.class, (CopyOnWriteArrayList) getLegacyDescriptors(describableType));
103+
super(jenkins, (Class) Descriptor.class);
110104
this.describableType = describableType;
111105
}
112106

@@ -238,46 +232,19 @@ private ExtensionList<Descriptor> getDescriptorExtensionList() {
238232
}
239233

240234
/**
241-
* Stores manually registered Descriptor instances. Keyed by the {@link Describable} type.
242-
*/
243-
@SuppressWarnings("rawtypes")
244-
private static final Map<Class, CopyOnWriteArrayList<ExtensionComponent<Descriptor>>> legacyDescriptors = new ConcurrentHashMap<>();
245-
246-
@SuppressWarnings({"unchecked", "rawtypes"})
247-
private static <T extends Describable<T>> CopyOnWriteArrayList<ExtensionComponent<Descriptor>> getLegacyDescriptors(Class<T> type) {
248-
return legacyDescriptors.computeIfAbsent(type, key -> new CopyOnWriteArrayList());
249-
}
250-
251-
/**
252-
* List up all the legacy instances currently in use.
235+
* @deprecated Now always empty.
253236
*/
237+
@Deprecated
254238
public static Iterable<Descriptor> listLegacyInstances() {
255-
return new Iterable<>() {
256-
@Override
257-
public Iterator<Descriptor> iterator() {
258-
return new AdaptedIterator<ExtensionComponent<Descriptor>, Descriptor>(
259-
new FlattenIterator<ExtensionComponent<Descriptor>, CopyOnWriteArrayList<ExtensionComponent<Descriptor>>>(legacyDescriptors.values()) {
260-
@Override
261-
protected Iterator<ExtensionComponent<Descriptor>> expand(CopyOnWriteArrayList<ExtensionComponent<Descriptor>> v) {
262-
return v.iterator();
263-
}
264-
}) {
265-
266-
@Override
267-
protected Descriptor adapt(ExtensionComponent<Descriptor> item) {
268-
return item.getInstance();
269-
}
270-
};
271-
}
272-
};
239+
return List.of();
273240
}
274241

275242
/**
276-
* Exposed just for the test harness. Clear legacy instances.
243+
* @deprecated No longer does anything.
277244
*/
278-
@SuppressFBWarnings(value = "HSM_HIDING_METHOD", justification = "TODO needs triage")
245+
@SuppressFBWarnings(value = "HSM_HIDING_METHOD", justification = "irrelevant now")
246+
@Deprecated
279247
public static void clearLegacyInstances() {
280-
legacyDescriptors.clear();
281248
}
282249

283250
private static final Logger LOGGER = Logger.getLogger(DescriptorExtensionList.class.getName());

core/src/main/java/hudson/ExtensionList.java

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,9 @@
2626

2727
import edu.umd.cs.findbugs.annotations.CheckForNull;
2828
import edu.umd.cs.findbugs.annotations.NonNull;
29-
import hudson.ExtensionPoint.LegacyInstancesAreScopedToHudson;
3029
import hudson.init.InitMilestone;
3130
import hudson.model.Hudson;
3231
import hudson.util.AdaptedIterator;
33-
import hudson.util.DescriptorList;
3432
import hudson.util.Iterators;
3533
import java.util.AbstractList;
3634
import java.util.ArrayList;
@@ -39,11 +37,8 @@
3937
import java.util.IdentityHashMap;
4038
import java.util.Iterator;
4139
import java.util.List;
42-
import java.util.Map;
4340
import java.util.Objects;
4441
import java.util.Set;
45-
import java.util.Vector;
46-
import java.util.concurrent.ConcurrentHashMap;
4742
import java.util.concurrent.CopyOnWriteArrayList;
4843
import java.util.logging.Level;
4944
import java.util.logging.Logger;
@@ -57,22 +52,14 @@
5752
* Retains the known extension instances for the given type 'T'.
5853
*
5954
* <p>
60-
* Extensions are loaded lazily on demand and automatically by using {@link ExtensionFinder}, but this
61-
* class also provides a mechanism to provide compatibility with the older {@link DescriptorList}-based
62-
* manual registration,
63-
*
64-
* <p>
65-
* All {@link ExtensionList} instances should be owned by {@link jenkins.model.Jenkins}, even though
66-
* extension points can be defined by anyone on any type. Use {@link jenkins.model.Jenkins#getExtensionList(Class)}
67-
* and {@link jenkins.model.Jenkins#getDescriptorList(Class)} to obtain the instances.
55+
* Use {@link Extension} to register extensions.
56+
* Use {@link #lookup}, {@link #lookupSingleton}, or {@link #lookupFirst} to find them.
6857
*
6958
* @param <T>
7059
* Type of the extension point. This class holds instances of the subtypes of 'T'.
7160
*
7261
* @author Kohsuke Kawaguchi
7362
* @since 1.286
74-
* @see jenkins.model.Jenkins#getExtensionList(Class)
75-
* @see jenkins.model.Jenkins#getDescriptorList(Class)
7663
*/
7764
public class ExtensionList<T> extends AbstractList<T> implements OnMaster {
7865
/**
@@ -93,7 +80,7 @@ public class ExtensionList<T> extends AbstractList<T> implements OnMaster {
9380
private final List<ExtensionListListener> listeners = new CopyOnWriteArrayList<>();
9481

9582
/**
96-
* Place to store manually registered instances with the per-Hudson scope.
83+
* Place to store manually registered instances.
9784
* {@link CopyOnWriteArrayList} is used here to support concurrent iterations and mutation.
9885
*/
9986
private final CopyOnWriteArrayList<ExtensionComponent<T>> legacyInstances;
@@ -113,20 +100,17 @@ protected ExtensionList(Jenkins jenkins, Class<T> extensionType) {
113100

114101
/**
115102
* @deprecated as of 1.416
116-
* Use {@link #ExtensionList(Jenkins, Class, CopyOnWriteArrayList)}
103+
* Use {@link #ExtensionList(Jenkins, Class)}
117104
*/
118105
@Deprecated
119106
protected ExtensionList(Hudson hudson, Class<T> extensionType, CopyOnWriteArrayList<ExtensionComponent<T>> legacyStore) {
120107
this((Jenkins) hudson, extensionType, legacyStore);
121108
}
122109

123110
/**
124-
*
125-
* @param legacyStore
126-
* Place to store manually registered instances. The version of the constructor that
127-
* omits this uses a new {@link Vector}, making the storage lifespan tied to the life of {@link ExtensionList}.
128-
* If the manually registered instances are scoped to VM level, the caller should pass in a static list.
111+
* @deprecated {@link #ExtensionList(Jenkins, Class)} should suffice
129112
*/
113+
@Deprecated
130114
protected ExtensionList(Jenkins jenkins, Class<T> extensionType, CopyOnWriteArrayList<ExtensionComponent<T>> legacyStore) {
131115
this.hudson = (Hudson) jenkins;
132116
this.jenkins = jenkins;
@@ -437,11 +421,7 @@ public static <T> ExtensionList<T> create(Hudson hudson, Class<T> type) {
437421

438422
@SuppressWarnings({"unchecked", "rawtypes"})
439423
public static <T> ExtensionList<T> create(Jenkins jenkins, Class<T> type) {
440-
if (type.getAnnotation(LegacyInstancesAreScopedToHudson.class) != null)
441-
return new ExtensionList<>(jenkins, type);
442-
else {
443-
return new ExtensionList(jenkins, type, staticLegacyInstances.computeIfAbsent(type, key -> new CopyOnWriteArrayList()));
444-
}
424+
return new ExtensionList<>(jenkins, type);
445425
}
446426

447427
/**
@@ -506,16 +486,10 @@ public static <T> ExtensionList<T> create(Jenkins jenkins, Class<T> type) {
506486
}
507487

508488
/**
509-
* Places to store static-scope legacy instances.
510-
*/
511-
@SuppressWarnings("rawtypes")
512-
private static final Map<Class, CopyOnWriteArrayList> staticLegacyInstances = new ConcurrentHashMap<>();
513-
514-
/**
515-
* Exposed for the test harness to clear all legacy extension instances.
489+
* @deprecated No longer does anything.
516490
*/
491+
@Deprecated
517492
public static void clearLegacyInstances() {
518-
staticLegacyInstances.clear();
519493
}
520494

521495
private static final Logger LOGGER = Logger.getLogger(ExtensionList.class.getName());

core/src/main/java/hudson/ExtensionPoint.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929

3030
import java.lang.annotation.Retention;
3131
import java.lang.annotation.Target;
32-
import jenkins.model.Jenkins;
3332

3433
/**
3534
* Marker interface that designates extensible components
@@ -47,10 +46,9 @@
4746
*/
4847
public interface ExtensionPoint {
4948
/**
50-
* Used by designers of extension points (direct subtypes of {@link ExtensionPoint}) to indicate that
51-
* the legacy instances are scoped to {@link Jenkins} instance. By default, legacy instances are
52-
* static scope.
49+
* @deprecated No longer has any effect.
5350
*/
51+
@Deprecated
5452
@Target(TYPE)
5553
@Retention(RUNTIME)
5654
@interface LegacyInstancesAreScopedToHudson {}

core/src/main/java/hudson/cli/CLICommand.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import hudson.Extension;
3232
import hudson.ExtensionList;
3333
import hudson.ExtensionPoint;
34-
import hudson.ExtensionPoint.LegacyInstancesAreScopedToHudson;
3534
import hudson.Functions;
3635
import hudson.cli.declarative.CLIMethod;
3736
import hudson.cli.declarative.OptionHandlerExtension;
@@ -103,7 +102,6 @@
103102
* @since 1.302
104103
* @see CLIMethod
105104
*/
106-
@LegacyInstancesAreScopedToHudson
107105
public abstract class CLICommand implements ExtensionPoint, Cloneable {
108106

109107
/**

core/src/main/java/hudson/model/AdministrativeMonitor.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import hudson.Extension;
2828
import hudson.ExtensionList;
2929
import hudson.ExtensionPoint;
30-
import hudson.ExtensionPoint.LegacyInstancesAreScopedToHudson;
3130
import hudson.security.Permission;
3231
import hudson.triggers.SCMTrigger;
3332
import hudson.triggers.TimerTrigger;
@@ -88,7 +87,6 @@
8887
* @since 1.273
8988
* @see Jenkins#administrativeMonitors
9089
*/
91-
@LegacyInstancesAreScopedToHudson
9290
public abstract class AdministrativeMonitor extends AbstractModelObject implements ExtensionPoint, StaplerProxy {
9391
/**
9492
* Human-readable ID of this monitor, which needs to be unique within the system.

core/src/main/java/jenkins/model/Jenkins.java

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@
5858
import hudson.ExtensionComponent;
5959
import hudson.ExtensionFinder;
6060
import hudson.ExtensionList;
61-
import hudson.ExtensionPoint;
6261
import hudson.FilePath;
6362
import hudson.Functions;
6463
import hudson.Launcher;
@@ -197,7 +196,6 @@
197196
import hudson.util.Futures;
198197
import hudson.util.HudsonIsLoading;
199198
import hudson.util.HudsonIsRestarting;
200-
import hudson.util.Iterators;
201199
import hudson.util.JenkinsReloadFailed;
202200
import hudson.util.LogTaskListener;
203201
import hudson.util.MultipartFormDataParser;
@@ -1507,8 +1505,7 @@ public CloudSet getCloud() {
15071505
*/
15081506
@SuppressWarnings("rawtypes") // too late to fix
15091507
public Descriptor getDescriptor(String id) {
1510-
// legacy descriptors that are registered manually doesn't show up in getExtensionList, so check them explicitly.
1511-
Iterable<Descriptor> descriptors = Iterators.sequence(getExtensionList(Descriptor.class), DescriptorExtensionList.listLegacyInstances());
1508+
Iterable<Descriptor> descriptors = getExtensionList(Descriptor.class);
15121509
for (Descriptor d : descriptors) {
15131510
if (d.getId().equals(id)) {
15141511
return d;
@@ -2817,14 +2814,7 @@ public Lifecycle getLifecycle() {
28172814
}
28182815

28192816
/**
2820-
* Returns {@link ExtensionList} that retains the discovered instances for the given extension type.
2821-
*
2822-
* @param extensionType
2823-
* The base type that represents the extension point. Normally {@link ExtensionPoint} subtype
2824-
* but that's not a hard requirement.
2825-
* @return
2826-
* Can be an empty list but never null.
2827-
* @see ExtensionList#lookup
2817+
* An obsolete alias for {@link ExtensionList#lookup}.
28282818
*/
28292819
@SuppressWarnings("unchecked")
28302820
public <T> ExtensionList<T> getExtensionList(Class<T> extensionType) {
@@ -2848,7 +2838,7 @@ public ExtensionList getExtensionList(String extensionType) throws ClassNotFound
28482838
/**
28492839
* Returns {@link ExtensionList} that retains the discovered {@link Descriptor} instances for the given
28502840
* kind of {@link Describable}.
2851-
*
2841+
* <p>Assuming an appropriate {@link Descriptor} subtype, for most purposes you can simply use {@link ExtensionList#lookup}.
28522842
* @return
28532843
* Can be an empty list but never null.
28542844
*/

0 commit comments

Comments
 (0)