在 javax.enterprise.inject.spi.Extension 内确定 JNDI 可移植名称

Determine JNDI portable name within an javax.enterprise.inject.spi.Extension

我正在实施 JCA inbound resource adapter 以允许 EIS 将消息发送到部署在 Java EE 应用程序服务器上的应用程序。

只有用我的注释注释的 EJB 应该是可访问的,所以我使用了 javax.enterprise.inject.spi.Extension in order to observe ProcessAnnotatedType,然后我可以用它来存储有关部署在应用程序服务器上的所有用我的注释注释的 EJB 方法的详细信息。

注释包含一个简短的唯一名称,可以像逻辑服务名称一样使用以允许来自 EIS 的入站调用。然后通过 JNDI 将这些调用分派到相应的端点。

目前一切正常,但 JNDI 名称当前必须作为我的注释中的值提供。我想删除此要求并让我的分机确定 Global Portable JNDI Name.

因为我在 JCA 资源适配器中,所以我必须使用 java:global 形式:

java:global[/application name]/module name/enterprise bean name[/interface name]

我正在测试的示例包括:

java:global/testappwar01/SimpleService!org.example.service.ISimpleService
java:global/testappear01/test-ejb/SimpleService!org.example.service.ISimpleService

我或多或少可以从我收到的 ProcessAnnotatedType 对象中计算出接口名称和企业 bean 名称,但事实证明应用程序名称和模块名称有点难以捉摸。

我试过使用 lookups of java:app/AppName and java:module/Module 名称。当部署是 .war 时,这些值在 wildfly (10.x) 中工作良好,但在 .ear 中由于某种原因这些值不存在。在 weblogic 12.x 中,无论部署存档类型如何,这些值根本不存在。

我正在寻找可以在任何 Java 兼容 EE 的应用程序服务器上运行的东西,因此理想情况下没有特定于应用程序服务器的依赖项。虽然更糟糕的情况是可以接受与 weblogic 和 wildfly 一起工作的东西。

更新 - 野蝇日志:

部署的应用程序与之前描述的不完全一样,我已经对它们进行了清理:

casual-test-app-0.0.1.ear 在 application.xml "casual-test-app-custom-2" 中有一个自定义名称,其中包含 test-ejb.jar 和 test-ejb2.jar

casual-java-testapp.war 是我可以让 appName 和 moduleName 工作的地方。

casual-jca-0.0.1.ear 是我的资源适配器

2018-02-21 10:18:03,226 INFO  [org.jboss.weld.deployer] (MSC service thread 1-7) WFLYWELD0003: Processing weld deployment casual-test-app-0.0.1.ear
2018-02-21 10:18:03,520 INFO  [org.jboss.weld.deployer] (MSC service thread 1-3) WFLYWELD0003: Processing weld deployment casual-jca-0.0.1.ear
2018-02-21 10:18:03,852 INFO  [org.jboss.weld.deployer] (MSC service thread 1-8) WFLYWELD0003: Processing weld deployment test-ejb.jar
2018-02-21 10:18:03,853 INFO  [org.jboss.weld.deployer] (MSC service thread 1-2) WFLYWELD0003: Processing weld deployment test-ejb2.jar
2018-02-21 10:18:03,873 INFO  [org.jboss.weld.deployer] (MSC service thread 1-5) WFLYWELD0003: Processing weld deployment casual-java-testapp.war
2018-02-21 10:18:03,877 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-2) WFLYEJB0473: JNDI bindings for session bean named 'SimpleServiceNoViewEjb' in deployment unit 'subdeployment "test-ejb2.jar" of deployment "casual-test-app-0.0.1.ear"' are as follows:

    java:global/casual-test-app-custom-2/test-ejb2/SimpleServiceNoViewEjb!se.kodarkatten.casual.example.service.SimpleServiceNoViewEjb
    java:app/test-ejb2/SimpleServiceNoViewEjb!se.kodarkatten.casual.example.service.SimpleServiceNoViewEjb
    java:module/SimpleServiceNoViewEjb!se.kodarkatten.casual.example.service.SimpleServiceNoViewEjb
    java:global/casual-test-app-custom-2/test-ejb2/SimpleServiceNoViewEjb
    java:app/test-ejb2/SimpleServiceNoViewEjb
    java:module/SimpleServiceNoViewEjb

