From 54f078f52110db90099d21fbe38a32e1d2068eac Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Fri, 25 Mar 2011 08:45:22 +1100 Subject: [PATCH] SOLDER-94 fix thread safety issue --- .../beanManager/BeanManagerLocator.java | 91 +++++++++---------- 1 file changed, 44 insertions(+), 47 deletions(-) diff --git a/api/src/main/java/org/jboss/seam/solder/beanManager/BeanManagerLocator.java b/api/src/main/java/org/jboss/seam/solder/beanManager/BeanManagerLocator.java index 28894dab..1c00cd83 100644 --- a/api/src/main/java/org/jboss/seam/solder/beanManager/BeanManagerLocator.java +++ b/api/src/main/java/org/jboss/seam/solder/beanManager/BeanManagerLocator.java @@ -16,66 +16,66 @@ */ package org.jboss.seam.solder.beanManager; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; +import org.jboss.seam.solder.util.Sortable; +import org.jboss.seam.solder.util.service.ServiceLoader; import javax.enterprise.inject.spi.BeanManager; import javax.enterprise.inject.spi.Extension; import javax.inject.Inject; - -import org.jboss.seam.solder.util.Sortable; -import org.jboss.seam.solder.util.service.ServiceLoader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; /** *

* A utility for use in non-managed classes, which are not able to obtain a * reference to the {@link BeanManager} using injection. *

- * + * *

* {@link BeanManagerProvider} is an SPI that may be implemented to allow third * parties to register custom methods of looking up the BeanManager in an * external context. This class will consult implementations according to * precedence. *

- * + * *

* **WARNING** This class is NOT a clever way to get the * BeanManager, and should be avoided at all costs. If you need a handle * to the {@link BeanManager} you should probably register an {@link Extension} * instead of using this class; have you tried using @{@link Inject}? *

- * + * *

* If you think you need to use this class, chat to the community and make sure * you aren't missing a trick! *

- * + * * @see BeanManagerProvider * @see BeanManagerAware - * + * * @author Pete Muir * @author Nicklas Karlsson * @author Dan Allen + * @author Stuart Douglas */ public class BeanManagerLocator { - private BeanManager beanManager; - - private boolean lookupPerformed = false; - - private BeanManagerProvider locatingProvider; + private volatile BeanManager beanManager; + + private volatile boolean lookupPerformed = false; - private List providers; + private volatile BeanManagerProvider locatingProvider; + + private volatile List providers; /** * If a lookup has not yet been performed, consult registered * {@link BeanManagerProvider} implementations to locate the * {@link BeanManager} and return the result. If the {@link BeanManager} * cannot be resolved, throw a {@link BeanManagerUnavailableException}. - * + * * @throws BeanManagerUnavailableException if the BeanManager cannot be resolved * @return the BeanManager for the current bean archive */ @@ -83,14 +83,14 @@ public BeanManager getBeanManager() { if (!lookupPerformed) { - beanManager = lookupBeanManager(); + lookupBeanManager(); } - + if (beanManager == null) { throw new BeanManagerUnavailableException(providers); } - + return beanManager; } @@ -99,7 +99,7 @@ public BeanManager getBeanManager() * {@link BeanManagerProvider} implementations to locate the * {@link BeanManager} and return whether it was found, caching * the result. - * + * * @return true if the bean manager has been found, otherwise * false */ @@ -107,17 +107,17 @@ public boolean isBeanManagerAvailable() { if (!lookupPerformed) { - beanManager = lookupBeanManager(); + lookupBeanManager(); } - + return beanManager != null; } - + /** * Return the {@link BeanManagerProvider} that was used to * locate the BeanManager. This method will not attempt * a lookup. - * + * * @return the BeanManagerProvider implementation */ public BeanManagerProvider getLocatingProvider() @@ -125,36 +125,33 @@ public BeanManagerProvider getLocatingProvider() return locatingProvider; } - private BeanManager lookupBeanManager() + private synchronized void lookupBeanManager() { - BeanManager beanManager = null; - if (providers == null) - { - loadServices(); + if(!lookupPerformed) { + final List providers = loadServices(); Collections.sort(providers, new Sortable.Comparator()); - } - - for (BeanManagerProvider provider : providers) - { - beanManager = provider.getBeanManager(); - if (beanManager != null) + for (BeanManagerProvider provider : providers) { - locatingProvider = provider; - break; + beanManager = provider.getBeanManager(); + if (beanManager != null) + { + locatingProvider = provider; + break; + } } + this.providers = providers; + lookupPerformed = true; } - - lookupPerformed = true; - return beanManager; } - - private void loadServices() + + private List loadServices() { - providers = new ArrayList(); - + List providers = new ArrayList(); + for (Iterator it = ServiceLoader.load(BeanManagerProvider.class).iterator(); it.hasNext();) { providers.add(it.next()); } + return providers; } }