diff --git a/core/src/main/java/hudson/DescriptorExtensionList.java b/core/src/main/java/hudson/DescriptorExtensionList.java index f2b6ad35d962a4f18bc7bde3fbf512729b2f755c..508481c1a88660c6c3ac2c42725ef0ab5fd22b49 100644 --- a/core/src/main/java/hudson/DescriptorExtensionList.java +++ b/core/src/main/java/hudson/DescriptorExtensionList.java @@ -26,12 +26,12 @@ package hudson; import hudson.model.Descriptor; import hudson.model.Describable; import hudson.model.Hudson; +import hudson.util.Memoizer; import java.util.List; import java.util.ArrayList; import java.util.logging.Logger; import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.ConcurrentHashMap; import java.lang.reflect.Type; import java.lang.reflect.ParameterizedType; @@ -52,7 +52,7 @@ public final class DescriptorExtensionList> extends Ext private final Class describableType; public DescriptorExtensionList(Hudson hudson, Class describableType) { - super(hudson, (Class)Descriptor.class,allocateLegacyInstanceStore(describableType)); + super(hudson, (Class)Descriptor.class, legacyDescriptors.get(describableType)); this.describableType = describableType; } @@ -78,19 +78,17 @@ public final class DescriptorExtensionList> extends Ext * Obtain the statically-scoped storage to store manulaly registered {@link Descriptor}s. */ private static List allocateLegacyInstanceStore(Class describableType) { - List r = legacyDescriptors.get(describableType); - if(r!=null) return r; - - r = new CopyOnWriteArrayList(); - List x = legacyDescriptors.putIfAbsent(describableType, r); - if(x==null) return r; - return x; + return legacyDescriptors.get(describableType); } /** * Stores manually registered Descriptor instances. */ - private static final ConcurrentHashMap legacyDescriptors = new ConcurrentHashMap(); + private static final Memoizer legacyDescriptors = new Memoizer() { + public List compute(Class key) { + return new CopyOnWriteArrayList(); + } + }; private static final Logger LOGGER = Logger.getLogger(DescriptorExtensionList.class.getName()); } diff --git a/core/src/main/java/hudson/ExtensionList.java b/core/src/main/java/hudson/ExtensionList.java index e781750d0c0060d3e7ccb5c5029f470144d2c58d..ea642ef2462c123d1cc852a2d0e55582d9a8a8e0 100644 --- a/core/src/main/java/hudson/ExtensionList.java +++ b/core/src/main/java/hudson/ExtensionList.java @@ -25,6 +25,8 @@ package hudson; import hudson.model.Hudson; import hudson.util.DescriptorList; +import hudson.util.Memoizer; +import hudson.ExtensionPoint.LegacyInstancesAreScopedToHudson; import java.util.AbstractList; import java.util.ArrayList; @@ -33,6 +35,7 @@ import java.util.Iterator; import java.util.List; import java.util.Vector; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ConcurrentHashMap; /** * Retains the known extension instances for the given type 'T'. @@ -174,6 +177,19 @@ public class ExtensionList extends AbstractList { return Collections.singleton(new ExtensionFinder.Sezpoz()); } }; - return new ExtensionList(hudson,type); + if(type.getAnnotation(LegacyInstancesAreScopedToHudson.class)!=null) + return new ExtensionList(hudson,type); + else { + return new ExtensionList(hudson,type,staticLegacyInstances.get(type)); + } } + + /** + * Places to store static-scope legacy instances. + */ + private static final Memoizer staticLegacyInstances = new Memoizer() { + public List compute(Class key) { + return new CopyOnWriteArrayList(); + } + }; } diff --git a/core/src/main/java/hudson/ExtensionPoint.java b/core/src/main/java/hudson/ExtensionPoint.java index bacc75a4d292fe6ead175e3596735e44bd5f007c..613a142dd7faa1b61a526dc416fb8cf5027a2846 100644 --- a/core/src/main/java/hudson/ExtensionPoint.java +++ b/core/src/main/java/hudson/ExtensionPoint.java @@ -23,6 +23,13 @@ */ package hudson; +import hudson.model.Hudson; + +import static java.lang.annotation.ElementType.TYPE; +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Target; + /** * Marker interface that designates extensible components * in Hudson that can be implemented by plugins. @@ -41,4 +48,12 @@ package hudson; * @see Extension */ public interface ExtensionPoint { + /** + * Used by designers of extension points (direct subtypes of {@link ExtensionPoint}) to indicate that + * the legacy instances are scoped to {@link Hudson} instance. By default, legacy instances are + * static scope. + */ + @Target(TYPE) + @Retention(RUNTIME) + public @interface LegacyInstancesAreScopedToHudson {} } diff --git a/core/src/main/java/hudson/model/AdministrativeMonitor.java b/core/src/main/java/hudson/model/AdministrativeMonitor.java index aed8ce8a216946665f05fec900fe5b922df9b646..e36989dc9934eededdaa1560b14c44b60a9da171 100644 --- a/core/src/main/java/hudson/model/AdministrativeMonitor.java +++ b/core/src/main/java/hudson/model/AdministrativeMonitor.java @@ -26,6 +26,7 @@ package hudson.model; import hudson.ExtensionPoint; import hudson.ExtensionList; import hudson.Extension; +import hudson.ExtensionPoint.LegacyInstancesAreScopedToHudson; import hudson.triggers.SCMTrigger; import hudson.triggers.TimerTrigger; @@ -72,6 +73,7 @@ import org.kohsuke.stapler.StaplerResponse; * @since 1.273 * @see Hudson#administrativeMonitors */ +@LegacyInstancesAreScopedToHudson public abstract class AdministrativeMonitor extends AbstractModelObject implements ExtensionPoint { /** * Human-readable ID of this monitor, which needs to be unique within the system. diff --git a/core/src/main/java/hudson/model/Hudson.java b/core/src/main/java/hudson/model/Hudson.java index e3668e09edc3b5949f4168f3a563827247377578..c1b81dd8283cded921730724ed804c1be66f844a 100644 --- a/core/src/main/java/hudson/model/Hudson.java +++ b/core/src/main/java/hudson/model/Hudson.java @@ -106,6 +106,7 @@ import hudson.util.XStream2; import hudson.util.HudsonIsRestarting; import hudson.util.DescribableList; import hudson.util.Futures; +import hudson.util.Memoizer; import hudson.widgets.Widget; import net.sf.json.JSONObject; import org.acegisecurity.*; @@ -281,12 +282,20 @@ public final class Hudson extends Node implements ItemGroup, Stapl /** * All {@link ExtensionList} keyed by their {@link ExtensionList#extensionType}. */ - private transient final ConcurrentHashMap extensionLists = new ConcurrentHashMap(); + private transient final Memoizer extensionLists = new Memoizer() { + public ExtensionList compute(Class key) { + return ExtensionList.create(Hudson.this,key); + } + }; /** * All {@link DescriptorExtensionList} keyed by their {@link DescriptorExtensionList#describableType}. */ - private transient final ConcurrentHashMap descriptorLists = new ConcurrentHashMap(); + private transient final Memoizer descriptorLists = new Memoizer() { + public DescriptorExtensionList compute(Class key) { + return new DescriptorExtensionList(Hudson.this,key); + } + }; /** * Active {@link Cloud}s. @@ -631,7 +640,7 @@ public final class Hudson extends Node implements ItemGroup, Stapl * Gets the repository browser descriptor by name. Primarily used for making them web-visible. */ public Descriptor> getRepositoryBrowser(String shortClassName) { - return findDescriptor(shortClassName,RepositoryBrowsers.LIST); + return findDescriptor(shortClassName,RepositoryBrowser.all()); } /** @@ -1468,15 +1477,7 @@ public final class Hudson extends Node implements ItemGroup, Stapl */ @SuppressWarnings({"unchecked"}) public ExtensionList getExtensionList(Class extensionType) { - // by far the common case is where we find an instance already created. - ExtensionList r = extensionLists.get(extensionType); - if(r!=null) return r; - - // if we have to create a new one, make sure we don't create two at the same time. - r = ExtensionList.create(this,extensionType); - ExtensionList x = extensionLists.putIfAbsent(extensionType, r); - if(x==null) return r; - else return x; + return extensionLists.get(extensionType); } /** @@ -1488,15 +1489,7 @@ public final class Hudson extends Node implements ItemGroup, Stapl */ @SuppressWarnings({"unchecked"}) public > DescriptorExtensionList getDescriptorList(Class type) { - // by far the common case is where we find an instance already created. - DescriptorExtensionList r = descriptorLists.get(type); - if(r!=null) return r; - - // if we have to create a new one, make sure we don't create two at the same time. - r = new DescriptorExtensionList(this,type); - DescriptorExtensionList x = descriptorLists.putIfAbsent(type, r); - if(x==null) return r; - else return x; + return descriptorLists.get(type); } /** diff --git a/core/src/main/java/hudson/scm/RepositoryBrowser.java b/core/src/main/java/hudson/scm/RepositoryBrowser.java index 5aa6366125d2e68e0cf9ad398f4ea89599f9a88e..07b2f4f47b6da9079f9e58f58e8b8a675cbe518d 100644 --- a/core/src/main/java/hudson/scm/RepositoryBrowser.java +++ b/core/src/main/java/hudson/scm/RepositoryBrowser.java @@ -24,7 +24,12 @@ package hudson.scm; import hudson.ExtensionPoint; +import hudson.DescriptorExtensionList; +import hudson.Extension; +import hudson.tasks.BuildWrapper; import hudson.model.Describable; +import hudson.model.Descriptor; +import hudson.model.Hudson; import java.io.IOException; import java.io.Serializable; @@ -44,8 +49,7 @@ import java.net.MalformedURLException; * {@link RepositoryBrowser} is persisted with {@link SCM}. * *