2018-02-21 10:18:03,878 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-2) WFLYEJB0473: JNDI bindings for session bean named 'SimpleService2' in deployment unit 'subdeployment "test-ejb2.jar" of deployment "casual-test-app-0.0.1.ear"' are as follows:

    java:global/casual-test-app-custom-2/test-ejb2/SimpleService2!se.kodarkatten.casual.example.service.ISimpleService2
    java:app/test-ejb2/SimpleService2!se.kodarkatten.casual.example.service.ISimpleService2
    java:module/SimpleService2!se.kodarkatten.casual.example.service.ISimpleService2
    java:jboss/exported/casual-test-app-custom-2/test-ejb2/SimpleService2!se.kodarkatten.casual.example.service.ISimpleService2
    java:global/casual-test-app-custom-2/test-ejb2/SimpleService2
    java:app/test-ejb2/SimpleService2
    java:module/SimpleService2

2018-02-21 10:18:03,881 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-8) WFLYEJB0473: JNDI bindings for session bean named 'SimpleService2' in deployment unit 'subdeployment "test-ejb.jar" of deployment "casual-test-app-0.0.1.ear"' are as follows:

    java:global/casual-test-app-custom-2/test-ejb/SimpleService2!se.kodarkatten.casual.example.service.ISimpleService2
    java:app/test-ejb/SimpleService2!se.kodarkatten.casual.example.service.ISimpleService2
    java:module/SimpleService2!se.kodarkatten.casual.example.service.ISimpleService2
    java:jboss/exported/casual-test-app-custom-2/test-ejb/SimpleService2!se.kodarkatten.casual.example.service.ISimpleService2
    java:global/casual-test-app-custom-2/test-ejb/SimpleService2
    java:app/test-ejb/SimpleService2
    java:module/SimpleService2

2018-02-21 10:18:03,909 INFO  [org.jboss.weld.deployer] (MSC service thread 1-2) WFLYWELD0003: Processing weld deployment casual-jca-0.0.1.rar
2018-02-21 10:18:03,911 INFO  [org.jboss.as.connector.deployment] (MSC service thread 1-2) WFLYJCA0002: Bound JCA ConnectionFactory [java:/JmsXA]
2018-02-21 10:18:03,912 INFO  [org.wildfly.extension.messaging-activemq] (MSC service thread 1-2) WFLYMSGAMQ0002: Bound messaging object to jndi name java:jboss/DefaultJMSConnectionFactory
2018-02-21 10:18:03,916 INFO  [org.jboss.weld.deployer] (MSC service thread 1-1) WFLYWELD0003: Processing weld deployment casual-inbound-handler-fielded-buffer.jar
2018-02-21 10:18:03,917 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-1) WFLYEJB0473: JNDI bindings for session bean named 'FieldedBufferHandler' in deployment unit 'subdeployment "casual-inbound-handler-fielded-buffer.jar" of deployment "casual-jca-0.0.1.ear"' are as follows:

    java:global/casual-jca-app/casual-inbound-handler-fielded-buffer/FieldedBufferHandler!se.kodarkatten.casual.jca.inbound.handler.buffer.BufferHandler
    java:app/casual-inbound-handler-fielded-buffer/FieldedBufferHandler!se.kodarkatten.casual.jca.inbound.handler.buffer.BufferHandler
    java:module/FieldedBufferHandler!se.kodarkatten.casual.jca.inbound.handler.buffer.BufferHandler
    java:global/casual-jca-app/casual-inbound-handler-fielded-buffer/FieldedBufferHandler
    java:app/casual-inbound-handler-fielded-buffer/FieldedBufferHandler
    java:module/FieldedBufferHandler

