Wildfly-Swarm 并通过资源适配器连接到外部 activemq:WFLYCTL0412
Posted
技术标签:
【中文标题】Wildfly-Swarm 并通过资源适配器连接到外部 activemq:WFLYCTL0412【英文标题】:Wildfly-Swarm and connection to external activemq via resource adapter: WFLYCTL0412 【发布时间】:2018-04-07 11:10:27 【问题描述】:所以我已经在这方面花费了相当多的时间,但现在已经到了我完全无能为力的地步......
要求: 我正在尝试将基于 wildfly 10.1.0 的消息驱动 bean 连接到外部 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]"]
看来,资源适配器不可用,但它在我部署的管理控制台中也是可见的。
要设置 swarm 容器,我使用以下 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
pom 的相关部分如下所示:
<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 目的地对性能的影响不适用于 jms 网桥)。
编辑 1
Arg,发布后我在我的 pom 中发现了至少一个问题:我使用了不匹配的 swarm 插件版本:swarm fractions 是 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 插件在调用中添加了一个额外的层,它记录了额外的堆栈跟踪,但问题仍然是一样的。
【问题讨论】:
【参考方案1】:最后,经过几个小时,我自己解决了这个问题。正如预期的那样,解决方案很简单但并不明显......
我从here 得到的一个重要提示。 经过一些认真的分析和调试会话后,我发现资源适配器未正确部署:虽然在已安装的服务中提到了合适的部署单元(JMX 控制台非常有助于找到这些),但资源适配器本身是仍然不可用。 所有这一切的解决方案是部署的名称: 要正确部署适配器,必须使用以下 sn-p:
swarm:
deployment:
org.apache.activemq:activemq-rar.rar:
请注意,maven version 编号 必须省略,只需要使用 maven artifactId(与我原来的 sn- p 上面)。由于 swarm 插件与 maven 依赖管理紧密耦合,它自己计算物理名称。在独立的 wildfly 中,这是不同的:它对 maven 工件一无所知,因此必须使用物理存档名称。在standalone-full.xml 中它看起来像这样:
<deployments>
<deployment name="activemq-rar-5.15.0.rar" runtime-name="activemq-rar-5.15.0.rar">
...
更正存档名称后,部署工作。由于 ArtemisMQ 适配器的存在,唯一剩下的就是 JNDI 中的冲突(使用 swarm 的 YAML 方法无法将其删除)。所以这也必须适应。
为了完整起见:这是我最终工作的 project-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
【讨论】:
非常感谢!经过长时间的斗争,这为我解决了。以上是关于Wildfly-Swarm 并通过资源适配器连接到外部 activemq:WFLYCTL0412的主要内容,如果未能解决你的问题,请参考以下文章
无法连接到一个 VM 上的网络适配器,相同的代码适用于另一个 VM