简体   繁体   English

自由激活@MessageDriven

[英]Liberty activate @MessageDriven

I want to activate custom message listener on liberty application server.我想在自由应用程序服务器上激活自定义消息侦听器。

this is my code:这是我的代码:

@MessageDriven(name = "Receiver")
public class Receiver implements InboundListener {

    @Override
    public void receiveMessage(String message) {
        System.out.println("Message Received : " + message);
    }
}      

and this is server.xml:这是server.xml:

<?xml version="1.0" encoding="UTF-8"?>
<server description="Dandelion IOT server">
    <featureManager>
        <feature>cdi-2.0</feature>
        <feature>beanValidation-2.0</feature>
        <feature>appSecurity-3.0</feature>
        <feature>jpa-2.2</feature>
        <feature>jaxrs-2.1</feature>
        <feature>jsonb-1.0</feature>
        <feature>jsonp-1.1</feature>
        <feature>managedBeans-1.0</feature>
        <feature>websocket-1.1</feature>
        <feature>ejbLite-3.2</feature>
        <feature>jca-1.7</feature>
        <feature>jndi-1.0</feature>
        <feature>mdb-3.2</feature>
        <feature>localConnector-1.0</feature>
    </featureManager>
    <library id="DandelionLibs">
        <fileset dir="/etc/dandelion/lib" includes="*.jar"/>
    </library>
    <jdbcDriver id="database-driver" libraryRef="DandelionLibs"/>
    <dataSource jndiName="JTA-DataSource" transactional="true" jdbcDriverRef="database-driver">
        <properties databaseName="${database.name}" serverName="${database.hostname}" portNumber="${database.port}"
                    user="${database.username}" password="${database.password}"/>
    </dataSource>

    <resourceAdapter id="dra" autoStart="true" location="/etc/dandelion/lib/RA.rar"/>

    <connectionFactory jndiName="h5/sampleConnection">
        <properties.dra/>
    </connectionFactory>

    <activationSpec id="h5/inboundListener">
        <properties.dra.DandelionActivationSpec/>
    </activationSpec>

    <webApplication id="dandelion-web"
                    location="dandelion-war-0.1-SNAPSHOT.war"
                    name="dandelion-web">
        <classloader classProviderRef="dra"/>
    </webApplication>

    <basicRegistry id="basic" realm="BasicRealm"/>
    <httpSession securityIntegrationEnabled="false"/>
    <httpEndpoint id="defaultHttpEndpoint" httpPort="8080" httpsPort="9443">
        <httpOptions http2="enabled"/>
    </httpEndpoint>
    <webContainer disableXPoweredBy="true"/>
    <applicationManager autoExpand="true"/>
    <applicationMonitor updateTrigger="mbean"/>
</server>    

and my activation specification:和我的激活规范:

@Activation(messageListeners = InboundListener.class)
public class DandelionActivationSpec implements ActivationSpec {

    private ResourceAdapter resourceAdapter;

    @Override
    public void validate() throws InvalidPropertyException {
    }

    @Override
    public ResourceAdapter getResourceAdapter() {
        return resourceAdapter;
    }

    @Override
    public void setResourceAdapter(ResourceAdapter ra) throws ResourceException {
        this.resourceAdapter = ra;
    }
}       

and ra.xml:和 ra.xml:

<?xml version="1.0" encoding="UTF-8"?>
<connector xmlns="http://xmlns.jcp.org/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
           http://xmlns.jcp.org/xml/ns/javaee/connector_1_7.xsd"
           version="1.7">
    <description>Sample Resource Adapter</description>
    <display-name>Sample Resource Adapter</display-name>
    <eis-type>Sample Resource Adapter</eis-type>
    <resourceadapter-version>1.0</resourceadapter-version>
    <license>
        <license-required>false</license-required>
    </license>
    <resourceadapter>
        <resourceadapter-class>org.company.dandelion.adapter.DandelionResourceAdapter</resourceadapter-class>
        <outbound-resourceadapter>
            <connection-definition>
                <managedconnectionfactory-class>org.company.dandelion.adapter.DandelionManagedConnectionFactory</managedconnectionfactory-class>
                <connectionfactory-interface>org.company.dandelion.api.DandelionConnectionFactory</connectionfactory-interface>
                <connectionfactory-impl-class>org.company.dandelion.adapter.DandelionConnectionFactoryImpl</connectionfactory-impl-class>
                <connection-interface>org.company.dandelion.api.DandelionConnection</connection-interface>
                <connection-impl-class>org.company.dandelion.adapter.DandelionConnectionImpl</connection-impl-class>
            </connection-definition>
            <transaction-support>NoTransaction</transaction-support>
            <reauthentication-support>false</reauthentication-support>
        </outbound-resourceadapter>
        <inbound-resourceadapter>
            <messageadapter>
                <messagelistener>
                    <messagelistener-type>org.company.dandelion.api.InboundListener</messagelistener-type>
                    <activationspec>
                        <activationspec-class>org.company.dandelion.adapter.DandelionActivationSpec</activationspec-class>
                    </activationspec>
                </messagelistener>
            </messageadapter>
        </inbound-resourceadapter>
    </resourceadapter>
</connector>

Liberty application server result this log on console: Liberty 应用程序服务器在控制台上生成此日志:

[WARNING ] CNTR4015W: The message endpoint for the Receiver message-driven bean cannot be activated because the dandelion-war-0.1-SNAPSHOT/Receiver activation specification is not available. The message endpoint will not receive messages until the activation specification becomes available.        

outbound resource adapter working without any problem, but inbound does not receive any message !出站资源适配器正常工作,但入站没有收到任何消息!
I read this links before asking this question but can not understand how can fix this problem:我在问这个问题之前阅读了这个链接,但不明白如何解决这个问题:
Link 1 链接 1
Link 2 链接 2
Link 3 链接 3
What part of configuration/Code has problem?配置/代码的哪一部分有问题?

UPDATE:更新:
I change configuration to this:我将配置更改为:

<activationSpec id="dandelion-web/Receiver">
    <properties.dra/>
</activationSpec>
<webApplication id="dandelion-web"
                location="dandelion-web.war"
                name="dandelion-web">
    <classloader classProviderRef="dra"/>
</webApplication>     

now receive this error on console:现在在控制台上收到此错误:

[AUDIT   ] J2CA7001I: Resource adapter dra installed in 1.911 seconds.
[AUDIT   ] CWWKT0016I: Web application available (default_host): http://localhost:8080/
[AUDIT   ] CWWKZ0001I: Application dandelion started in 8.064 seconds.
[err] javax.resource.spi.UnavailableException: activating thread not allowed to create endpoint during activation.
[err]   at com.ibm.ws.ejbcontainer.mdb.BaseMessageEndpointFactory.createEndpoint(BaseMessageEndpointFactory.java:406)
[err]   at [internal classes]
[err]   at com.company.dandelion.adapter.DandelionResourceAdapter.endpointActivation(DandelionResourceAdapter.java:56)
[err]   at com.ibm.ws.jca.service.EndpointActivationService.activateEndpoint(EndpointActivationService.java:585)
[err]   at [internal classes]
[err]   at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[err]   at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[err]   at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[err]   at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[err]   at org.apache.felix.scr.impl.inject.methods.BaseMethod.invokeMethod(BaseMethod.java:242)
[err]   at org.apache.felix.scr.impl.inject.methods.BaseMethod.access$500(BaseMethod.java:41)
[err]   at org.apache.felix.scr.impl.inject.methods.BaseMethod$Resolved.invoke(BaseMethod.java:678)
[err]   at [internal classes]
[err]   at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
[err]   at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
[err]   at java.base/java.lang.Thread.run(Thread.java:834)
[AUDIT   ] CWWKF0012I: The server installed the following features: [appSecurity-3.0, beanValidation-2.0, cdi-2.0, distributedMap-1.0, ejbLite-3.2, el-3.0, jaxrs-2.1, jaxrsClient-2.1, jca-1.7, jdbc-4.2, jndi-1.0, jpa-2.2, jpaContainer-2.2, jsonb-1.0, jsonp-1.1, localConnector-1.0, managedBeans-1.0, mdb-3.2, servlet-4.0, ssl-1.0, websocket-1.1].
[AUDIT   ] CWWKF0011I: The dandelion server is ready to run a smarter planet. The dandelion server started in 12.919 seconds.     