2018-02-21 10:18:03,918 INFO  [org.jboss.weld.deployer] (MSC service thread 1-7) WFLYWELD0003: Processing weld deployment casual-inbound-handler-jscd-buffer.jar
2018-02-21 10:18:03,919 INFO  [org.jboss.weld.deployer] (MSC service thread 1-4) WFLYWELD0003: Processing weld deployment casual-inbound-handler-javaee-service.jar
2018-02-21 10:18:03,919 INFO  [org.jboss.weld.deployer] (MSC service thread 1-3) WFLYWELD0003: Processing weld deployment casual-inbound-handler-casual-service.jar
2018-02-21 10:18:03,920 INFO  [org.jboss.weld.deployer] (MSC service thread 1-6) WFLYWELD0003: Processing weld deployment casual-inbound.jar
2018-02-21 10:18:03,921 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-7) WFLYEJB0473: JNDI bindings for session bean named 'JavaServiceCallBufferHandler' in deployment unit 'subdeployment "casual-inbound-handler-jscd-buffer.jar" of deployment "casual-jca-0.0.1.ear"' are as follows:

    java:global/casual-jca-app/casual-inbound-handler-jscd-buffer/JavaServiceCallBufferHandler!se.kodarkatten.casual.jca.inbound.handler.buffer.BufferHandler
    java:app/casual-inbound-handler-jscd-buffer/JavaServiceCallBufferHandler!se.kodarkatten.casual.jca.inbound.handler.buffer.BufferHandler
    java:module/JavaServiceCallBufferHandler!se.kodarkatten.casual.jca.inbound.handler.buffer.BufferHandler
    java:global/casual-jca-app/casual-inbound-handler-jscd-buffer/JavaServiceCallBufferHandler
    java:app/casual-inbound-handler-jscd-buffer/JavaServiceCallBufferHandler
    java:module/JavaServiceCallBufferHandler

2018-02-21 10:18:03,921 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-3) WFLYEJB0473: JNDI bindings for session bean named 'CasualServiceHandler' in deployment unit 'subdeployment "casual-inbound-handler-casual-service.jar" of deployment "casual-jca-0.0.1.ear"' are as follows:

    java:global/casual-jca-app/casual-inbound-handler-casual-service/CasualServiceHandler!se.kodarkatten.casual.jca.inbound.handler.service.ServiceHandler
    java:app/casual-inbound-handler-casual-service/CasualServiceHandler!se.kodarkatten.casual.jca.inbound.handler.service.ServiceHandler
    java:module/CasualServiceHandler!se.kodarkatten.casual.jca.inbound.handler.service.ServiceHandler
    java:global/casual-jca-app/casual-inbound-handler-casual-service/CasualServiceHandler
    java:app/casual-inbound-handler-casual-service/CasualServiceHandler
    java:module/CasualServiceHandler

2018-02-21 10:18:03,921 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-4) WFLYEJB0473: JNDI bindings for session bean named 'JavaeeServiceHandler' in deployment unit 'subdeployment "casual-inbound-handler-javaee-service.jar" of deployment "casual-jca-0.0.1.ear"' are as follows:

    java:global/casual-jca-app/casual-inbound-handler-javaee-service/JavaeeServiceHandler!se.kodarkatten.casual.jca.inbound.handler.service.ServiceHandler
    java:app/casual-inbound-handler-javaee-service/JavaeeServiceHandler!se.kodarkatten.casual.jca.inbound.handler.service.ServiceHandler
    java:module/JavaeeServiceHandler!se.kodarkatten.casual.jca.inbound.handler.service.ServiceHandler
    java:global/casual-jca-app/casual-inbound-handler-javaee-service/JavaeeServiceHandler
    java:app/casual-inbound-handler-javaee-service/JavaeeServiceHandler
    java:module/JavaeeServiceHandler

2018-02-21 10:18:03,964 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-5) WFLYEJB0473: JNDI bindings for session bean named 'EchoService' in deployment unit 'deployment "casual-java-testapp.war"' are as follows:

    java:global/casual-java-testapp/EchoService!se.kodarkatten.casual.example.EchoService
    java:app/casual-java-testapp/EchoService!se.kodarkatten.casual.example.EchoService
    java:module/EchoService!se.kodarkatten.casual.example.EchoService
    java:global/casual-java-testapp/EchoService
    java:app/casual-java-testapp/EchoService
    java:module/EchoService

