Klaus Schröder created FELIX-4374:
-------------------------------------
Summary: IPOJO: ConcurrentModificationException in ProvidedService
Key: FELIX-4374
URL: https://issues.apache.org/jira/browse/FELIX-4374
Project: Felix
Issue Type: Bug
Components: iPOJO
Affects Versions: ipojo-runtime-1.11.0
Environment: Karaf 2.3.3
Reporter: Klaus Schröder
I have a problem with a ManagedServices and IPOJO.
We have a service that provides externally configured properties. We want to
use the managed service approach to get automatic refreshs of changed
properties. The properties are read from a file
{karaf}/etc/na.default.properties containing ~500 properties and are injected
into the service by @Updated, see code below.
Basically the code works fine, but from time to time the service startup fails
with a ConcurrentModificationException in class ProvidedService. The exception
does not show always, but it is reproducible by starting and stopping the
bundle various times. The code has been stripped down to be very simple and the
problem could still be reproduced.
IPOJO version is 1.11.0, Karaf version 2.3.3
Short stacktrace:
{code}
2014-01-03 16:17:41,357 | INFO | pool-1-thread-1 |
product-properties-services | ? ? | 64 -
product-properties-services - 0.0.1.SNAPSHOT | [INFO]
com.nextaudience.clustor.product.properties.services.DefaultPropertiesResolverService
: An error occurred when creating an instance of
com.nextaudience.clustor.product.properties.services.DefaultPropertiesResolverService
java.util.ConcurrentModificationException
at
java.util.TreeMap$PrivateEntryIterator.nextEntry(TreeMap.java:1115)[:1.7.0_45]
at java.util.TreeMap$ValueIterator.next(TreeMap.java:1160)[:1.7.0_45]
at
org.apache.felix.ipojo.handlers.providedservice.ProvidedService.getServiceProperties(ProvidedService.java:447)[55:org.apache.felix.ipojo:1.11.0]
at
org.apache.felix.ipojo.handlers.providedservice.ProvidedService.registerService(ProvidedService.java:357)[55:org.apache.felix.ipojo:1.11.0]
at
org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler.__M_stateChanged(ProvidedServiceHandler.java:484)[55:org.apache.felix.ipojo:1.11.0]
at
org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler.stateChanged(ProvidedServiceHandler.java)[55:org.apache.felix.ipojo:1.11.0]
at
org.apache.felix.ipojo.InstanceManager.setState(InstanceManager.java:536)[55:org.apache.felix.ipojo:1.11.0]
at
org.apache.felix.ipojo.InstanceManager.start(InstanceManager.java:418)[55:org.apache.felix.ipojo:1.11.0]
at
org.apache.felix.ipojo.ComponentFactory.createInstance(ComponentFactory.java:179)[55:org.apache.felix.ipojo:1.11.0]
at
org.apache.felix.ipojo.IPojoFactory.createComponentInstance(IPojoFactory.java:319)[55:org.apache.felix.ipojo:1.11.0]
at
org.apache.felix.ipojo.IPojoFactory.createComponentInstance(IPojoFactory.java:240)[55:org.apache.felix.ipojo:1.11.0]
at
org.apache.felix.ipojo.extender.internal.linker.ManagedType$InstanceSupport$1.call(ManagedType.java:312)[55:org.apache.felix.ipojo:1.11.0]
at
org.apache.felix.ipojo.extender.internal.linker.ManagedType$InstanceSupport$1.call(ManagedType.java:306)[55:org.apache.felix.ipojo:1.11.0]
at
org.apache.felix.ipojo.extender.internal.queue.JobInfoCallable.call(JobInfoCallable.java:114)[55:org.apache.felix.ipojo:1.11.0]
at java.util.concurrent.FutureTask.run(FutureTask.java:262)[:1.7.0_45]
at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)[:1.7.0_45]
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)[:1.7.0_45]
at java.lang.Thread.run(Thread.java:744)[:1.7.0_45]
2014-01-03 16:17:41,357 | ERROR | pool-1-thread-1 |
product-properties-services | ? ? | 64 -
product-properties-services - 0.0.1.SNAPSHOT | [ERROR]
com.nextaudience.clustor.product.properties.services.DefaultPropertiesResolverService
: null
{code}
Our service:
{code
@Component(managedservice = "na.default.properties", publicFactory = false)
@Instantiate
@Provides
public class DefaultPropertiesResolverService implements
ObservablePropertiesResolver {
private static final Logger LOG =
LoggerFactory.getLogger(DefaultPropertiesResolverService.class);
@ServiceController
private boolean ready;
private Dictionary<String, String> properties;
@Validate
synchronized private void startService() {
LOG.info("startService start...");
if (getProperties() == null) {
LOG.warn("No properties for " + getClass().getName());
return;
}
if (getProperties().isEmpty()) {
LOG.warn("Empty properties for " + getClass().getName());
return;
}
ready = true;
LOG.info(DefaultPropertiesResolverService.class.getName() + "::Start");
}
@Invalidate
synchronized private void stopService() {
ready = false;
LOG.info(DefaultPropertiesResolverService.class.getName() + "::Stop");
}
synchronized public Dictionary<String, String> getProperties() {
return properties;
}
@Updated
synchronized public void updateLocalProperties(Dictionary<String, String>
cfgProperties) {
LOG.info("DefaultProperties: updateLocalProperties start...");
properties = cfgProperties;
LOG.info("DefaultProperties: updateLocalProperties end");
}
}
{code
--
This message was sent by Atlassian JIRA
(v6.1.5#6160)