ARTEMIS-3484 flesh out Jakarta Messaging support

Back in version 2.17.0 we began to provide Maven artifacts for Jakarta
Messaging client resources. This commit expands that support in the
following ways:

 - Distribute a Jakarta Messaging 3.0 client with the broker (in the
   'lib/client' directory alongside the JMS client.
 - Update documentation.
 - Add example using the Jakarta Messaging client.
 - Update Artemis CLI to use core instead of JMS as it was causing
   conflicts with the new Jarkarta Messaging client.
 - Add example to build Jarkarta Messaging version of the JCA RA for
   deployment into Jakarta EE 9 application servers.
This commit is contained in:
Justin Bertram 2021-09-14 22:20:18 -05:00 committed by clebertsuconic
parent c3b403a980
commit 447422604c
23 changed files with 919 additions and 70 deletions

View File

@ -42,6 +42,11 @@
<artifactId>artemis-jms-client-all</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jakarta-client-all</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-boot</artifactId>
@ -215,7 +220,7 @@
<version>${project.version} </version>
<type>war</type>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>

View File

@ -124,6 +124,16 @@
<unpack>false</unpack>
<useProjectArtifact>false</useProjectArtifact>
</dependencySet>
<dependencySet>
<directoryMode>0755</directoryMode>
<fileMode>0644</fileMode>
<includes>
<include>org.apache.activemq:artemis-jakarta-client-all</include>
</includes>
<outputDirectory>lib/client</outputDirectory>
<unpack>false</unpack>
<useProjectArtifact>false</useProjectArtifact>
</dependencySet>
<!-- native -->
<dependencySet>
<includes>
@ -163,7 +173,7 @@
<directoryMode>0755</directoryMode>
<fileMode>0644</fileMode>
</dependencySet>
<!-- Management Console Dependencies -->
<dependencySet>
<includes>
@ -198,7 +208,7 @@
<directoryMode>0755</directoryMode>
<fileMode>0644</fileMode>
</dependencySet>
</dependencySets>
<fileSets>
<!-- schema -->

View File

@ -69,6 +69,7 @@ cd paging; mvn verify; cd ..
cd pre-acknowledge; mvn verify; cd ..
cd producer-rate-limit; mvn verify; cd ..
cd queue; mvn verify; cd ..
cd queue-jakarta; mvn verify; cd ..
cd queue-requestor; mvn verify; cd ..
cd queue-selector; mvn verify; cd ..
cd reattach-node; mvn verify; cd ..

View File

@ -72,6 +72,7 @@ cd paging; mvn verify; cd ..
cd pre-acknowledge; mvn verify; cd ..
cd producer-rate-limit; mvn verify; cd ..
cd queue; mvn verify; cd ..
cd queue-jakarta; mvn verify; cd ..
cd queue-requestor; mvn verify; cd ..
cd queue-selector; mvn verify; cd ..
cd reattach-node; mvn verify; cd ..

View File

@ -0,0 +1,136 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-pom</artifactId>
<version>2.19.0-SNAPSHOT</version>
</parent>
<artifactId>artemis-jakarta-client-all</artifactId>
<packaging>jar</packaging>
<name>ActiveMQ Artemis Jakarta Messaging Client All</name>
<properties>
<activemq.basedir>${project.basedir}/..</activemq.basedir>
<jakarta.jms-api.version>3.0.0</jakarta.jms-api.version>
<jakarta.json-api.version>2.0.1</jakarta.json-api.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jakarta-client</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createSourcesJar>true</createSourcesJar>
<shadeSourcesContent>true</shadeSourcesContent>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>INSTALL.html</exclude>
<exclude>LICENSE</exclude>
<exclude>README</exclude>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>META-INF/ASL2.0</exclude>
<exclude>META-INF/DEPENDENCIES.txt</exclude>
<exclude>META-INF/LICENSE.txt</exclude>
<exclude>META-INF/NOTICE.txt</exclude>
<exlude>overview.html</exlude>
</excludes>
</filter>
<filter>
<artifact>org.jgroups:jgroups</artifact>
<includes>
<include>org/jgroups/**</include>
<include>jg-magic-map.xml</include>
<include>jg-protocol-ids.xml</include>
<include>*.properties</include>
<include>*.xsd</include>
</includes>
</filter>
</filters>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/DEPENDENCIES</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ApacheNoticeResourceTransformer">
<addHeader>false</addHeader>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
<resource>.txt</resource>
<resource>features.xml</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
</transformers>
<relocations>
<relocation>
<pattern>org.apache.activemq</pattern>
<shadedPattern>org.apache.activemq</shadedPattern>
</relocation>
<relocation>
<pattern>org.apache.geronimo</pattern>
<shadedPattern>org.apache.activemq.artemis.shaded.org.apache.geronimo</shadedPattern>
</relocation>
<relocation>
<pattern>com.google</pattern>
<shadedPattern>org.apache.activemq.artemis.shaded.com.google</shadedPattern>
</relocation>
<relocation>
<pattern>org.apache.johnzon</pattern>
<shadedPattern>org.apache.activemq.artemis.shaded.org.apache.johnzon</shadedPattern>
</relocation>
<relocation>
<pattern>org.apache.commons</pattern>
<shadedPattern>org.apache.activemq.artemis.shaded.org.apache.commons</shadedPattern>
</relocation>
<relocation>
<pattern>org.jboss</pattern>
<shadedPattern>org.apache.activemq.artemis.shaded.org.jboss</shadedPattern>
</relocation>
<relocation>
<pattern>org.jgroups</pattern>
<shadedPattern>org.apache.activemq.artemis.shaded.org.jgroups</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -64,7 +64,7 @@
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jms-client</artifactId>
<artifactId>artemis-core-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
@ -72,10 +72,6 @@
<artifactId>artemis-cli</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>jakarta.jms</groupId>
<artifactId>jakarta.jms-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>

View File

@ -18,9 +18,10 @@ package org.apache.activemq.artemis.maven;
import java.io.File;
import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
import org.apache.activemq.artemis.api.core.client.ServerLocator;
import org.apache.activemq.artemis.boot.Artemis;
import org.apache.activemq.artemis.cli.commands.Run;
import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
@ -105,11 +106,11 @@ public class ArtemisCLIPlugin extends ArtemisAbstractPlugin {
if (testURI != null) {
long timeout = System.currentTimeMillis() + spawnTimeout;
while (System.currentTimeMillis() <= timeout) {
try (ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory(testURI)) {
try (ServerLocator locator = ActiveMQClient.createServerLocator(testURI)) {
if (testUser != null && testPassword != null) {
cf.createConnection(testUser, testPassword).close();
locator.createSessionFactory().createSession(testUser, testPassword, false, false, false, false, 0).close();
} else {
cf.createConnection().close();
locator.createSessionFactory().createSession().close();
}
getLog().info("Server started");
} catch (Exception e) {

View File

@ -12,14 +12,20 @@ persistence (although JDBC is still an option if necessary).
Apache ActiveMQ Artemis clients, potentially on different physical machines,
interact with the Apache ActiveMQ Artemis broker. Apache ActiveMQ Artemis
currently ships two API implementations for messaging at the client side:
currently ships three API implementations for messaging at the client side:
1. Core client API. This is a simple intuitive Java API that is aligned with
the Artemis internal Core. Allowing more control of broker objects (e.g
direct creation of addresses and queues). The Core API also offers a full set
of messaging functionality without some of the complexities of JMS.
direct creation of addresses and queues). The Core API also offers a full
set of messaging functionality without some of the complexities of JMS.
2. JMS 2.0 client API. The standard JMS API is available at the client side.
This client is also compliant with the Jakarta Messaging 2.0 specification.
3. Jakarta Messaging 3.0 client API. This is essentially the same as the JMS
2.0 API. The only difference is the package names use `jakarta` insead of
`javax`. This difference was introduced due to the move from Oracle's
Java EE to Eclipse's Jakarta EE.
Apache ActiveMQ Artemis also provides different protocol implementations on the
server so you can use respective clients for these protocols:
@ -79,31 +85,31 @@ instantiate and embed brokers in your own application.
Read more about [embedding Apache ActiveMQ Artemis](embedding-activemq.md).
## Integrated with a Java EE application server
## Integrated with a Java/Jakarta EE application server
Apache ActiveMQ Artemis provides its own fully functional Java Connector
Architecture (JCA) adaptor which enables it to be integrated easily into any
Java EE compliant application server or servlet engine.
Java/Jakarta EE (henceforth just "EE") compliant application server or servlet
engine.
Java EE application servers provide Message Driven Beans (MDBs), which are a
special type of Enterprise Java Beans (EJBs) that can process messages from
sources such as JMS systems or mail systems.
EE application servers provide Message Driven Beans (MDBs), which are a special
type of Enterprise Java Beans (EJBs) that can process messages from sources
such as JMS systems or mail systems.
Probably the most common use of an MDB is to consume messages from a JMS
messaging system.
According to the Java EE specification, a Java EE application server uses a JCA
adapter to integrate with a JMS messaging system so it can consume messages for
MDBs.
According to the EE specification an application server uses a JCA adapter to
integrate with a JMS messaging system so it can consume messages for MDBs.
However, the JCA adapter is not only used by the Java EE application server for
However, the JCA adapter is not only used by the EE application server for
*consuming* messages via MDBs, it is also used when sending message to the JMS
messaging system e.g. from inside an EJB or servlet.
When integrating with a JMS messaging system from inside a Java EE application
When integrating with a JMS messaging system from inside an EE application
server it is always recommended that this is done via a JCA adaptor. In fact,
communicating with a JMS messaging system directly, without using JCA would be
illegal according to the Java EE specification.
illegal according to the EE specification.
The application server's JCA service provides extra functionality such as
connection pooling and automatic transaction enlistment, which are desirable
@ -113,10 +119,10 @@ JCA adapter, but this is not recommended since you will not be able to take
advantage of the JCA features, such as caching of JMS sessions, which can
result in poor performance.
Figure 3.2 below shows a Java EE application server integrating with a Apache
ActiveMQ Artemis server via the Apache ActiveMQ Artemis JCA adaptor. Note that
all communication between EJB sessions or entity beans and Message Driven beans
go through the adaptor and not directly to Apache ActiveMQ Artemis.
Figure 3.2 below shows an application server integrating with a Apache ActiveMQ
Artemis server via the Apache ActiveMQ Artemis JCA adaptor. Note that all
communication between EJB sessions or entity beans and Message Driven beans go
through the adaptor and not directly to Apache ActiveMQ Artemis.
The large arrow with the prohibited sign shows an EJB session bean talking
directly to the Apache ActiveMQ Artemis server. This is not recommended as

View File

@ -3,10 +3,10 @@
Apache ActiveMQ Artemis provides a powerful filter language based on a subset of the
SQL 92 expression syntax.
It is the same as the syntax used for JMS selectors, but the predefined
identifiers are different. For documentation on JMS selector syntax
please the JMS javadoc for
[javax.jms.Message](https://docs.oracle.com/javaee/7/api/javax/jms/Message.html).
It is the same as the syntax used for JMS & Jakarta Messaging selectors, but the
predefined identifiers are different. For documentation on JMS selector syntax
please the JavaDoc for [`javax.jms.Message`](https://docs.oracle.com/javaee/7/api/javax/jms/Message.html).
For the corresponding Jakarta Messaging JavaDoc see [`jakarta.jms.Message`](https://jakarta.ee/specifications/messaging/3.0/apidocs/jakarta/jms/message)
Filter expressions are used in several places in Apache ActiveMQ Artemis
@ -50,19 +50,20 @@ refer to attributes of the core message in an expression:
Any other identifiers used in core filter expressions will be assumed to
be properties of the message.
The JMS spec states that a String property should not get converted to a
numeric when used in a selector. So for example, if a message has the `age`
property set to String `21` then the following selector should not match
it: `age > 18`. Since Apache ActiveMQ Artemis supports STOMP clients which
can only send messages with string properties, that restriction is a bit
limiting. Therefore, if you want your filter expressions to auto-convert String
properties to the appropriate number type, just prefix it with
`convert_string_expressions:`. If you changed the filter expression in the
The JMS and Jakarta Messaging specs state that a String property should not
get converted to a numeric when used in a selector. So for example, if a
message has the `age` property set to `String` `21` then the following selector
should not match it: `age > 18`. Since Apache ActiveMQ Artemis supports STOMP
clients which can only send messages with string properties, that restriction
is a bit limiting. Therefore, if you want your filter expressions to
auto-convert `String` properties to the appropriate number type, just prefix it
with `convert_string_expressions:`. If you changed the filter expression in the
previous example to be `convert_string_expressions:age > 18`, then it would
match the aforementioned message.
The JMS spec also states that property identifiers (and therefore the
identifiers which are valid for use in a filter expression) are an:
The JMS and Jakarta Messaging specs also state that property identifiers (and
therefore the identifiers which are valid for use in a filter expression) are
an:
> unlimited-length sequence of letters and digits, the first of which must be
> a letter. A letter is any character for which the method
@ -70,10 +71,10 @@ identifiers which are valid for use in a filter expression) are an:
> or digit is any character for which the method `Character.isJavaLetterOrDigit`
> returns `true`.
This constraint means that hyphens (i.e. `-`) cannot be used.
However, this constraint can be overcome by using the `hyphenated_props:`
prefix. For example, if a message had the `foo-bar` property set to `0` then
the filter expression `hyphenated_props:foo-bar = 0` would match it.
This constraint means that hyphens (i.e. `-`) cannot be used. However, this
constraint can be overcome by using the `hyphenated_props:` prefix. For
example, if a message had the `foo-bar` property set to `0` then the filter
expression `hyphenated_props:foo-bar = 0` would match it.
## XPath

View File

@ -158,24 +158,27 @@ emerging standards in this space.
Let's take a brief look at these:
### Java Message Service (JMS)
### JMS & Jakarta Messaging
[JMS](https://en.wikipedia.org/wiki/Java_Message_Service) is part of Oracle's
Java EE specification. It's a Java API that encapsulates both message queue and
publish-subscribe messaging patterns. JMS is a lowest common denominator
specification - i.e. it was created to encapsulate common functionality of the
already existing messaging systems that were available at the time of its
creation.
[JMS](https://en.wikipedia.org/wiki/Java_Message_Service) was historically part
of Oracle's Java EE specification. However, in 2017 control was transferred to
the Eclipse Foundation and it is now known as [Jakarta Messaging](https://jakarta.ee/specifications/messaging/)
which is part of Jakarta EE.
JMS is a very popular API and is implemented by most messaging systems. JMS is
It is a Java API that encapsulates both message queue and publish-subscribe
messaging patterns. It is a lowest common denominator specification - i.e. it
was created to encapsulate common functionality of the already existing
messaging systems that were available at the time of its creation.
It is a very popular API and is implemented by most messaging systems. It is
only available to clients running Java.
JMS does not define a standard wire format - it only defines a programmatic API
so JMS clients and servers from different vendors cannot directly interoperate
It does not define a standard wire format - it only defines a programmatic API
so clients and servers from different vendors cannot directly interoperate
since each will use the vendor's own internal wire protocol.
Apache ActiveMQ Artemis provides a fully compliant [JMS 1.1 and JMS 2.0 client
implementation](using-jms.md).
Apache ActiveMQ Artemis provides client implementations which are a fully
compliant with [JMS 1.1 & 2.0 as well as Jakarta Messaging 2.0 & 3.0](using-jms.md).
### System specific APIs

View File

@ -20,8 +20,9 @@ modules out of the box. The 5 modules offer support for the following protocols:
#### APIs and Other Interfaces
Although JMS is a standardized API, it does not define a network protocol. The [ActiveMQ Artemis JMS 2.0 client](using-jms.md)
is implemented on top of the core protocol. We also provide a [client-side JNDI implementation](using-jms.md#jndi).
Although JMS and Jakarta Messaging are standardized APIs, they does not define a network protocol. The ActiveMQ Artemis
[JMS & Jakarta Messaging clients](using-jms.md) are implemented on top of the core protocol. We also provide a
[client-side JNDI implementation](using-jms.md#jndi).
The broker also ships with a [REST messaging interface](rest.md) (not to be confused with the REST management API
provided via our integration with Jolokia).

View File

@ -1,4 +1,4 @@
# Using JMS
# Using JMS or Jakarta Messaging
Although Apache ActiveMQ Artemis provides a JMS agnostic messaging API, many
users will be more comfortable using JMS.
@ -178,7 +178,8 @@ The `refreshTimeout` and `discoveryInitialWaitTimeout` properties are supported
just like with `udp`.
The default type for the default connection factory is of type
`javax.jms.ConnectionFactory`. This can be changed by setting the type like so
`javax.jms.ConnectionFactory`or `jakarta.jms.ConnectionFactory` depending on the
client you're using. This can be changed by setting the type like so
```properties
@ -191,14 +192,17 @@ that can be set.
#### Configuration for Connection Factory Types
The interface provided will depend on whether you're using the JMS or Jakarta
Messaging client implementation.
type | interface
--- |---
CF (default) | javax.jms.ConnectionFactory
XA_CF | javax.jms.XAConnectionFactory
QUEUE_CF | javax.jms.QueueConnectionFactory
QUEUE_XA_CF | javax.jms.XAQueueConnectionFactory
TOPIC_CF | javax.jms.TopicConnectionFactory
TOPIC_XA_CF | javax.jms.XATopicConnectionFactory
CF (default) | `javax.jms.ConnectionFactory` or `jakarta.jms.ConnectionFactory`
XA_CF | `javax.jms.XAConnectionFactory`or `jakarta.jms.XAConnectionFactory`
QUEUE_CF | `javax.jms.QueueConnectionFactory`or `jakarta.jms.QueueConnectionFactory`
QUEUE_XA_CF | `javax.jms.XAQueueConnectionFactory`or `jakarta.jms.XAQueueConnectionFactory`
TOPIC_CF | `javax.jms.TopicConnectionFactory`or `jakarta.jms.TopicConnectionFactory`
TOPIC_XA_CF | `javax.jms.XATopicConnectionFactory`or `jakarta.jms.XATopicConnectionFactory`
### Destination JNDI

View File

@ -86,6 +86,7 @@ Highlights:
- JDBC datasource property values can now be masked.
- Lots of usability improvements to the Hawtio 2 based web console introduced in 2.16.0
- New management method to create a core bridge using JSON-based configuration input.
- [Jakarta Messaging 2.0 & 3.0 artifacts for Jakarta EE 8 & 9 respectively](https://blogs.apache.org/activemq/entry/activemq-artemis-embraces-jakarta-ee).
## 2.16.0

View File

@ -84,6 +84,7 @@ under the License.
<module>pre-acknowledge</module>
<module>producer-rate-limit</module>
<module>queue</module>
<module>queue-jakarta</module>
<module>queue-requestor</module>
<module>queue-selector</module>
<module>reattach-node</module>

View File

@ -0,0 +1,111 @@
<?xml version='1.0'?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.activemq.examples.broker</groupId>
<artifactId>jms-examples</artifactId>
<version>2.19.0-SNAPSHOT</version>
</parent>
<artifactId>queue-jakarta</artifactId>
<packaging>jar</packaging>
<name>ActiveMQ Artemis Jakarta Messaging 3.0 Queue Example</name>
<properties>
<activemq.basedir>${project.basedir}/../../../..</activemq.basedir>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jakarta-client-all</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-maven-plugin</artifactId>
<executions>
<execution>
<id>create</id>
<goals>
<goal>create</goal>
</goals>
<configuration>
<ignore>${noServer}</ignore>
</configuration>
</execution>
<execution>
<id>start</id>
<goals>
<goal>cli</goal>
</goals>
<configuration>
<spawn>true</spawn>
<ignore>${noServer}</ignore>
<testURI>tcp://localhost:61616</testURI>
<args>
<param>run</param>
</args>
</configuration>
</execution>
<execution>
<id>runClient</id>
<goals>
<goal>runClient</goal>
</goals>
<configuration>
<clientClass>org.apache.activemq.artemis.jms.example.QueueExample</clientClass>
</configuration>
</execution>
<execution>
<id>stop</id>
<goals>
<goal>cli</goal>
</goals>
<configuration>
<ignore>${noServer}</ignore>
<args>
<param>stop</param>
</args>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.apache.activemq.examples.broker</groupId>
<artifactId>queue-jakarta</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,11 @@
# Jakarta Messaging 3.0 Queue Example
To run the example, simply type **mvn verify** from this directory, or **mvn -PnoServer verify** if you want to start and create the broker manually.
This example shows you how to send and receive a message to a JMS Queue using ActiveMQ Artemis.
Queues are a standard part of JMS, please consult the Jakarta Messaging 3.0 specification for full details.
A Queue is used to send messages point to point, from a producer to a consumer. The queue guarantees message ordering between these 2 points.
Notice this example is using pretty much a default stock configuration

View File

@ -0,0 +1,83 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.jms.example;
import jakarta.jms.Connection;
import jakarta.jms.ConnectionFactory;
import jakarta.jms.MessageConsumer;
import jakarta.jms.MessageProducer;
import jakarta.jms.Queue;
import jakarta.jms.Session;
import jakarta.jms.TextMessage;
import javax.naming.InitialContext;
/**
* A simple JMS Queue example that creates a producer and consumer on a queue and sends then receives a message.
*/
public class QueueExample {
public static void main(final String[] args) throws Exception {
Connection connection = null;
InitialContext initialContext = null;
try {
// Step 1. Create an initial context to perform the JNDI lookup.
initialContext = new InitialContext();
// Step 2. Perform a lookup on the queue
Queue queue = (Queue) initialContext.lookup("queue/exampleQueue");
// Step 3. Perform a lookup on the Connection Factory
ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("ConnectionFactory");
// Step 4.Create a JMS Connection
connection = cf.createConnection();
// Step 5. Create a JMS Session
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Step 6. Create a JMS Message Producer
MessageProducer producer = session.createProducer(queue);
// Step 7. Create a Text Message
TextMessage message = session.createTextMessage("This is a text message");
System.out.println("Sent message: " + message.getText());
// Step 8. Send the Message
producer.send(message);
// Step 9. Create a JMS Message Consumer
MessageConsumer messageConsumer = session.createConsumer(queue);
// Step 10. Start the Connection
connection.start();
// Step 11. Receive the message
TextMessage messageReceived = (TextMessage) messageConsumer.receive(5000);
System.out.println("Received message: " + messageReceived.getText());
} finally {
// Step 12. Be sure to close our JMS resources!
if (initialContext != null) {
initialContext.close();
}
if (connection != null) {
connection.close();
}
}
}
}

View File

@ -0,0 +1,20 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
connectionFactory.ConnectionFactory=tcp://localhost:61616
queue.queue/exampleQueue=exampleQueue

View File

@ -0,0 +1,136 @@
<?xml version='1.0'?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.activemq.examples.modules</groupId>
<artifactId>broker-modules</artifactId>
<version>2.19.0-SNAPSHOT</version>
</parent>
<artifactId>artemis-jakarta-rar</artifactId>
<packaging>rar</packaging>
<name>ActiveMQ Artemis Jakarta Messaging 3.0 RA</name>
<properties>
<activemq.basedir>${project.basedir}/../../../..</activemq.basedir>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jakarta-client</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-core-client</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jakarta-client</artifactId>
</exclusion>
<exclusion>
<groupId>jakarta.jms</groupId>
<artifactId>jakarta.jms-api</artifactId>
</exclusion>
<exclusion>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-ejb_3.0_spec</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jakarta-ra</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>jakarta.transaction</groupId>
<artifactId>jakarta.transaction-api</artifactId>
</exclusion>
<exclusion>
<groupId>jakarta.jms</groupId>
<artifactId>jakarta.jms-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jakarta-server</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>jakarta.transaction</groupId>
<artifactId>jakarta.transaction-api</artifactId>
</exclusion>
<exclusion>
<groupId>jakarta.jms</groupId>
<artifactId>jakarta.jms-api</artifactId>
</exclusion>
<exclusion>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-core-client</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-core-client</artifactId>
</exclusion>
<exclusion>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-rar-plugin</artifactId>
<configuration>
<raXmlFile>src/main/resources/ra.xml</raXmlFile>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,315 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id: ra.xml 76819 2008-08-08 11:04:20Z jesper.pedersen $ -->
<connector xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/connector_1_5.xsd"
version="1.5">
<display-name>ArtemisRA</display-name>
<description>ActiveMQ Artemis Resource Adapter</description>
<vendor-name>Apache Software Foundation</vendor-name>
<eis-type>Jakarta Messaging 3.0 Server</eis-type>
<resourceadapter-version>1.0</resourceadapter-version>
<license>
<description>
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
</description>
<license-required>true</license-required>
</license>
<resourceadapter>
<resourceadapter-class>org.apache.activemq.artemis.ra.ActiveMQResourceAdapter</resourceadapter-class>
<config-property>
<description>
The transport type. Multiple connectors can be configured by using a comma separated list,
i.e. org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnectorFactory,org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnectorFactory.
</description>
<config-property-name>ConnectorClassName</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory</config-property-value>
</config-property>
<config-property>
<description>The transport configuration. These values must be in the form of key=val;key=val;,
if multiple connectors are used then each set must be separated by a comma i.e. host=host1;port=61616,host=host2;port=61617.
Each set of params maps to the connector classname specified.
</description>
<config-property-name>ConnectionParameters</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>host=localhost,port=61616</config-property-value>
</config-property>
<!-- <config-property>
<description>Does we support HA</description>
<config-property-name>HA</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
</config-property>
<config-property>
<description>The method to use for locating the transactionmanager</description>
<config-property-name>TransactionManagerLocatorMethod</config-property-name>
<config-property-type>java.lang.String</config-property-type>
</config-property>
<config-property>
<description>Use A local Transaction instead of XA?</description>
<config-property-name>UseLocalTx</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
</config-property>
<config-property>
<description>The user name used to login to the JMS server</description>
<config-property-name>UserName</config-property-name>
<config-property-type>java.lang.String</config-property-type>
</config-property>
<config-property>
<description>The password used to login to the JMS server</description>
<config-property-name>Password</config-property-name>
<config-property-type>java.lang.String</config-property-type>
</config-property>
<config-property>
<description>The jndi params to use to look up the jms resources if local jndi is not to be used</description>
<config-property-name>JndiParams</config-property-name>
<config-property-type>java.lang.String</config-property-type>
</config-property>
<config-property>
<description>The jGroups File name</description>
<config-property-name>JgroupsFile</config-property-name>
<config-property-type>java.lang.String</config-property-type>
</config-property>
<config-property>
<description>The name of the channel used on this configuration</description>
<config-property-name>JgroupsChannelName</config-property-name>
<config-property-type>java.lang.Integer</config-property-type>
</config-property>
<config-property>
<description>The discovery group address</description>
<config-property-name>DiscoveryAddress</config-property-name>
<config-property-type>java.lang.String</config-property-type>
</config-property>
<config-property>
<description>The discovery group port</description>
<config-property-name>DiscoveryPort</config-property-name>
<config-property-type>java.lang.Integer</config-property-type>
</config-property>
<config-property>
<description>The discovery refresh timeout</description>
<config-property-name>DiscoveryRefreshTimeout</config-property-name>
<config-property-type>java.lang.Long</config-property-type>
</config-property>
<config-property>
<description>The discovery initial wait timeout</description>
<config-property-name>DiscoveryInitialWaitTimeout</config-property-name>
<config-property-type>java.lang.Long</config-property-type>
</config-property>
<config-property>
<description>The load balancing policy class name</description>
<config-property-name>LoadBalancingPolicyClassName</config-property-name>
<config-property-type>java.lang.String</config-property-type>
</config-property>
<config-property>
<description>The client failure check period</description>
<config-property-name>ClientFailureCheckPeriod</config-property-name>
<config-property-type>java.lang.Long</config-property-type>
</config-property>
<config-property>
<description>The connection TTL</description>
<config-property-name>ConnectionTTL</config-property-name>
<config-property-type>java.lang.Long</config-property-type>
</config-property>
<config-property>
<description>The call timeout</description>
<config-property-name>CallTimeout</config-property-name>
<config-property-type>java.lang.Long</config-property-type>
</config-property>
<config-property>
<description>The dups ok batch size</description>
<config-property-name>DupsOKBatchSize</config-property-name>
<config-property-type>java.lang.Integer</config-property-type>
</config-property>
<config-property>
<description>The transaction batch size</description>
<config-property-name>TransactionBatchSize</config-property-name>
<config-property-type>java.lang.Integer</config-property-type>
</config-property>
<config-property>
<description>The consumer window size</description>
<config-property-name>ConsumerWindowSize</config-property-name>
<config-property-type>java.lang.Integer</config-property-type>
</config-property>
<config-property>
<description>The consumer max rate</description>
<config-property-name>ConsumerMaxRate</config-property-name>
<config-property-type>java.lang.Integer</config-property-type>
</config-property>
<config-property>
<description>The confirmation window size</description>
<config-property-name>ConfirmationWindowSize</config-property-name>
<config-property-type>java.lang.Integer</config-property-type>
</config-property>
<config-property>
<description>The producer max rate</description>
<config-property-name>ProducerMaxRate</config-property-name>
<config-property-type>java.lang.Integer</config-property-type>
</config-property>
<config-property>
<description>The min large message size</description>
<config-property-name>MinLargeMessageSize</config-property-name>
<config-property-type>java.lang.Integer</config-property-type>
</config-property>
<config-property>
<description>The block on acknowledge</description>
<config-property-name>BlockOnAcknowledge</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
</config-property>
<config-property>
<description>The block on non durable send</description>
<config-property-name>BlockOnNonDurableSend</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
</config-property>
<config-property>
<description>The block on durable send</description>
<config-property-name>BlockOnDurableSend</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
</config-property>
<config-property>
<description>The auto group</description>
<config-property-name>AutoGroup</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
</config-property>
<config-property>
<description>The max connections</description>
<config-property-type>java.lang.Integer</config-property-type>
</config-property>
<config-property>
<description>The pre acknowledge</description>
<config-property-name>PreAcknowledge</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
</config-property>
<config-property>
<description>The retry interval</description>
<config-property-name>RetryInterval</config-property-name>
<config-property-type>java.lang.Long</config-property-type>
</config-property>
<config-property>
<description>The retry interval multiplier</description>
<config-property-name>RetryIntervalMultiplier</config-property-name>
<config-property-type>java.lang.Double</config-property-type>
</config-property>
<config-property>
<description>The client id</description>
<config-property-name>ClientID</config-property-name>
<config-property-type>java.lang.String</config-property-type>
</config-property>
<config-property>
<description>Whether the password is cleartext or encrypted, default false</description>
<config-property-name>UseMaskedPassword</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
</config-property>
<config-property>
<description>The class definition (full qualified name and its properties) used to encrypt the password</description>
<config-property-name>PasswordCodec</config-property-name>
<config-property-type>java.lang.String</config-property-type>
</config-property>
<config-property>
<description>Cache destinations per session</description>
<config-property-name>CacheDestinations</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
</config-property>-->
<outbound-resourceadapter>
<connection-definition>
<managedconnectionfactory-class>org.apache.activemq.artemis.ra.ActiveMQRAManagedConnectionFactory</managedconnectionfactory-class>
<config-property>
<description>The default session type</description>
<config-property-name>SessionDefaultType</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>javax.jms.Queue</config-property-value>
</config-property>
<config-property>
<description>Whether or not to participate in a JTA transaction, this is used if the RA does not have access to the Transaction Manager</description>
<config-property-name>InJtaTransaction</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
<config-property-value>true</config-property-value>
</config-property>
<config-property>
<description>Try to obtain a lock within specified number of seconds; less than or equal to 0 disable this functionality</description>
<config-property-name>UseTryLock</config-property-name>
<config-property-type>java.lang.Integer</config-property-type>
<config-property-value>0</config-property-value>
</config-property>
<connectionfactory-interface>org.apache.activemq.artemis.ra.ActiveMQRAConnectionFactory</connectionfactory-interface>
<connectionfactory-impl-class>org.apache.activemq.artemis.ra.ActiveMQRAConnectionFactoryImpl</connectionfactory-impl-class>
<connection-interface>javax.jms.Session</connection-interface>
<connection-impl-class>org.apache.activemq.artemis.ra.ActiveMQRASession</connection-impl-class>
</connection-definition>
<transaction-support>XATransaction</transaction-support>
<authentication-mechanism>
<authentication-mechanism-type>BasicPassword</authentication-mechanism-type>
<credential-interface>javax.resource.spi.security.PasswordCredential</credential-interface>
</authentication-mechanism>
<reauthentication-support>false</reauthentication-support>
</outbound-resourceadapter>
<inbound-resourceadapter>
<messageadapter>
<messagelistener>
<messagelistener-type>javax.jms.MessageListener</messagelistener-type>
<activationspec>
<activationspec-class>org.apache.activemq.artemis.ra.inflow.ActiveMQActivationSpec</activationspec-class>
<required-config-property>
<config-property-name>destination</config-property-name>
</required-config-property>
</activationspec>
</messagelistener>
</messageadapter>
</inbound-resourceadapter>
<adminobject>
<adminobject-interface>javax.jms.Queue</adminobject-interface>
<adminobject-class>org.apache.activemq.artemis.jms.client.ActiveMQQueue</adminobject-class>
<config-property>
<config-property-name>Address</config-property-name>
<config-property-type>java.lang.String</config-property-type>
</config-property>
</adminobject>
<adminobject>
<adminobject-interface>javax.jms.Topic</adminobject-interface>
<adminobject-class>org.apache.activemq.artemis.jms.client.ActiveMQTopic</adminobject-class>
<config-property>
<config-property-name>Address</config-property-name>
<config-property-type>java.lang.String</config-property-type>
</config-property>
</adminobject>
<adminobject>
<adminobject-interface>javax.jms.ConnectionFactory</adminobject-interface>
<adminobject-class>org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory</adminobject-class>
<config-property>
<config-property-name>BrokerURL</config-property-name>
<config-property-type>java.lang.String</config-property-type>
</config-property>
</adminobject>
<adminobject>
<adminobject-interface>javax.jms.XAConnectionFactory</adminobject-interface>
<adminobject-class>org.apache.activemq.artemis.jms.client.ActiveMQXAConnectionFactory</adminobject-class>
<config-property>
<config-property-name>BrokerURL</config-property-name>
<config-property-type>java.lang.String</config-property-type>
</config-property>
</adminobject>
</resourceadapter>
</connector>

View File

@ -49,6 +49,7 @@ under the License.
<profile>
<id>release</id>
<modules>
<module>artemis-jakarta-ra-rar</module>
<module>artemis-ra-rar</module>
<module>inter-broker-bridge</module>
<module>tomcat</module>

View File

@ -48,6 +48,7 @@
<module>artemis-jms-client-all</module>
<module>artemis-jms-client-osgi</module>
<module>artemis-jakarta-client</module>
<module>artemis-jakarta-client-all</module>
<module>artemis-jms-server</module>
<module>artemis-jakarta-server</module>
<module>artemis-journal</module>

View File

@ -53,6 +53,10 @@
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jms-client-all</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jakarta-client-all</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>