2018-02-21 10:18:03,968 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-5) WFLYEJB0473: JNDI bindings for session bean named 'SimpleService' in deployment unit 'deployment "casual-java-testapp.war"' are as follows:

    java:global/casual-java-testapp/SimpleService!se.kodarkatten.casual.example.service.ISimpleService
    java:app/casual-java-testapp/SimpleService!se.kodarkatten.casual.example.service.ISimpleService
    java:module/SimpleService!se.kodarkatten.casual.example.service.ISimpleService
    java:jboss/exported/casual-java-testapp/SimpleService!se.kodarkatten.casual.example.service.ISimpleService
    java:global/casual-java-testapp/SimpleService
    java:app/casual-java-testapp/SimpleService
    java:module/SimpleService

2018-02-21 10:18:03,968 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-5) WFLYEJB0473: JNDI bindings for session bean named 'QueueService' in deployment unit 'deployment "casual-java-testapp.war"' are as follows:

    java:global/casual-java-testapp/QueueService!se.kodarkatten.casual.example.QueueService
    java:app/casual-java-testapp/QueueService!se.kodarkatten.casual.example.QueueService
    java:module/QueueService!se.kodarkatten.casual.example.QueueService
    java:global/casual-java-testapp/QueueService
    java:app/casual-java-testapp/QueueService
    java:module/QueueService

2018-02-21 10:18:03,972 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-5) WFLYEJB0473: JNDI bindings for session bean named 'InboundOrderRestService' in deployment unit 'deployment "casual-java-testapp.war"' are as follows:

    java:global/casual-java-testapp/InboundOrderRestService!se.kodarkatten.casual.example.inbound.InboundOrderRestService
    java:app/casual-java-testapp/InboundOrderRestService!se.kodarkatten.casual.example.inbound.InboundOrderRestService
    java:module/InboundOrderRestService!se.kodarkatten.casual.example.inbound.InboundOrderRestService
    java:global/casual-java-testapp/InboundOrderRestService
    java:app/casual-java-testapp/InboundOrderRestService
    java:module/InboundOrderRestService

2018-02-21 10:18:03,973 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-5) WFLYEJB0473: JNDI bindings for session bean named 'OrderRestService' in deployment unit 'deployment "casual-java-testapp.war"' are as follows:

    java:global/casual-java-testapp/OrderRestService!se.kodarkatten.casual.example.order.OrderRestService
    java:app/casual-java-testapp/OrderRestService!se.kodarkatten.casual.example.order.OrderRestService
    java:module/OrderRestService!se.kodarkatten.casual.example.order.OrderRestService
    java:global/casual-java-testapp/OrderRestService
    java:app/casual-java-testapp/OrderRestService
    java:module/OrderRestService

2018-02-21 10:18:03,974 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-5) WFLYEJB0473: JNDI bindings for session bean named 'CasualOrderService' in deployment unit 'deployment "casual-java-testapp.war"' are as follows:

    java:global/casual-java-testapp/CasualOrderService!se.kodarkatten.casual.example.service.order.ICasualOrderServiceRemote
    java:app/casual-java-testapp/CasualOrderService!se.kodarkatten.casual.example.service.order.ICasualOrderServiceRemote
    java:module/CasualOrderService!se.kodarkatten.casual.example.service.order.ICasualOrderServiceRemote
    java:jboss/exported/casual-java-testapp/CasualOrderService!se.kodarkatten.casual.example.service.order.ICasualOrderServiceRemote
    java:global/casual-java-testapp/CasualOrderService!se.kodarkatten.casual.example.service.order.ICasualOrderService
    java:app/casual-java-testapp/CasualOrderService!se.kodarkatten.casual.example.service.order.ICasualOrderService
    java:module/CasualOrderService!se.kodarkatten.casual.example.service.order.ICasualOrderService

