Wildfly-Swarm и подключение к внешнему ActiveMQ через адаптер ресурсов: WFLYCTL0412

Итак, я уже потратил на это значительное время, но теперь пришел к тому, что я полностью потерял рассудок...

Требование: я пытаюсь подключить bean-компонент на основе сообщений wildfly 10.1.0 к внешнему серверу activemq 5.15.0 («старый» activemq, а не artemis mq!). Для этого я развертываю адаптер ресурсов и настраиваю конфигурацию. В стандартном развертывании wildfly это работает нормально. Я использую следующий скрипт для настройки контейнера:

# Disable the artemis messaging completely
/subsystem=messaging-activemq/server=default:remove

# Deploy the resource adapter
deploy ${project.build.directory}/activemq-rar-5.15.0.rar

/subsystem=resource-adapters/resource-adapter=activemq-rar.rar:add(archive=activemq-rar-5.15.0.rar,transaction-support=LocalTransaction)
/subsystem=resource-adapters/resource-adapter=activemq-rar.rar/config-properties=ServerUrl:add(value="${activemq.broker}")
/subsystem=resource-adapters/resource-adapter=activemq-rar.rar/config-properties=UserName:add(value="${jboss.user}")
/subsystem=resource-adapters/resource-adapter=activemq-rar.rar/config-properties=Password:add(value="${jboss.password}")
/subsystem=resource-adapters/resource-adapter=activemq-rar.rar/config-properties=UseInboundSession:add(value="false")
/subsystem=resource-adapters/resource-adapter=activemq-rar.rar/connection-definitions=AMQConnectionFactory:add(jndi-name=ConnectionFactory,class-name=org.apache.activemq.ra.ActiveMQManagedConnectionFactory,enabled=true,min-pool-size=1,max-pool-size=20,pool-prefill=false,same-rm-override=false,use-java-context=true)
/subsystem=resource-adapters/resource-adapter=activemq-rar.rar/admin-objects=REQUESTQUEUE:add(class-name=org.apache.activemq.command.ActiveMQQueue,jndi-name=queues/request,use-java-context=true)
/subsystem=resource-adapters/resource-adapter=activemq-rar.rar/admin-objects=REPLYQUEUE:add(class-name=org.apache.activemq.command.ActiveMQQueue,jndi-name=queues/reply,use-java-context=true)
/subsystem=ejb3:write-attribute(name=default-resource-adapter-name,value=activemq-rar.rar)
/subsystem=ejb3:write-attribute(name=default-mdb-instance-pool,value=mdb-strict-max-pool)
/subsystem=ee/service=default-bindings:write-attribute(name=jms-connection-factory,value=java:/ConnectionFactory)

reload

С этой конфигурацией я могу запустить контейнер с автономной полной конфигурацией (чтобы также получить классы, связанные с JMS), и он работает по назначению.

Но если я попытаюсь добиться того же с помощью wildfly swarm, тот же тест mdb.jar не может быть развернут, во время запуска контейнера я получаю следующее исключение:

"WFLYCTL0412: Required services that are not installed:" => ["jboss.ra.activemq-rar"],
"WFLYCTL0180: Services with missing/unavailable dependencies" => ["jboss.deployment.unit.\"mdbtest.jar\".component.TestMDB.CREATE is missing [jboss.ra.activemq-rar]"]

Таким образом, похоже, что адаптер ресурсов недоступен, однако он также виден в развернутой мной консоли администрирования.

Для настройки контейнера роя я использую следующий файл project-defaults.xml:

swarm:

  resource-adapters:
    resource-adapters:
      activemq-rar:
        archive: activemq-rar-15.5.0.rar
        transaction-support: LocalTransaction
        config-properties:
          ServerUrl:
            value: failover:tcp://localhost:61616
          UserName:
            value: admin
          Password:
            value: admin
          UseInboundSession:
            value: false

        connection-definitions:
            AMQConnectionFactory:
                jndi-name: ConnectionFactory
                class-name: org.apache.activemq.ra.ActiveMQManagedConnectionFactory
                enabled: true
                min-pool-size: 1
                max-pool-size: 20
                pool-prefill: false
                same-rm-override: false
                use-java-context: true
                same-rm-override: false

        admin-objects:
            REQUESTQUEUE:
                class-name: org.apache.activemq.command.ActiveMQQueue
                jndi-name: queues/request
                use-java-context: true
            REPLEYQUEUE:
                class-name: org.apache.activemq.command.ActiveMQQueue
                jndi-name: queues/reply
                use-java-context: true

  ejb3:
    # Switch the MDB default to the resource adapter defined above
    default-resource-adapter-name: activemq-rar
    default-mdb-instance-pool: mdb-strict-max-pool

  ee:
      default-bindings:
          jms-connection-factory: java:/ConnectionFactory


  management:
    security-realms:
      ManagementRealm:
        in-memory-authentication:
          users:
            admin:    
              password: admin                            
    http-interface-management-interface:
      allowed-origins:
      - http://localhost:8080
      security-realm: ManagementRealm

  messaging-activemq:
    servers:
      default:
#        active: false
#        connection-factories:
#          InVmConnectionFactory:
#            client-id: blahblabla
#            block-on-acknowledge: true
#            entries:
#            - "java:/ArtemisConnectionFactory"
#        pooled-connection-factories:
#          activemq-ra:
#            entries:
#            connectors: in-vm
#            transaction: xa

  jca:
    archive-validation:
      enabled: false


  datasources:
    jdbc-drivers:
      org.postgresql:
        driver-class-name: org.postgresql.Driver
        xa-datasource-class-name: org.postgresql.xa.PGXADataSource
        driver-module-name: org.postgresql

    data-sources:
      myDS:
        connection-url: jdbc:postgresql://localhost:5432/mydb
        user-name: dbuser
        password: dbpassword
        driver-name: postgresql
        jndi-name: java:jboss/datasources/myDS
        min-pool-size: 4
        max-pool-size: 64
        use-ccm: false


  deployment:
    org.apache.activemq:activemq-rar.rar:
    com.oneworldsync.mdb:mdbtest.jar:
    org.postgresql:postgresql.jar:

  logging:
    loggers:
      org.jboss:
        level: warn
      org.wildfly:
        level: warn

Соответствующая часть помпы выглядит так:

<build>
  <plugins>
    <plugin>
      <groupId>org.wildfly.swarm</groupId>
      <artifactId>wildfly-swarm-plugin</artifactId> 
      <version>2017.4.0</version>
      <executions>
        <execution>
          <id>package</id>
          <goals>
            <goal>package</goal>
          </goals>
          <phase>package</phase>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>


<dependencies>
  <dependency>
    <groupId>com.oneworldsync.mdb</groupId>
    <artifactId>mdbtest</artifactId>
    <version>1.0.0-SNAPSHOT</version>
  </dependency>
  <dependency>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>logging</artifactId>
  </dependency>
  <dependency>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>datasources</artifactId>
  </dependency>
  <dependency>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>undertow</artifactId>
  </dependency>
  <dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.1.4</version>
  </dependency>
  <dependency>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>cdi</artifactId>
  </dependency>
  <dependency>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>jpa</artifactId>
  </dependency>
  <dependency>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>msc</artifactId>
  </dependency>
  <dependency>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>infinispan</artifactId>
  </dependency>
  <dependency>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>messaging</artifactId>
  </dependency>
  <dependency>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>jca</artifactId>
  </dependency>
  <dependency>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>resource-adapters</artifactId>
  </dependency>
  <dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-rar</artifactId>
    <version>${activemq.version}</version>
    <type>rar</type>
  </dependency>
  <dependency>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>management</artifactId>
  </dependency>
  <dependency>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>management-console</artifactId>
  </dependency>
  <dependency>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>cli</artifactId>
    <version>${jboss.version}</version>
  </dependency>
  <dependency>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>ejb</artifactId>
  </dependency>
  <dependency>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>connector</artifactId>
  </dependency>
  <dependency>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>jaxrs</artifactId>
  </dependency>
  <dependency>
    <groupId>org.wildfly.swarm</groupId>
    <artifactId>remoting</artifactId>
  </dependency>
</dependencies>

MDB для тестирования прост:

@MessageDriven(activationConfig = {
    @ActivationConfigProperty(propertyName = "acknowledgeMode",
            propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "destination",
            propertyValue = "request"),
    @ActivationConfigProperty(propertyName = "destinationType",
            propertyValue = "javax.jms.Queue")
})
public class TestMDB implements MessageListener {

    @Resource(name = "java:/ConnectionFactory")
    private QueueConnectionFactory queueConnectionFactory;


    @Override
    public void onMessage(Message message) {
        System.out.println(message);
    }
}

Итак, я ищу подсказку, почему MDB не может получить доступ к адаптеру ресурсов, даже если он был развернут, виден и использует соответствующее имя. Я ожидал, что это что-то простое на данный момент, но я не могу его найти.

Большое спасибо!

PS: внешний сервер activemq является обязательным требованием. Использование моста JMS, вероятно, сработает, но имеет некоторые недостатки, которые неприемлемы (влияние на производительность из-за дополнительного «прыжка», jms-reply-to target не работает через мост jms).

Изменить 1

Arg, после публикации я обнаружил как минимум одну проблему в своем pom: я использовал несоответствующую версию плагина swarm: фракции swarm 2017.10.0, но плагин 2017.4.0. Исправление этого немного меняет симптомы ошибки:

2017-10-26 09:21:07,731 ERROR [stderr] (main) Caused by: java.lang.RuntimeException: org.wildfly.swarm.container.DeploymentException: org.wildfly.swarm.container.DeploymentException: WFSWARM0004: Deployment failed: {"WFLYCTL0412: Required services that are not installed:" => ["jboss.ra.activemq-rar"],"WFLYCTL0180: Services with missing/unavailable dependencies" => ["jboss.deployment.unit.\"mdbtest.jar\".component.TestMDB.CREATE is missing [jboss.ra.activemq-rar]"]}
2017-10-26 09:21:07,732 ERROR [stderr] (main)   at org.wildfly.swarm.spi.api.ClassLoading.withTCCL(ClassLoading.java:45)
2017-10-26 09:21:07,732 ERROR [stderr] (main)   at org.wildfly.swarm.container.runtime.ServerBootstrapImpl.bootstrap(ServerBootstrapImpl.java:114)
2017-10-26 09:21:07,732 ERROR [stderr] (main)   at org.wildfly.swarm.Swarm.start(Swarm.java:386)
2017-10-26 09:21:07,732 ERROR [stderr] (main)   at org.wildfly.swarm.Swarm.main(Swarm.java:720)
2017-10-26 09:21:07,732 ERROR [stderr] (main)   ... 6 more

Таким образом, кажется, что внизу есть проблема с загрузкой классов. Изучу это, но все равно буду рад дальнейшему вкладу

Редактировать 2

Приведенная выше трассировка стека кажется неактуальной: на самом деле существует разница в том, как запускается роевое приложение:

  • Начните с java -jar something.app: без трассировки стека
  • Начните с mv nwildfly-swarm:run: приведенной выше трассировки стека.

Однако основная причина та же (зависимости не найдены). Я интерпретирую это так, что плагин maven добавляет к вызову дополнительный уровень, который регистрирует дополнительную трассировку стека, но проблема остается той же.


person bahkauv    schedule 26.10.2017    source источник


Ответы (1)


Наконец, после многих часов я сам решил проблему. Как и ожидалось, решение было простым, но не очевидным...

Один важный совет я взял из здесь. После серьезного анализа и сеансов отладки я обнаружил, что ресурс-адаптер был неправильно развернут: в то время как подходящая единица развертывания была упомянута в установленных службах (консоль JMX очень помогает найти их), сам ресурс-адаптер был все еще недоступен. Решением всего этого было название развертывания: для правильного развертывания адаптера необходимо использовать следующий фрагмент:

swarm:
  deployment:
    org.apache.activemq:activemq-rar.rar:

Обратите внимание, что номер версии maven должен быть опущен и должен использоваться только идентификатор maven ArtifexId (сравните с моим исходным фрагментом выше). Поскольку плагин swarm тесно связан с управлением зависимостями maven, он сам определяет физическое имя. В автономном wildfly все по-другому: он ничего не знает об артефактах maven, поэтому необходимо использовать имя физического архива. В standalone-full.xml это будет выглядеть так:

<deployments>
   <deployment name="activemq-rar-5.15.0.rar" runtime-name="activemq-rar-5.15.0.rar">
       ...

Когда имя архива исправлено, развертывание работает. Единственное, что осталось, это конфликт в JNDI из-за существования адаптера ArtemisMQ (используя YAML-подход swarm, его нельзя удалить). Так что это тоже надо адаптировать.

Итак, для полноты: вот мой наконец рабочий проект-defaults.yaml:

swarm:
  deployment:
    org.apache.activemq:activemq-rar.rar:

  resource-adapters:
    resource-adapters:
      activemq-rar:
        # This is not the physical jar name, but the maven coordinates (without version!)
        archive: activemq-rar.rar
        transaction-support: LocalTransaction
        config-properties:
          ServerUrl:
            value: failover:tcp://localhost:61616
          UserName:
            value: admin
          Password:
            value: admin
          UseInboundSession:
            value: false

        connection-definitions:
            AMQConnectionFactory:
                jndi-name: ConnectionFactory
                class-name: org.apache.activemq.ra.ActiveMQManagedConnectionFactory
                enabled: true
                min-pool-size: 1
                max-pool-size: 20
                pool-prefill: false
                same-rm-override: false
                use-java-context: true

        admin-objects:
            REQUESTQUEUE:
                class-name: org.apache.activemq.command.ActiveMQQueue
                jndi-name: queues/request
                use-java-context: true
                config-properties:
                  PhysicalName: demo.request


  ejb3:
    default-resource-adapter-name: activemq-rar.rar
    default-mdb-instance-pool: mdb-strict-max-pool

  ee:
      default-bindings:
          jms-connection-factory: java:/ConnectionFactory


  management:
    security-realms:
      ManagementRealm:
        in-memory-authentication:
          users:
            admin:    
              password: admin                            
    http-interface-management-interface:
      allowed-origins: http://localhost:8080
      security-realm: ManagementRealm
      console-enabled: true

  messaging-activemq:
    servers:
      default:
        active: false
        connection-factories:
          InVmConnectionFactory:
            block-on-acknowledge: true
            entries:
            - "java:/ArtemisConnectionFactory"

  jca:
    archive-validation:
      enabled: false

  logging:
    loggers:
      org.jboss:
        level: INFO
      org.wildfly:
        level: INFO
person bahkauv    schedule 08.11.2017
comment
Большое спасибо! После долгой борьбы это решило это для меня. - person Panu Haaramo; 30.04.2019