this is my DandelionResourceAdapter:这是我的蒲公英资源适配器:

@Connector(
        description = "Sample Resource Adapter",
        displayName = "Sample Resource Adapter",
        eisType = "Sample Resource Adapter",
        version = "1.0"
)
public class DandelionResourceAdapter implements ResourceAdapter {

    final Map<DandelionActivationSpec, EndpointTarget> targets = new ConcurrentHashMap<>();

    public void start(BootstrapContext bootstrapContext) throws ResourceAdapterInternalException {
    }

    public void stop() {
    }

    public void endpointActivation(final MessageEndpointFactory messageEndpointFactory,
                                   final ActivationSpec activationSpec) {
        final DandelionActivationSpec sampleActivationSpec = (DandelionActivationSpec) activationSpec;

        // ->>>>>>>>> EXCEPTION FOR THIS LINES : 
        try {
            final MessageEndpoint messageEndpoint = messageEndpointFactory.createEndpoint(null);
            final EndpointTarget target = new EndpointTarget(messageEndpoint);
            targets.put(sampleActivationSpec, target);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void endpointDeactivation(MessageEndpointFactory messageEndpointFactory, ActivationSpec activationSpec) {
        final DandelionActivationSpec sampleActivationSpec = (DandelionActivationSpec) activationSpec;

        final EndpointTarget endpointTarget = targets.get(sampleActivationSpec);
        if (endpointTarget == null) {
            throw new IllegalStateException("No EndpointTarget to undeploy for ActivationSpec " + activationSpec);
        }

        endpointTarget.messageEndpoint.release();
    }

    public XAResource[] getXAResources(ActivationSpec[] activationSpecs) throws ResourceException {
        return new XAResource[0];
    }

    public void sendMessage(final String message) {
        final Collection<EndpointTarget> endpoints = this.targets.values();
        for (final EndpointTarget endpoint : endpoints) {
            endpoint.invoke(message);
        }
    }

    public static class EndpointTarget {
        private final MessageEndpoint messageEndpoint;

        public EndpointTarget(final MessageEndpoint messageEndpoint) {
            this.messageEndpoint = messageEndpoint;
        }

        public void invoke(final String message) {
            ((InboundListener) this.messageEndpoint).receiveMessage(message);
        }
    }
}

Iranians have a proverb that says: a seeker is a finder伊朗人有一句谚语说:寻求者就是发现者
Finally after about 10 days search in internet and wrote simple codes.最后在互联网上搜索了大约 10 天并编写了简单的代码。 I found how can fix this problem.我发现如何解决这个问题。
Depend on application server, Message Endpoint should not created on endpointActivation method.取决于应用程序服务器,不应在 endpointActivation 方法上创建消息端点。
actually TomEE Application server does not result any exception on this code but liberty application server result this exceptions.实际上,TomEE 应用程序服务器不会对此代码产生任何异常,但自由应用程序服务器会导致此异常。
I wrote few simple application and published on github.我写了一些简单的应用程序并发布在 github 上。
you can compile and run this application on both TomEE or Liberty.您可以在 TomEE 或 Liberty 上编译和运行此应用程序。
I will publish more examples in the future, so you can use it too.以后我会发布更多的例子,所以你也可以使用它。

My GitHub Repository我的 GitHub 存储库

I also got CNTR4015W: The message endpoint for the.. bean cannot be activated because the.. activation specification is not available.我还收到 CNTR4015W:无法激活 .. bean 的消息端点,因为 .. 激活规范不可用。

Problem was, I had used.ear-name/.mdb-name/ejb-name but had also set a different <module-name> in ejb-jar.xml (which has priority)问题是,我使用了 .ear-name/.mdb-name/ejb-name 但还在 ejb-jar.xml 中设置了不同的<module-name> (优先级)

This is documented in the Note at https://www.ibm.com/support/knowledgecenter/SSEQTP_liberty/com.ibm.websphere.wlp.doc/ae/twlp_dep_msg_mdbjca.html这记录在https://www.ibm.com/support/knowledgecenter/SSEQTP_liberty/com.ibm.websphere.wlp.doc/ae/twlp_dep_msg_mdbjca.html的注释中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM