Java 10 Spring Boot Infinispan org.jgroups.logging.Slf4jLogImpl не найден - PullRequest
0 голосов
/ 17 сентября 2018

У меня есть приложение Spring Boot, которое я создаю и работаю с Java 10. Если я запускаю приложение, используя

java -jar

Все работает нормально.Приложение запускается просто ОК.

Но если я помещаю свое приложение в контейнер Docker с точно такой же версией Java, мое приложение выдает это исключение:

Caused by: 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.getStackConfigurator(ConfiguratorFactory.java:62)
    at org.jgroups.JChannel.<init>(JChannel.java:122)
    at org.infinispan.remoting.transport.jgroups.JGroupsTransport.buildChannel(JGroupsTransport.java:591)
    at org.infinispan.remoting.transport.jgroups.JGroupsTransport.initChannel(JGroupsTransport.java:405)
    at org.infinispan.remoting.transport.jgroups.JGroupsTransport.start(JGroupsTransport.java:389)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.infinispan.commons.util.SecurityActions.lambda$invokeAccessibly$0(SecurityActions.java:79)
    ... 104 common frames omitted

Я использую эту версиюJava:

java version "10.0.2" 2018-07-17
Java(TM) SE Runtime Environment 18.3 (build 10.0.2+13)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.2+13, mixed mode)

Версия Docker:

Client:
 Version:           18.06.1-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        e68fc7a
 Built:             Tue Aug 21 17:21:31 2018
 OS/Arch:           darwin/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.06.1-ce
  API version:      1.38 (minimum version 1.12)
  Go version:       go1.10.3
  Git commit:       e68fc7a
  Built:            Tue Aug 21 17:29:02 2018
  OS/Arch:          linux/amd64
  Experimental:     true

Мой Docker использует базовое изображение Alpine alpine:latest.Я устанавливаю java в своем контейнере по этой ссылке:

curl -jksSLH "Cookie: oraclelicense=accept-securebackup-cookie" -o /tmp/java.tar.gz \
      http://download.oracle.com/otn-pub/java/jdk/10.0.2+13/19aef61b38124481863b1413dce1855f/jdk-10.0.2_linux-x64_bin.tar.gz

Я действительно сбит с толку, потому что снаружи docker-контейнера мое приложение работает нормально, но внутри docker-контейнера это не так.В любом случае я использую одну и ту же версию Java.

ОБНОВЛЕНИЕ

Мы пробовали Oracle JDK и OpenJDK, такое же поведение

ОБНОВЛЕНИЕ 2

Мы даже попробовали java -jar изнутри контейнера, не повезло

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

TL; DR

Существует три варианта решения.

  1. Обновление JGroups до версии 4.0.16, в настоящее время SNAPSHOT . Редактировать: Теперь выпущен здесь .
  2. Убедитесь, что свойства java для "user.language" и "user.country" установлены.
  3. Принудительно 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/.

0 голосов
/ 25 сентября 2018

Это не настоящее решение, но, поскольку оно разблокировало нас, я поделюсь им. Также, возможно, кто-то может подумать о настоящей проблеме, взглянув на этот обходной путь. Мы добавили этот аргумент JVM для обхода SLF4J для jgroups и используем JDKLogImpl

-Djgroups.use.jdk_logger=true
...