2018-02-21 10:18:03,975 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-5) WFLYEJB0473: JNDI bindings for session bean named 'OrderService' in deployment unit 'deployment "casual-java-testapp.war"' are as follows:

    java:global/casual-java-testapp/OrderService!se.kodarkatten.casual.example.service.order.IOrderService
    java:app/casual-java-testapp/OrderService!se.kodarkatten.casual.example.service.order.IOrderService
    java:module/OrderService!se.kodarkatten.casual.example.service.order.IOrderService
    java:global/casual-java-testapp/OrderService!se.kodarkatten.casual.example.service.order.IOrderServiceRemote
    java:app/casual-java-testapp/OrderService!se.kodarkatten.casual.example.service.order.IOrderServiceRemote
    java:module/OrderService!se.kodarkatten.casual.example.service.order.IOrderServiceRemote
    java:jboss/exported/casual-java-testapp/OrderService!se.kodarkatten.casual.example.service.order.IOrderServiceRemote

2018-02-21 10:18:04,005 INFO  [org.jboss.weld.Version] (MSC service thread 1-3) WELD-000900: 2.3.5 (Final)

正如您的日志所说,您可以访问任何列出的 JNDI 名称下的 EJB

java:global/casual-test-app-custom-2/test-ejb/SimpleService2!se.kodarkatten.casual.example.service.ISimpleService2
java:app/test-ejb/SimpleService2!se.kodarkatten.casual.example.service.ISimpleService2
java:module/SimpleService2!se.kodarkatten.casual.example.service.ISimpleService2
java:jboss/exported/casual-test-app-custom-2/test-ejb/SimpleService2!se.kodarkatten.casual.example.service.ISimpleService2
java:global/casual-test-app-custom-2/test-ejb/SimpleService2
java:app/test-ejb/SimpleService2
java:module/SimpleService2

可能在您的情况下,带有 java:global/... 的效果最好。

我找到了几种不同的实现方法,但 none 非常理想。最后我们选择了解决方案 2,因为它适用于我们需要支持的大多数场景。

解决方案 1 - 在需要时使用注释数据创建服务

使用 CDI BeanManager 以根据在 SPI 扩展注释元数据中发现的信息创建我的远程服务对象。这是在 section 16.5 中记录的,尽管这是有效的最终版本:

public Object getServiceReference( AnnotatedType<CasualService> type )
{
    BeanManager beanManager = CDI.current().getBeanManager();
    CreationalContext<CasualService> ctx = beanManager.createCreationalContext(null);
    BeanAttributes<CasualService> attributes = beanManager.createBeanAttributes( type );
    InjectionTargetFactory<CasualService> itf = beanManager.getInjectionTargetFactory( type );
    Bean<CasualService> bean = beanManager.createBean( attributes, type.getJavaClass(), itf );
    Object reference = beanManager.getReference( bean, type.getBaseType(), ctx );
    return reference;
}

不幸的是,这只在 Wildfly 中有效,在 Weblogic 中无效。 weblogic 中的问题是由于 Weblogic bean 管理器实现创建 bean 的方式造成的;它不使用当前的线程 classloader,由于不满足的依赖关系或 class 未找到而导致异常。

我对每次都需要创建服务对象也不是很满意,因为 slb 缓存等应用程序服务器设置不会被接受。

解决方案 2 - 使用定时器服务执行延迟查找遍历 JNDI 树以进行匹配

  1. 在 spi Extension 发现注解的过程中,保存所有的注解元数据。
  2. 定时服务定期运行以遍历 JNDI 树以查找所有代理对象/远程服务。 (需要计时器服务,因为当扩展发现运行时 weblogic 没有可用的 JNDI 条目。)
  3. 使用服务注释元数据 "match" 它们来候选 JNDI url。基于来自 Global Portable JNDI names
  4. 的信息的文本匹配
  5. 使用代理对象 classloader 加载实现 class 检查它的方法注释数据以查看它是否是预期的服务 (加载 class 是作为代理需要 class 方法不包含任何注释元数据)
  6. 重复该过程,直到所有服务都有匹配的 JNDI。

有一些匹配不起作用的边缘情况,但对于这些边缘情况,我创建了另一个可以在服务 Class 上提供的注释,它硬编码了预期的 JNDI 路径,所以我们不不必搜索。

这种方法在 wildfly 和 weblogic 中都有效。