Update deps, use Collections.synchronizedList for serviceList and reentrantLock for lookup method in ServiceContainerImpl
diff --git a/contrib/TurbineYaafiComponentService.java b/contrib/TurbineYaafiComponentService.java
index a723b64..c0f19d0 100644
--- a/contrib/TurbineYaafiComponentService.java
+++ b/contrib/TurbineYaafiComponentService.java
@@ -68,7 +68,7 @@
public TurbineYaafiComponentService()
{
- this.logger = Logger.getLogger(TurbineYaafiComponentService.class);
+ this.logger = LogManager.getLogger(TurbineYaafiComponentService.class);
}
/**
diff --git a/pom.xml b/pom.xml
index 08310c5..a9be07e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,7 +37,7 @@
<connection>scm:git:https://gitbox.apache.org/repos/asf/turbine-fulcrum-yaafi.git</connection>
<developerConnection>scm:git:https://gitbox.apache.org/repos/asf/turbine-fulcrum-yaafi.git</developerConnection>
<url>https://github.com/apache/${turbine.site.path}/tree/${project.scm.tag}</url>
- <tag>fulcrum-yaafi-2.0.0-candidate</tag>
+ <tag>fulcrum-yaafi-2.0.0</tag>
</scm>
<developers>
@@ -66,12 +66,12 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
- <version>3.12.0</version>
+ <version>3.13.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
- <version>2.11.0</version>
+ <version>2.15.0</version>
</dependency>
<!-- use own Log4jLogger avalon adapter and replace other in turbine and testcontainer in upcoming releases -->
@@ -127,7 +127,7 @@
<dependency>
<groupId>org.apache.fulcrum</groupId>
<artifactId>fulcrum-testcontainer</artifactId>
- <version>1.0.9</version>
+ <version>2.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>
diff --git a/src/java/org/apache/fulcrum/yaafi/framework/container/ServiceContainerImpl.java b/src/java/org/apache/fulcrum/yaafi/framework/container/ServiceContainerImpl.java
index c5a554c..74a733d 100644
--- a/src/java/org/apache/fulcrum/yaafi/framework/container/ServiceContainerImpl.java
+++ b/src/java/org/apache/fulcrum/yaafi/framework/container/ServiceContainerImpl.java
@@ -22,9 +22,12 @@
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.ReentrantLock;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
@@ -39,6 +42,7 @@
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.commons.lang3.StringUtils;
import org.apache.fulcrum.yaafi.framework.component.AvalonServiceComponentImpl;
import org.apache.fulcrum.yaafi.framework.component.ServiceComponent;
import org.apache.fulcrum.yaafi.framework.configuration.ComponentConfigurationPropertiesResolver;
@@ -55,8 +59,6 @@
import org.apache.fulcrum.yaafi.framework.util.ToStringBuilder;
import org.apache.fulcrum.yaafi.framework.util.Validate;
-import org.apache.commons.lang3.StringUtils;
-
/**
* Yet another avalon framework implementation (YAAFI).
*
@@ -107,7 +109,7 @@
private List<ServiceComponent> serviceList;
/** The map of services used for the lookup */
- private HashMap<String, ServiceComponent> serviceMap;
+ private Map<String, ServiceComponent> serviceMap;
/** The Avalon role configuration loaded by this class */
private Configuration roleConfiguration;
@@ -146,15 +148,20 @@
private boolean hasDynamicProxies;
/** The list of interceptor services applied to all services */
- private ArrayList<String> defaultInterceptorServiceList;
+ private List<String> defaultInterceptorServiceList;
/** The list of ServiceManagers as fallback service lookup */
- private ArrayList<String> fallbackServiceManagerList;
+ private List<String> fallbackServiceManagerList;
/**
* the configuration for running the ComponentConfigurationPropertiesResolver
*/
private Configuration componentConfigurationPropertiesResolverConfig;
+
+ /**
+ * Lock access during service initialization
+ */
+ private final ReentrantLock serviceLock = new ReentrantLock();
/////////////////////////////////////////////////////////////////////////
// Avalon Service Lifecycle
@@ -180,14 +187,14 @@
this.isAlreadyDisposed = false;
this.isCurrentlyDisposing = false;
- this.serviceList = new ArrayList<ServiceComponent>();
- this.serviceMap = new HashMap<String, ServiceComponent>();
+ this.serviceList = Collections.synchronizedList(new ArrayList<ServiceComponent>());
+ this.serviceMap = new ConcurrentHashMap<String, ServiceComponent>();
this.applicationRootDir = new File(new File("").getAbsolutePath());
this.tempRootDir = new File(System.getProperty("java.io.tmpdir", "."));
- this.fallbackServiceManagerList = new ArrayList<String>();
- this.defaultInterceptorServiceList = new ArrayList<String>();
+ this.fallbackServiceManagerList = Collections.synchronizedList(new ArrayList<String>());
+ this.defaultInterceptorServiceList = Collections.synchronizedList(new ArrayList<String>());
this.disposalDelay = DISPOSAL_DELAY_DEFAULT;
this.reconfigurationDelay = RECONFIGURATION_DELAY_DEFAULT;
@@ -530,14 +537,14 @@
/**
* @see org.apache.fulcrum.yaafi.framework.container.ServiceLifecycleManager#getRoleEntry(java.lang.String)
*/
- public synchronized RoleEntry getRoleEntry(String name) throws ServiceException {
+ public RoleEntry getRoleEntry(String name) throws ServiceException {
return this.getServiceComponentEx(name).getRoleEntry();
}
/**
* @see org.apache.fulcrum.yaafi.framework.container.ServiceLifecycleManager#getRoleEntries()
*/
- public synchronized RoleEntry[] getRoleEntries() {
+ public RoleEntry[] getRoleEntries() {
ServiceComponent serviceComponent;
List<ServiceComponent> serviceList = this.getServiceList();
RoleEntry[] result = new RoleEntry[serviceList.size()];
@@ -581,14 +588,12 @@
return false;
}
- synchronized (this) {
- // look at our available service
- result = this.getLocalServiceComponent(name) != null;
+ // look at our available service
+ result = this.getLocalServiceComponent(name) != null;
- // look at fallback service managers
- if (!result)
- result = this.hasFallbackService(name);
- }
+ // look at fallback service managers
+ if (!result)
+ result = this.hasFallbackService(name);
// if we haven't found anything ask the parent ServiceManager
if (!result && this.hasParentServiceManager())
@@ -613,14 +618,15 @@
Object result = null;
ServiceComponent serviceManagerComponent;
- if (this.isAlreadyDisposed()) {
+ if (this.isAlreadyDisposed())
+ {
String msg = "The container is disposed an no services are available";
this.getLogger().error(msg);
throw new ServiceException(name, msg);
}
+ serviceLock.lock();
try {
- synchronized (this) {
// 1) check our local services
serviceManagerComponent = this.getLocalServiceComponent(name);
@@ -637,22 +643,28 @@
if (result == null) {
result = this.getFallbackService(name);
}
- }
- } catch (ServiceException e) {
+ } catch (ServiceException e)
+ {
String msg = "Failed to lookup a service " + name;
this.getLogger().error(msg, e);
throw e;
- } catch (Throwable t) {
+ } catch (Throwable t)
+ {
String msg = "Failed to lookup a service " + name;
this.getLogger().error(msg, t);
throw new ServiceException(name, msg, t);
- }
+ } finally
+ {
+ serviceLock.unlock();
+ }
// 3) if we haven't found anything ask the parent ServiceManager
- if (result == null && this.hasParentServiceManager()) {
+ if (result == null && this.hasParentServiceManager())
+ {
result = this.getParentServiceManager().lookup(name);
- if (result != null && this.getLogger().isDebugEnabled()) {
+ if (result != null && this.getLogger().isDebugEnabled())
+ {
String msg = "Located the service '" + name + "' using the parent service manager";
this.getLogger().debug(msg);
}
@@ -660,7 +672,8 @@
// if we still haven't found anything then complain
- if (result == null) {
+ if (result == null)
+ {
String msg = "The following component does not exist : " + name;
this.getLogger().error(msg);
throw new ServiceException(AvalonYaafiConstants.AVALON_CONTAINER_YAAFI, name);
@@ -886,7 +899,7 @@
/**
* @return Returns the serviceMap.
*/
- private HashMap<String, ServiceComponent> getServiceMap() {
+ private Map<String, ServiceComponent> getServiceMap() {
return this.serviceMap;
}
@@ -1078,7 +1091,7 @@
// get the default interceptors defined for the container
- ArrayList<String> defaultInterceptorList = this.getDefaultInterceptorServiceList();
+ List<String> defaultInterceptorList = this.getDefaultInterceptorServiceList();
// create the service components based on the role entries
@@ -1366,7 +1379,7 @@
/**
* @return Returns the defaultInterceptorServiceList.
*/
- private ArrayList<String> getDefaultInterceptorServiceList() {
+ private List<String> getDefaultInterceptorServiceList() {
return defaultInterceptorServiceList;
}
diff --git a/src/java/org/apache/fulcrum/yaafi/service/servicemanager/ServiceManagerServiceImpl.java b/src/java/org/apache/fulcrum/yaafi/service/servicemanager/ServiceManagerServiceImpl.java
index 61af981..a31759d 100644
--- a/src/java/org/apache/fulcrum/yaafi/service/servicemanager/ServiceManagerServiceImpl.java
+++ b/src/java/org/apache/fulcrum/yaafi/service/servicemanager/ServiceManagerServiceImpl.java
@@ -73,7 +73,7 @@
/**
* @return the one and only instance of this class
*/
- public static synchronized ServiceManagerService getInstance()
+ public static ServiceManagerService getInstance()
{
return instance;
}