OK - worked it out.

It was not an issue with CXF or really with Felix. I had two logging
services running within Felix,
The Felix logging service, and the OPS4J logging service (which I added
for the OPS4J Web service).

After removing the Felix log service, everything started up fine without
any deadlocks.

Regards,


                        Chris Clark  
                        
                        Senior developer
                        Vodafone NL Account
                        EDS MtI Team
                        EDS, an HP Company
                        Avenue Ceramique 241
                        6221 KX Maastricht NL
                        Chamber of Commerce: 27161118
                        Office: +31 887501769
                        Mobile: +31 6 15036556
                        Web: www.eds.nl <http://www.eds.nl/> 

                        This email contains information which is
confidential and may be privileged. Unless you are the intended
addressee (or authorised to receive for the addressee) you may not use,
forward, copy or disclose to anyone this email or any information
contained in this email. If you have received this email in error,
please advise the sender by reply email immediately and delete this
email. 


                _____________________________________________
                From: Clark, Chris 
                Sent: 30 July 2009 10:08
                To: '[email protected]'
                Subject: Deadlock in CXF DOSGi implementation (latest
1.1 snapshot)
                

                Hi

                When trying to use the latest CXF DOSGi RI (multibundle)
together with Apache Felix 1.8.1 I noticed a thread deadlock when
starting
                Up - this occurs on the startup of the last bundle in
the list, cxf-dosgi-ri-dsw-cxf-1.1-SNAPSHOT.jar.

                The last log entry I see is:

                [FelixStartLevel] INFO
org.apache.cxf.dosgi.dsw.hooks.AbstractClientHook - looku
                p discovery service: interface:
org.osgi.service.event.EventHandler filter: (|(e
        
vent.topics=\*)(event.topics=org/\*)(event.topics=org/osgi/\*)(event.top
ics=org/
        
osgi/service/\*)(event.topics=org/osgi/service/log/\*)(event.topics=org/
osgi/ser
        
vice/log/LogEntry/\*)(event.topics=org/osgi/service/log/LogEntry/LOG_DEB
UG))
                [9818...@qtp-4171180-0 - /system/console/logs] DEBUG
org.mortbay.jetty - REQUEST
                 /system/console/logs on
org.mortbay.jetty.httpconnect...@19b808a

                When using jconsole (I am running on JDK 6.0 u14), these
are the deadlocks:

                [1]
                
                Name: FelixStartLevel
                State: BLOCKED on java.util.st...@39f16f owned by:
Thread-4
                Total blocked: 70  Total waited: 46

                Stack trace: 
        
org.apache.felix.log.LogListenerThread.addEntry(LogListenerThread.java:5
2)
                org.apache.felix.log.Log.addEntry(Log.java:125)
                   - locked org.apache.felix.log....@1637d45
                org.apache.felix.log.Log.serviceChanged(Log.java:263)
        
org.apache.felix.framework.util.EventDispatcher.invokeServiceListenerCal
lback(EventDispatcher.java:846)
        
org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(Eve
ntDispatcher.java:704)
        
org.apache.felix.framework.util.EventDispatcher.fireServiceEvent(EventDi
spatcher.java:635)
        
org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:3443)
        
org.apache.felix.framework.Felix.access$000(Felix.java:39)
        
org.apache.felix.framework.Felix$1.serviceChanged(Felix.java:622)
        
org.apache.felix.framework.ServiceRegistry.fireServiceChanged(ServiceReg
istry.java:576)
        
org.apache.felix.framework.ServiceRegistry.servicePropertiesModified(Ser
viceRegistry.java:501)
        
org.apache.felix.framework.ServiceRegistrationImpl.setProperties(Service
RegistrationImpl.java:107)
        
org.apache.cxf.dosgi.dsw.hooks.AbstractClientHook.lookupDiscoveryService
(AbstractClientHook.java:218)
                   - locked
org.apache.cxf.dosgi.dsw.hooks.cxffindlistenerh...@1a0283e
        
org.apache.cxf.dosgi.dsw.hooks.CxfFindListenerHook.find(CxfFindListenerH
ook.java:95)
        
org.apache.felix.framework.Felix.getServiceReferences(Felix.java:2642)
        
org.apache.felix.framework.Felix.getAllowedServiceReferences(Felix.java:
2672)
        
org.apache.felix.framework.BundleContextImpl.getServiceReferences(Bundle
ContextImpl.java:310)
        
org.apache.felix.eventadmin.impl.handler.BlacklistingHandlerTasks.create
HandlerTasks(BlacklistingHandlerTasks.java:114)
        
org.apache.felix.eventadmin.impl.EventAdminImpl.postEvent(EventAdminImpl
.java:87)
        
org.apache.felix.eventadmin.impl.adapter.ServiceEventAdapter.serviceChan
ged(ServiceEventAdapter.java:135)
        
org.apache.felix.framework.util.EventDispatcher.invokeServiceListenerCal
lback(EventDispatcher.java:846)
        
org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(Eve
ntDispatcher.java:704)
        
org.apache.felix.framework.util.EventDispatcher.fireServiceEvent(EventDi
spatcher.java:635)
        
org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:3443)
        
org.apache.felix.framework.Felix.access$000(Felix.java:39)
        
org.apache.felix.framework.Felix$1.serviceChanged(Felix.java:622)
        
org.apache.felix.framework.ServiceRegistry.fireServiceChanged(ServiceReg
istry.java:576)
        
org.apache.felix.framework.ServiceRegistry.servicePropertiesModified(Ser
viceRegistry.java:501)
        
org.apache.felix.framework.ServiceRegistrationImpl.setProperties(Service
RegistrationImpl.java:107)
        
org.apache.cxf.dosgi.dsw.hooks.AbstractClientHook.lookupDiscoveryService
(AbstractClientHook.java:218)
                   - locked
org.apache.cxf.dosgi.dsw.hooks.cxffindlistenerh...@1a0283e
        
org.apache.cxf.dosgi.dsw.hooks.CxfFindListenerHook.find(CxfFindListenerH
ook.java:95)
        
org.apache.felix.framework.Felix.getServiceReferences(Felix.java:2642)
        
org.apache.felix.framework.Felix.getAllowedServiceReferences(Felix.java:
2672)
        
org.apache.felix.framework.BundleContextImpl.getServiceReferences(Bundle
ContextImpl.java:310)
        
org.apache.felix.eventadmin.impl.handler.BlacklistingHandlerTasks.create
HandlerTasks(BlacklistingHandlerTasks.java:114)
        
org.apache.felix.eventadmin.impl.EventAdminImpl.postEvent(EventAdminImpl
.java:87)
        
org.apache.felix.eventadmin.impl.adapter.LogEventAdapter$1.logged(LogEve
ntAdapter.java:285)
        
org.ops4j.pax.logging.internal.LogReaderServiceImpl.fire(LogReaderServic
eImpl.java:129)
        
org.ops4j.pax.logging.internal.LogReaderServiceImpl.fireEvent(LogReaderS
erviceImpl.java:121)
        
org.ops4j.pax.logging.internal.PaxLoggingServiceImpl.handleEvents(PaxLog
gingServiceImpl.java:151)
        
org.ops4j.pax.logging.internal.PaxLoggerImpl.debug(PaxLoggerImpl.java:11
6)
        
org.ops4j.pax.logging.internal.PaxLoggingServiceImpl.log(PaxLoggingServi
ceImpl.java:140)
        
org.ops4j.pax.logging.internal.PaxLoggingServiceImpl.log(PaxLoggingServi
ceImpl.java:93)
        
org.ops4j.pax.logging.internal.PaxLoggingServiceImpl.log(PaxLoggingServi
ceImpl.java:88)
        
org.ops4j.pax.logging.internal.FrameworkHandler.serviceChanged(Framework
Handler.java:147)
        
org.apache.felix.framework.util.EventDispatcher.invokeServiceListenerCal
lback(EventDispatcher.java:846)
        
org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(Eve
ntDispatcher.java:704)
        
org.apache.felix.framework.util.EventDispatcher.fireServiceEvent(EventDi
spatcher.java:635)
        
org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:3443)
        
org.apache.felix.framework.Felix.access$000(Felix.java:39)
        
org.apache.felix.framework.Felix$1.serviceChanged(Felix.java:622)
        
org.apache.felix.framework.ServiceRegistry.fireServiceChanged(ServiceReg
istry.java:576)
        
org.apache.felix.framework.ServiceRegistry.registerService(ServiceRegist
ry.java:86)
        
org.apache.felix.framework.Felix.registerService(Felix.java:2569)
        
org.apache.felix.framework.BundleContextImpl.registerService(BundleConte
xtImpl.java:252)
        
org.apache.cxf.dosgi.dsw.Activator.start(Activator.java:78)
        
org.apache.felix.framework.util.SecureAction.startActivator(SecureAction
.java:589)
        
org.apache.felix.framework.Felix.startBundle(Felix.java:1461)
        
org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:984)
        
org.apache.felix.framework.StartLevelImpl.run(StartLevelImpl.java:263)
                java.lang.Thread.run(Unknown Source)

                [2]
                
                Name: Thread-4
                State: BLOCKED on
org.apache.cxf.dosgi.dsw.hooks.cxffindlistenerh...@1a0283e owned by:
FelixStartLevel
                Total blocked: 122  Total waited: 114

                Stack trace: 
        
org.apache.cxf.dosgi.dsw.hooks.AbstractClientHook.lookupDiscoveryService
(AbstractClientHook.java:201)
        
org.apache.cxf.dosgi.dsw.hooks.CxfFindListenerHook.find(CxfFindListenerH
ook.java:95)
        
org.apache.felix.framework.Felix.getServiceReferences(Felix.java:2642)
        
org.apache.felix.framework.Felix.getAllowedServiceReferences(Felix.java:
2672)
        
org.apache.felix.framework.BundleContextImpl.getServiceReferences(Bundle
ContextImpl.java:310)
        
org.apache.felix.eventadmin.impl.handler.BlacklistingHandlerTasks.create
HandlerTasks(BlacklistingHandlerTasks.java:114)
        
org.apache.felix.eventadmin.impl.EventAdminImpl.postEvent(EventAdminImpl
.java:87)
        
org.apache.felix.eventadmin.impl.adapter.LogEventAdapter$1.logged(LogEve
ntAdapter.java:285)
        
org.apache.felix.log.LogListenerThread.run(LogListenerThread.java:113)
                   - locked java.util.vec...@4478fe
                   - locked java.util.st...@39f16f
                

                Now, after logging in using a remote shell (I use the
remote shell service), and requesting the runtime state using the
                'ps' command, I get an extra deadlock:

                [3]
                
                Name: telnetconsole.shell remote=/127.0.0.1:1898
                State: BLOCKED on
org.apache.cxf.dosgi.dsw.hooks.cxffindlistenerh...@1a0283e owned by:
FelixStartLevel
                Total blocked: 1  Total waited: 0

                Stack trace: 
        
org.apache.cxf.dosgi.dsw.hooks.AbstractClientHook.lookupDiscoveryService
(AbstractClientHook.java:201)
        
org.apache.cxf.dosgi.dsw.hooks.CxfFindListenerHook.find(CxfFindListenerH
ook.java:95)
        
org.apache.felix.framework.Felix.getServiceReferences(Felix.java:2642)
        
org.apache.felix.framework.Felix.getAllowedServiceReferences(Felix.java:
2672)
        
org.apache.felix.framework.BundleContextImpl.getServiceReferences(Bundle
ContextImpl.java:310)
        
org.apache.felix.framework.BundleContextImpl.getServiceReference(BundleC
ontextImpl.java:261)
        
org.apache.felix.shell.impl.PsCommandImpl.execute(PsCommandImpl.java:58)
        
org.apache.felix.shell.impl.Activator$ShellServiceImpl.executeCommand(Ac
tivator.java:291)
                   - locked
org.apache.felix.shell.impl.activator$shellservicei...@438e1e
                org.apache.felix.shell.remote.Shell.run(Shell.java:109)
                java.lang.Thread.run(Unknown Source)

                So I had a look at the code for the AbstractClientHook,
and pinned down where the deadlock is...
                (red area is where the deadlock occurs).

                    protected synchronized void
lookupDiscoveryService(String interfaceName, String filterValue) {
                        LOG.info("lookup discovery service: interface: "
+ interfaceName
                                 + " filter: " + filterValue);
                
                        boolean change = false;
                        if (interfaceName != null) {
                            change |= append(trackerProperties,
                                   INTERFACE_MATCH_CRITERIA,
                                   interfaceName); 
                        }

                        if (filterValue != null) {
                            change |= append(trackerProperties,
                                   FILTER_MATCH_CRITERIA,
                                   filterValue); 
                        }

                        if (change) {
        
trackerRegistration.setProperties(trackerProperties);
                        }
                    }

                    @SuppressWarnings("unchecked")
                    private boolean append(Dictionary properties, String
key, String additional) {
                        Collection existing =
(Collection)properties.get(key);
                        if (existing == null) {
                            existing = new ArrayList<String>();
                            properties.put(key, existing);
                        }
                        
                        if (!existing.contains(additional)) {
                            existing.add(additional);
                            return true;
                        } else {
                            return false;
                        }
                    }
                
                Now the issue is - how is this deadlock occurring, and
how can it be avoided - is this an issue to do with
                synchronized on the method? Is the LOG object not
threadsafe?

                The LOG object is defined at the start of the
AbstractClientHook class,

                                public class AbstractClientHook extends
AbstractHook {
                                    
                                    private static final Logger LOG =
Logger.getLogger(AbstractClientHook.class.getName());
                

                Anyone have any ideas on this?

                TIA, Chris
                

Reply via email to