You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@felix.apache.org by "klasch42@gmail.com" <kl...@gmail.com> on 2014/01/03 16:38:55 UTC

IPOJO: ConcurrentModificationException in ProvidedService

Hi
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:

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

Our service:


@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");
    }
}

Thanks for any help
Klaus



--
View this message in context: http://apache-felix.18485.x6.nabble.com/IPOJO-ConcurrentModificationException-in-ProvidedService-tp5006665.html
Sent from the Apache Felix - Dev mailing list archive at Nabble.com.

Re: IPOJO: ConcurrentModificationException in ProvidedService

Posted by Clement Escoffier <cl...@gmail.com>.
Hi,

Nice catch, can you open an issue on https://issues.apache.org/jira/browse/FELIX (select the iPOJO component). I will have a look tomorrow.

Thanks and regards,

Clement

On 3 janv. 2014, at 16:38, klasch42@gmail.com wrote:

> Hi
> 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:
> 
> 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
> 
> Our service:
> 
> 
> @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");
>    }
> }
> 
> Thanks for any help
> Klaus
> 
> 
> 
> --
> View this message in context: http://apache-felix.18485.x6.nabble.com/IPOJO-ConcurrentModificationException-in-ProvidedService-tp5006665.html
> Sent from the Apache Felix - Dev mailing list archive at Nabble.com.