- * To have Hudson recognize {@link RepositoryBrowser}, add the descriptor - * to {@link RepositoryBrowsers#LIST}. + * To have Hudson recognize {@link RepositoryBrowser}, put {@link Extension} on your {@link Descriptor}. * * @author Kohsuke Kawaguchi * @since 1.89 @@ -90,5 +94,16 @@ public abstract class RepositoryBrowser implements } } + public Descriptor> getDescriptor() { + return Hudson.getInstance().getDescriptor(getClass()); + } + + /** + * Returns all the registered {@link RepositoryBrowser} descriptors. + */ + public static DescriptorExtensionList> all() { + return (DescriptorExtensionList)Hudson.getInstance().getDescriptorList(RepositoryBrowser.class); + } + private static final long serialVersionUID = 1L; } diff --git a/core/src/main/java/hudson/scm/RepositoryBrowsers.java b/core/src/main/java/hudson/scm/RepositoryBrowsers.java index 26e793a004ff3e8dc76bd77bfc6e3387061f11aa..ced9128be6c04d0e62dd14a6e4ac06be80600d21 100644 --- a/core/src/main/java/hudson/scm/RepositoryBrowsers.java +++ b/core/src/main/java/hudson/scm/RepositoryBrowsers.java @@ -24,8 +24,11 @@ package hudson.scm; import hudson.model.Descriptor; +import hudson.model.Hudson; import hudson.model.Descriptor.FormException; import hudson.scm.browsers.*; +import hudson.util.DescriptorList; +import hudson.Extension; import org.kohsuke.stapler.StaplerRequest; import java.util.ArrayList; @@ -42,23 +45,18 @@ import net.sf.json.JSONArray; public class RepositoryBrowsers { /** * List of all installed {@link RepositoryBrowsers}. + * + * @deprecated as of 1.286. + * Use {@link RepositoryBrowser#all()} for read access and {@link Extension} for registration. */ - public static final List>> LIST = Descriptor.toList( - ViewCVS.DESCRIPTOR, - ViewSVN.DescriptorImpl.INSTANCE, - FishEyeSVN.DESCRIPTOR, - FishEyeCVS.DESCRIPTOR, - WebSVN.DESCRIPTOR, - Sventon.DESCRIPTOR, - CollabNetSVN.DESCRIPTOR - ); + public static final List>> LIST = new DescriptorList>((Class)RepositoryBrowser.class); /** * Only returns those {@link RepositoryBrowser} descriptors that extend from the given type. */ public static List>> filter(Class t) { List>> r = new ArrayList>>(); - for (Descriptor> d : LIST) + for (Descriptor> d : RepositoryBrowser.all()) if(t.isAssignableFrom(d.clazz)) r.add(d); return r; diff --git a/core/src/main/java/hudson/scm/browsers/CollabNetSVN.java b/core/src/main/java/hudson/scm/browsers/CollabNetSVN.java index 92fb8b1eee7804fc17260b75eed13bc683f8eddb..411a32dd334c8f2bf1fc89df480973d0fb858fe2 100644 --- a/core/src/main/java/hudson/scm/browsers/CollabNetSVN.java +++ b/core/src/main/java/hudson/scm/browsers/CollabNetSVN.java @@ -24,10 +24,13 @@ package hudson.scm.browsers; import hudson.model.Descriptor; +import hudson.model.Descriptor.FormException; import hudson.scm.EditType; import hudson.scm.RepositoryBrowser; import hudson.scm.SubversionChangeLogSet; import hudson.scm.SubversionRepositoryBrowser; +import hudson.Extension; + import java.io.IOException; import java.net.URL; import net.sf.json.JSONObject; @@ -42,19 +45,17 @@ import org.kohsuke.stapler.StaplerRequest; */ public class CollabNetSVN extends SubversionRepositoryBrowser { - public static final Descriptor> DESCRIPTOR - = new Descriptor>() { + @Extension + public static class DescriptorImpl extends Descriptor> { public String getDisplayName() { return "CollabNet"; } - @Override - public RepositoryBrowser newInstance(StaplerRequest req, - JSONObject formData) throws FormException { + public RepositoryBrowser newInstance(StaplerRequest req, JSONObject formData) throws FormException { return req.bindParameters(CollabNetSVN.class, "collabnet.svn."); } - }; + } public final URL url; @@ -110,12 +111,4 @@ public class CollabNetSVN extends SubversionRepositoryBrowser query.add("view=rev"); return new URL(url, query.toString()); } - - - /** - * {@inheritDoc} - */ - public Descriptor> getDescriptor() { - return DESCRIPTOR; - } } diff --git a/core/src/main/java/hudson/scm/browsers/FishEyeCVS.java b/core/src/main/java/hudson/scm/browsers/FishEyeCVS.java index f74e996c4f8d51ba9f8aec8529a116eb9a909a6c..8e952b8509162b21786ad6c0642e7f5db825427c 100644 --- a/core/src/main/java/hudson/scm/browsers/FishEyeCVS.java +++ b/core/src/main/java/hudson/scm/browsers/FishEyeCVS.java @@ -24,6 +24,7 @@ package hudson.scm.browsers; import hudson.Util; +import hudson.Extension; import hudson.model.Descriptor; import hudson.model.Hudson; import hudson.scm.CVSChangeLogSet; @@ -76,12 +77,7 @@ public final class FishEyeCVS extends CVSRepositoryBrowser { return null; } - public DescriptorImpl getDescriptor() { - return DESCRIPTOR; - } - - public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl(); - + @Extension public static class DescriptorImpl extends Descriptor> { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/scm/browsers/FishEyeSVN.java b/core/src/main/java/hudson/scm/browsers/FishEyeSVN.java index e2e254107d9c638c56f8eb60de7ee43d374d609b..218eace79f8551a84cfa3e4a8bf805d183b7a935 100644 --- a/core/src/main/java/hudson/scm/browsers/FishEyeSVN.java +++ b/core/src/main/java/hudson/scm/browsers/FishEyeSVN.java @@ -32,6 +32,7 @@ import hudson.scm.SubversionChangeLogSet.Path; import hudson.scm.SubversionRepositoryBrowser; import hudson.scm.EditType; import hudson.util.FormFieldValidator; +import hudson.Extension; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.DataBoundConstructor; @@ -121,12 +122,7 @@ public class FishEyeSVN extends SubversionRepositoryBrowser { return new URL(url,"../../changelog/"+getProjectName()+"/?cs="+changeSet.getRevision()); } - public Descriptor> getDescriptor() { - return DESCRIPTOR; - } - - public static final Descriptor> DESCRIPTOR = new DescriptorImpl(); - + @Extension public static class DescriptorImpl extends Descriptor> { public String getDisplayName() { return "FishEye"; diff --git a/core/src/main/java/hudson/scm/browsers/Sventon.java b/core/src/main/java/hudson/scm/browsers/Sventon.java index dcd3a234114cf920162610fd248d19f75009fe64..5e70a3892d1f7315db95e3034c9059fb7bf295c3 100644 --- a/core/src/main/java/hudson/scm/browsers/Sventon.java +++ b/core/src/main/java/hudson/scm/browsers/Sventon.java @@ -31,6 +31,7 @@ import hudson.scm.SubversionChangeLogSet.Path; import hudson.scm.SubversionRepositoryBrowser; import hudson.scm.EditType; import hudson.util.FormFieldValidator; +import hudson.Extension; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.DataBoundConstructor; @@ -121,12 +122,7 @@ public class Sventon extends SubversionRepositoryBrowser { repositoryInstance,changeSet.getRevision())); } - public Descriptor> getDescriptor() { - return DESCRIPTOR; - } - - public static final Descriptor> DESCRIPTOR = new DescriptorImpl(); - + @Extension public static class DescriptorImpl extends Descriptor> { public String getDisplayName() { return "Sventon"; diff --git a/core/src/main/java/hudson/scm/browsers/ViewCVS.java b/core/src/main/java/hudson/scm/browsers/ViewCVS.java index 59af93d2af1b98f7b46dcf0ab4bd691af51b0f95..b5106cd2f4c1564fadead91dd1469502d77c702b 100644 --- a/core/src/main/java/hudson/scm/browsers/ViewCVS.java +++ b/core/src/main/java/hudson/scm/browsers/ViewCVS.java @@ -29,6 +29,7 @@ import hudson.scm.CVSChangeLogSet.File; import hudson.scm.CVSChangeLogSet.Revision; import hudson.scm.CVSRepositoryBrowser; import hudson.scm.RepositoryBrowser; +import hudson.Extension; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.DataBoundConstructor; @@ -79,15 +80,12 @@ public final class ViewCVS extends CVSRepositoryBrowser { return new QueryBuilder(url.getQuery()); } - public Descriptor> getDescriptor() { - return DESCRIPTOR; - } - - public static final Descriptor> DESCRIPTOR = new Descriptor>() { + @Extension + public static class DescriptorImpl extends Descriptor> { public String getDisplayName() { return "ViewCVS"; } - }; + } private static final long serialVersionUID = 1L; } diff --git a/core/src/main/java/hudson/scm/browsers/ViewSVN.java b/core/src/main/java/hudson/scm/browsers/ViewSVN.java index 271c79f5d18f1f952c04828d06abd4c0f2f1888d..16827e254585693764e769a6dac52530293cd159 100644 --- a/core/src/main/java/hudson/scm/browsers/ViewSVN.java +++ b/core/src/main/java/hudson/scm/browsers/ViewSVN.java @@ -29,6 +29,7 @@ import hudson.scm.RepositoryBrowser; import hudson.scm.SubversionChangeLogSet; import hudson.scm.SubversionChangeLogSet.Path; import hudson.scm.SubversionRepositoryBrowser; +import hudson.Extension; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.DataBoundConstructor; @@ -80,15 +81,10 @@ public class ViewSVN extends SubversionRepositoryBrowser { return new QueryBuilder(url.getQuery()); } - public DescriptorImpl getDescriptor() { - return DescriptorImpl.INSTANCE; - } - private static final long serialVersionUID = 1L; + @Extension public static final class DescriptorImpl extends Descriptor> { - public static final DescriptorImpl INSTANCE = new DescriptorImpl(); - public String getDisplayName() { return "ViewSVN"; } diff --git a/core/src/main/java/hudson/scm/browsers/WebSVN.java b/core/src/main/java/hudson/scm/browsers/WebSVN.java index 2878f7944a611de136f2244b539ed8ae67b7ef0b..68d5eb6fdecc7c8bdd24224cf03d4b1f112d4177 100644 --- a/core/src/main/java/hudson/scm/browsers/WebSVN.java +++ b/core/src/main/java/hudson/scm/browsers/WebSVN.java @@ -32,6 +32,7 @@ import hudson.scm.SubversionChangeLogSet; import hudson.scm.SubversionChangeLogSet.Path; import hudson.scm.SubversionRepositoryBrowser; +import hudson.Extension; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.DataBoundConstructor; @@ -51,12 +52,12 @@ import java.net.URL; */ public class WebSVN extends SubversionRepositoryBrowser { - public static final Descriptor> DESCRIPTOR = - new Descriptor>() { - public String getDisplayName() { - return "WebSVN"; - } - }; + @Extension + public static class DescriptorImpl extends Descriptor> { + public String getDisplayName() { + return "WebSVN"; + } + } private static final long serialVersionUID = 1L; @@ -135,13 +136,4 @@ public class WebSVN extends SubversionRepositoryBrowser { private QueryBuilder param() { return new QueryBuilder(url.getQuery()); } - - /** - * Returns the descriptor value. - * - * @return the descriptor value. - */ - public Descriptor> getDescriptor() { - return DESCRIPTOR; - } } diff --git a/core/src/main/java/hudson/util/Memoizer.java b/core/src/main/java/hudson/util/Memoizer.java new file mode 100644 index 0000000000000000000000000000000000000000..fab3229a205df4714327d7999b811d25efebaa7d --- /dev/null +++ b/core/src/main/java/hudson/util/Memoizer.java @@ -0,0 +1,61 @@ +/* + * The MIT License + * + * Copyright (c) 2004-2009, Sun Microsystems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.util; + +import java.util.concurrent.ConcurrentHashMap; + +/** + * Implements memoization semantics. + * + *

+ * Conceputually a function from K -> V that computes values lazily and remembers the results. + * Often used to implement a data store per key. + * + * @author Kohsuke Kawaguchi + * @since 1.281 + */ +public abstract class Memoizer { + private final ConcurrentHashMap store = new ConcurrentHashMap(); + + public V get(K key) { + V v = store.get(key); + if(v!=null) return v; + + // TODO: if we want to, we can avoid locking altogether by putting a sentinel value + // that represents "the value is being computed". FingerprintMap does this. + synchronized (this) { + v = store.get(key); + if(v!=null) return v; + + v = compute(key); + store.put(key,v); + return v; + } + } + + /** + * Creates a new instance. + */ + public abstract V compute(K key); +} diff --git a/test/src/main/java/org/jvnet/hudson/test/HudsonTestCase.java b/test/src/main/java/org/jvnet/hudson/test/HudsonTestCase.java index 4438c3d56ed86b9645f5617a6275ce3e7c14faa9..80b7e9d5f5caedde52cfa264473ec0cdb05c950e 100644 --- a/test/src/main/java/org/jvnet/hudson/test/HudsonTestCase.java +++ b/test/src/main/java/org/jvnet/hudson/test/HudsonTestCase.java @@ -30,7 +30,6 @@ import hudson.WebAppMain; import hudson.Launcher.LocalLauncher; import hudson.matrix.MatrixProject; import hudson.maven.MavenModuleSet; -import hudson.maven.MavenReporters; import hudson.model.Descriptor; import hudson.model.FreeStyleProject; import hudson.model.Hudson; @@ -300,7 +299,7 @@ public abstract class HudsonTestCase extends TestCase { String home = System.getProperty("maven.home"); if(home!=null) { MavenInstallation mavenInstallation = new MavenInstallation("default",home); - Maven.DESCRIPTOR.setInstallations(mavenInstallation); + ((Maven.DescriptorImpl)hudson.getDescriptor(Maven.class)).setInstallations(mavenInstallation); return mavenInstallation; } @@ -320,7 +319,7 @@ public abstract class HudsonTestCase extends TestCase { MavenInstallation mavenInstallation = new MavenInstallation("default", new File(mvnHome,"maven-2.0.7").getAbsolutePath()); - Maven.DESCRIPTOR.setInstallations(mavenInstallation); + ((Maven.DescriptorImpl)hudson.getDescriptor(Maven.class)).setInstallations(mavenInstallation); return mavenInstallation; }