jakartaee / messaging

Jakarta Messaging
https://eclipse.org/ee4j/messaging
Other
39 stars 32 forks source link

@MessageConsumer for discovery #241

Open dblevins opened 4 years ago

dblevins commented 4 years ago

Replace the JMS 2.1 proposed JMSMessageDrivenBean with an annotation, tentatively called @MessageConsumer

Background

JMS 2.1 proposed a JMSMessageDrivenBean interface which would be implemented by the MDB to allow the bean to be mapped to a Connector per the Connector 1.7 rules for no-interface views.

The Connector 1.7 rules require the Connector Provider to supply an interface with no methods and specify it as the message listener interface. The proposed JMSMessageDrivenBean would have been specified by the JMS RA (Connector) in the ra.xml file as follows:

<inbound-resourceadapter>
    <messageadapter>
        <messagelistener>
            <messagelistener-type>javax.jms.JMSMessageDrivenBean</messagelistener-type>
            <activationspec>
                <!-- omitted for brevity -->
            </activationspec>
        </messagelistener>
    </messageadapter>
</inbound-resourceadapter>

A bean developer would then implement this no-method interface so that it could have the ability to use the new annotation-based JMS 2.1 API. For example:

import javax.annotation.Resource;
import javax.ejb.MessageDriven;
import javax.jms.ConnectionFactory;
import javax.jms.JMSContext;
import javax.jms.JMSException;
import javax.jms.JMSMessageDrivenBean;
import javax.jms.JMSProducer;
import javax.jms.JMSRuntimeException;
import javax.jms.MessageHeader;
import javax.jms.ObjectMessage;
import javax.jms.QueueListener;
import javax.jms.Topic;

@MessageDriven
public class BuildAndNotify implements JMSMessageDrivenBean {

    @Resource
    private ConnectionFactory connectionFactory;

    @QueueListener("PROJECT.BUILD")
    public void buildProject(@MessageHeader(MessageHeader.Header.JMSReplyTo) final Topic buildNotifications,
                             @MessageHeader(MessageHeader.Header.JMSCorrelationID) final String buildId,
                             final ObjectMessage objectMessage) throws JMSException {
        // ...
    }
}

Issues

While functional, this solution is a bit awkward:

Proposal

As annotations are essentially interfaces, the proposal is to update the Connector specification such that the <messagelistener-type> may be either an interface or an @interface (annotation). When the type is an annotation, this shall be deemed to function identically to the Connector 1.7 no-interface view.

For Jakarta Messaging the implication is that the proposed JMSMessageDrivenBean interface could be replaced with an annotation, such as MessageConsumer:

package jakarta.jms;

import javax.resource.spi.ConnectorDrivenBean;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 * This annotation replaces the proposed JMSMessageDrivenBean interface
 */
@Retention(RUNTIME)
@Target({ANNOTATION_TYPE, TYPE})
@ConnectorDrivenBean
public @interface MessageConsumer {
}

A bean developer could use that annotation as follows:

@MessageConsumer
public class BuildAndNotify {

    @Resource
    private ConnectionFactory connectionFactory;

    @QueueListener("PROJECT.BUILD")
    public void buildProject(@MessageHeader(MessageHeader.Header.JMSReplyTo) final Topic buildNotifications,
                             @MessageHeader(MessageHeader.Header.JMSCorrelationID) final String buildId,
                             final ObjectMessage objectMessage) throws JMSException {
        // ...
    }
}

Benefits

bshannon commented 4 years ago

Was a corresponding issue filed against the Connector spec to enable this usage?

keilw commented 4 years ago

Btw, will the package really remain jakarta.jms, not jakarta.messaging?

dblevins commented 4 years ago

@bshannon not yet, but filing that and linking it in this issue is the plan. Likely this weekend.

m-reza-rahman commented 4 years ago

This is a solid start. What I have had in mind is to make the @MessageConsumer top level annotation unnecessary and the beans become just CDI beans with some allowed sensible scopes.

I am working to get my paperwork sorted out so I can contribute more than just comments. In the meanwhile, please let me know if there is some way I can help.

Reza Rahman Principal Program Manager Java on Azure

Please note that views here are my own as an individual community member and do not represent the views of my employer.

m-reza-rahman commented 4 years ago

@keilw I think it is best to keep the package names unchanged. It is not ideal I know, but it will make writing backwards compatibility tools and functionality easier.

Reza Rahman Principal Program Manager Java on Azure

Please note that views here are my own as an individual community member and do not represent the views of my employer.