TL; DR
Существует три варианта решения.
- Обновление JGroups до версии 4.0.16, в настоящее время SNAPSHOT . Редактировать: Теперь выпущен здесь .
- Убедитесь, что свойства java для "user.language" и "user.country" установлены.
- Принудительно JDKLogImpl с
-Djgroups.use.jdk_logger=true
. (упоминается Перимош )
Объяснение
Эта проблема возникла в следующем сценарии.
Apache Camel + JGroups отлично работал в локальной среде. Развернул его в другом месте в экземпляре Docker, где мы получили следующую трассировку стека:
2018-11-19 13:38:03.063 INFO 582 --- [ main] o.a.camel.spring.boot.RoutesCollector : Loading additional Camel XML routes from: classpath:camel/*.xml
2018-11-19 13:38:03.064 INFO 582 --- [ main] o.a.camel.spring.boot.RoutesCollector : Loading additional Camel XML rests from: classpath:camel-rest/*.xml
2018-11-19 13:38:03.107 INFO 582 --- [ main] o.a.camel.spring.SpringCamelContext : Apache Camel 2.22.2 (CamelContext: camel-1) is starting
2018-11-19 13:38:03.111 INFO 582 --- [ main] o.a.c.m.ManagedManagementStrategy : JMX is enabled
2018-11-19 13:38:03.480 INFO 582 --- [ main] o.a.camel.spring.SpringCamelContext : StreamCaching is not in use. If using streams then its recommended to enable stream caching. See more details at http://camel.apache.org/stream-caching.html
2018-11-19 13:38:03.597 INFO 582 --- [ main] o.a.camel.spring.SpringCamelContext : Apache Camel 2.22.2 (CamelContext: camel-1) is shutting down
2018-11-19 13:38:03.616 WARN 582 --- [ main] o.a.camel.spring.SpringCamelContext : Error occurred while shutting down service: org.apache.camel.component.jgroups.cluster. JGroupsLockClusterService@10fa5af5. This exception will be ignored.
java.lang.NullPointerException: null
at org.apache.camel.component.jgroups.cluster.JGroupsLockClusterView.doStop(JGroupsLockClusterView.java:109)
at org.apache.camel.support.ServiceSupport.stop(ServiceSupport.java:102)
at org.apache.camel.impl.cluster.AbstractCamelClusterService.lambda$doStop$2(AbstractCamelClusterService.java:134)
at org.apache.camel.util.concurrent.LockHelper.doWithReadLockT(LockHelper.java:54)
at org.apache.camel.impl.cluster.AbstractCamelClusterService.doStop(AbstractCamelClusterService.java:130)
at org.apache.camel.support.ServiceSupport.stop(ServiceSupport.java:102)
at org.apache.camel.util.ServiceHelper.stopService(ServiceHelper.java:142)
at org.apache.camel.util.ServiceHelper.stopAndShutdownService(ServiceHelper.java:205)
at org.apache.camel.impl.DefaultCamelContext.shutdownServices(DefaultCamelContext.java:3663)
at org.apache.camel.impl.DefaultCamelContext.shutdownServices(DefaultCamelContext.java:3688)
at org.apache.camel.impl.DefaultCamelContext.shutdownServices(DefaultCamelContext.java:3676)
at org.apache.camel.impl.DefaultCamelContext.doStop(DefaultCamelContext.java:3567)
at org.apache.camel.support.ServiceSupport.stop(ServiceSupport.java:102)
at org.apache.camel.impl.DefaultCamelContext.stop(DefaultCamelContext.java:3220)
at org.apache.camel.spring.SpringCamelContext.stop(SpringCamelContext.java:148)
...
2018-11-19 13:38:03.679 INFO 582 --- [ main] o.a.camel.spring.SpringCamelContext : Apache Camel 2.22.2 (CamelContext: camel-1) uptime 0.570 seconds
2018-11-19 13:38:03.680 INFO 582 --- [ main] o.a.camel.spring.SpringCamelContext : Apache Camel 2.22.2 (CamelContext: camel-1) is shutdown in 0.082 seconds
2018-11-19 13:38:03.716 INFO 582 --- [ main] org.mongodb.driver.connection : Closed connection [connectionId{localValue:2, serverValue:2}] to localhost:43115 because the pool has been closed.
Как вы можете видеть, Apache Camel пытается запустить, но никогда не делает и заканчивает тем, что закрывается. Таким образом, JGroups получает NPE, потому что ожидает, что верблюд встанет.
После отладки кода выяснилось, что в процессе запуска Camel было сгенерировано исключение.
Оттуда обнаружил, что создание экземпляра Slf4jLogImpl в org.jgroups.logging.LogFactory#getLog(java.lang.Class<?>)
(new Slf4jLogImpl(clazz)
) было проблемой Method threw 'java.lang.ExceptionInInitializerError' exception.
:
java.lang.NullPointerException: null
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at org.jgroups.logging.LogFactory.getLog(LogFactory.java:101)
at org.jgroups.conf.XmlConfigurator.<clinit>(XmlConfigurator.java:33)
at org.jgroups.conf.ConfiguratorFactory.getXmlConfigurator(ConfiguratorFactory.java:210)
at org.jgroups.conf.ConfiguratorFactory.getStackConfigurator(ConfiguratorFactory.java:91)
at org.jgroups.JChannel.<init>(JChannel.java:130)
...
Запуск (new Slf4jLogImpl(clazz)
) второй раз в отладчике приводит к следующей трассировке стека, которая отражает исходную опубликованную проблему:
java.lang.NoClassDefFoundError: Could not initialize class org.jgroups.logging.Slf4jLogImpl
at org.jgroups.logging.LogFactory.getLog(LogFactory.java:101)
at org.jgroups.conf.XmlConfigurator.<clinit>(XmlConfigurator.java:33)
at org.jgroups.conf.ConfiguratorFactory.getXmlConfigurator(ConfiguratorFactory.java:210)
at org.jgroups.conf.ConfiguratorFactory.getStackConfigurator(ConfiguratorFactory.java:91)
at org.jgroups.JChannel.<init>(JChannel.java:130)
Эта разница в результатах объясняется тем, что загрузчик классов кэширует результат вызова Class.forName()
, который ранее определял, что определение класса не найдено.
Наконец, мы проследили, чтобы предыдущий NPE был сброшен с java.util.Locale#Locale(java.lang.String, java.lang.String, java.lang.String)
, поскольку страна была null
. Это связано с тем, что org.jgroups.logging.Slf4jLogImpl
в JGroup является полем LOCALE
, использующим свойства java для user.language и user.country. Первый не был установлен в нашем экземпляре докера, поэтому Locale.java
бросил NPE. Добавление обоих этих свойств Java должно решить эту проблему. В качестве альтернативы вы можете принудительно использовать JDKLogImpl
, чтобы никогда не пытались создать экземпляр Slf4jLogImpl
. Это было упомянуто в предыдущем ответе, передавая -Djgroups.use.jdk_logger=true
.
Редактировать: Исправлено в последней версии , выпущенной здесь .
Теперь, похоже, это будет исправлено в следующем выпуске JGroup 4.0.16.Final (https://github.com/belaban/JGroups/commit/61578c657138f02178c32a564ac9eae7c3976093#diff-93eb0f6a8a4953312098be459bd7ce76). До этого вы можете получить версию моментального снимка с исправлением в https://repository.jboss.org/nexus/content/repositories/snapshots/org/jgroups/jgroups/4.0.16-SNAPSHOT/.