2015-07-05 2 views
1

Этот вопрос связан с тупиком, который случается (иногда, как описано ниже) при импорте службы osgi с использованием функции spring-dm.Заключительный случай возникает при импорте службы osgi с использованием Spring-DM

Я недавно столкнулся с этой проблемой в классе ServiceDynamicInterceptor Spring-DM, что приводит к ситуации с мертвой блокировкой. Это происходит, когда два контекста приложения загружаются из двух пакетов. Предположим, что приложение ctx A экспортирует службу osgi, а приложение ctx B импортирует службу osgi, экспортированную из A. Проблема возникает, когда оба пакета запускаются вместе. Когда приложение ctx A инициализируется, пружина вызывает прослушивателей, зарегистрированных для службы синхронно во время публикации службы osgi. Предположим, что приложение ctx B инициализируется одновременно, и импорт osgi выполняется. Сначала он добавляет слушателя для службы osgi к контексту связки, а затем переходит к поиску службы osgi. Подобно тому, как слушатель добавляется в контекст связки, приложение ctx A подбирает его и выполняет прослушиватель. На этом этапе приложение ctx B, которое получает блокировку, пытается найти службу osgi, которая еще не опубликована, поскольку слушатель вызывается, который ожидает, что тот же самый замок будет выпущен, вызывая тупик. После того, как тайм-аут создания весеннего боба достигнут через 5 минут (по умолчанию), приложение ctx B не работает с BeanInitializationException, вызванное ServiceUnavailableException.

Я перечислил код, выполняемый в двух потоках. Обратите внимание, что и поиск, и слушатель определены в одном файле - ServiceDynamicInterceptor.

App Ctx А ждет замок на

145: synchronized (lock) { 
146:  servicePresent = (wrapper != null && wrapper.isServiceAlive()); 
147: } 

App Ctx B ждет службы OSGi будут опубликованы на

428: private Object lookupService() { 
429:  synchronized (lock) { 
430:    return (Object) retryTemplate.execute(retryCallback); 
431:  } 
432: } 

Это происходит иногда, как я уже говорил раньше, когда оба пучка перезапускаются вместе. Однако это происходит не каждый раз по понятным причинам. Вопрос в том, можно ли избежать этой мертвой блокировки?

Выдержки из потока отвала

App Ctx

"SpringOsgiExtenderThread-90" Id=908 in BLOCKED on [email protected] 
    owned by pool-45-thread-1 Id=798 
    at org.springframework.osgi.service.importer.support.internal.aop.ServiceDynamicInterceptor$Listener.serviceChanged(ServiceDynamicInterceptor.java:146) 
    at org.apache.felix.framework.util.EventDispatcher.invokeServiceListenerCallback(EventDispatcher.java:934) 
    at org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:795) 
    at org.apache.felix.framework.util.EventDispatcher.fireServiceEvent(EventDispatcher.java:544) 
    at org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:4596) 
    at org.apache.felix.framework.Felix.registerService(Felix.java:3604) 
    at org.apache.felix.framework.BundleContextImpl.registerService(BundleContextImpl.java:346) 
    at org.springframework.osgi.service.exporter.support.OsgiServiceFactoryBean.registerService(OsgiServiceFactoryBean.java:310) 
    at org.springframework.osgi.service.exporter.support.OsgiServiceFactoryBean.registerService(OsgiServiceFactoryBean.java:279) 
    at org.springframework.osgi.service.exporter.support.OsgiServiceFactoryBean$Executor.registerService(OsgiServiceFactoryBean.java:95) 
    at org.springframework.osgi.service.exporter.support.internal.controller.ExporterController.registerService(ExporterController.java:40) 
    at org.springframework.osgi.service.dependency.internal.DefaultMandatoryDependencyManager.startExporter(DefaultMandatoryDependencyManager.java:320) 
    at org.springframework.osgi.service.dependency.internal.DefaultMandatoryDependencyManager.checkIfExporterShouldStart(DefaultMandatoryDependencyManager.java:261) 
    at org.springframework.osgi.service.dependency.internal.DefaultMandatoryDependencyManager.discoverDependentImporterFor(DefaultMandatoryDependencyManager.java:254) 
     - locked org.sprin[email protected]2ae6baf0 
    at org.springframework.osgi.service.dependency.internal.DefaultMandatoryDependencyManager.addServiceExporter(DefaultMandatoryDependencyManager.java:187) 
    at org.springframework.osgi.service.dependency.internal.MandatoryDependencyBeanPostProcessor.postProcessAfterInitialization(MandatoryDependencyBeanPostProcessor.java:46) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:407) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1461) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) 
     - locked [email protected] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:589) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:925) 
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.access$1600(AbstractDelegatedExecutionApplicationContext.java:69) 
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:355) 
     - locked [email protected] 
    at org.springframework.osgi.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85) 
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:320) 
    at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:132) 
    at java.lang.Thread.run(Thread.java:745) 

App Ctx B

"pool-45-thread-1" Id=798 in TIMED_WAITING on [email protected] 
    at java.lang.Object.wait(Native Method) 
    at org.springframework.osgi.service.importer.support.internal.support.RetryTemplate.execute(RetryTemplate.java:106) 
    at org.springframework.osgi.service.importer.support.internal.aop.ServiceDynamicInterceptor.lookupService(ServiceDynamicInterceptor.java:430) 
    at org.springframework.osgi.service.importer.support.internal.aop.ServiceDynamicInterceptor.getTarget(ServiceDynamicInterceptor.java:415) 
    at org.springframework.osgi.service.importer.support.internal.aop.ServiceDynamicInterceptor.afterPropertiesSet(ServiceDynamicInterceptor.java:472) 
    at org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean.createProxy(OsgiServiceProxyFactoryBean.java:215) 
    at org.springframework.osgi.service.importer.support.AbstractServiceImporterProxyFactoryBean.getObject(AbstractServiceImporterProxyFactoryBean.java:86) 
    at org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean.getObject(OsgiServiceProxyFactoryBean.java:161) 
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142) 
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:102) 
     - locked [email protected] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1442) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:248) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) 
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1109) 
    at org.apache.camel.spring.spi.ApplicationContextRegistry.lookup(ApplicationContextRegistry.java:43) 
    at org.apache.camel.impl.CompositeRegistry.lookup(CompositeRegistry.java:51) 
    at org.apache.camel.impl.PropertyPlaceholderDelegateRegistry.lookup(PropertyPlaceholderDelegateRegistry.java:62) 
    at org.apache.camel.util.CamelContextHelper.lookup(CamelContextHelper.java:119) 
    at org.apache.camel.model.RouteBuilderDefinition.createRouteBuilder(RouteBuilderDefinition.java:64) 
    at org.apache.camel.core.xml.AbstractCamelContextFactoryBean.installRoutes(AbstractCamelContextFactoryBean.java:624) 
    at org.apache.camel.core.xml.AbstractCamelContextFactoryBean.afterPropertiesSet(AbstractCamelContextFactoryBean.java:276) 
    at org.apache.camel.spring.CamelContextFactoryBean.afterPropertiesSet(CamelContextFactoryBean.java:235) 
    at org.apache.camel.osgi.CamelContextFactoryBean.afterPropertiesSet(CamelContextFactoryBean.java:64) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) 
     - locked [email protected] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) 
    at org.springframework.context.event.AbstractApplicationEventMulticaster.getApplicationListeners(AbstractApplicationEventMulticaster.java:155) 
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:86) 
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:327) 
    at org.springframework.osgi.service.importer.support.internal.aop.ServiceDynamicInterceptor.publishEvent(ServiceDynamicInterceptor.java:439) 
    at org.springframework.osgi.service.importer.support.internal.aop.ServiceDynamicInterceptor.access$300(ServiceDynamicInterceptor.java:67) 
    at org.springframework.osgi.service.importer.support.internal.aop.ServiceDynamicInterceptor$EventSenderRetryTemplate.onMissingTarget(ServiceDynamicInterceptor.java:96) 
    at org.springframework.osgi.service.importer.support.internal.support.RetryTemplate.execute(RetryTemplate.java:95) 
    at org.springframework.osgi.service.importer.support.internal.aop.ServiceDynamicInterceptor.lookupService(ServiceDynamicInterceptor.java:430) 
     - locked [email protected] 
    at org.springframework.osgi.service.importer.support.internal.aop.ServiceDynamicInterceptor.getTarget(ServiceDynamicInterceptor.java:415) 
    at org.springframework.osgi.service.importer.support.internal.aop.ServiceDynamicInterceptor.afterPropertiesSet(ServiceDynamicInterceptor.java:472) 
    at org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean.createProxy(OsgiServiceProxyFactoryBean.java:215) 
    at org.springframework.osgi.service.importer.support.AbstractServiceImporterProxyFactoryBean.getObject(AbstractServiceImporterProxyFactoryBean.java:86) 
    at org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean.getObject(OsgiServiceProxyFactoryBean.java:161) 
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142) 
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:102) 
     - locked java.util.concurrent.ConcurrentHash[email protected] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1442) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:305) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:323) 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:107) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1360) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1118) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) 
     - locked [email protected] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:607) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:925) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:472) 
     - locked [email protected] 
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.access$301(AbstractDelegatedExecutionApplicationContext.java:69) 
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext$1.run(AbstractDelegatedExecutionApplicationContext.java:186) 
    at org.springframework.osgi.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85) 
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.normalRefresh(AbstractDelegatedExecutionApplicationContext.java:182) 
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext$NoDependenciesWaitRefreshExecutor.refresh(AbstractDelegatedExecutionApplicationContext.java:89) 
    at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.refresh(AbstractDelegatedExecutionApplicationContext.java:175) 
    at com.xxx.bbb.core.extender.service.bbbManagedServiceFactory$1.run(BbbManagedServiceFactory.java:178) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:745) 
+0

Что вы ожидаете от ответа здесь? Spring DM больше не поддерживается в течение многих лет. Таким образом, максимум, который вы можете достичь, - обходное решение, которое я думаю. –

+0

@ChristianSchneider Обходной путь был бы замечательным. Единственный способ избежать этого - добавить компонент с задержкой (скажем 1s) и вызвать его из зависимого элемента в osgi: ссылочном элементе в app ctx B. Но это не сработает, если приложение ctx A займет больше времени инициализируется, когда к нему добавляются больше бобов. –

+0

Аналогичная проблема была поднята 5 лет назад. Поэтому он никогда не был разрешен. http://forum.spring.io/forum/attic/spring-dynamic-modules/82295-spring-dm-trying-to-obtain-a-service-hangs –

ответ

0

В прошлом у меня были подобные проблемы с Спринг-DM, обходной путь, который я сделал, должен был отслеживать услугу с помощью ServiceTracker через BundleActivator. В некоторых случаях мне также пришлось настраивать весь код, который полагался на эту услугу (например: autowiring). Это было уродливо ... но это сработало. После некоторых экспериментов, подобных этому, я помню, что я также использовал с успехом FactoryBean, который имел такой же подход ...

Смежные вопросы