20:00:58,381 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-3) MSC000001: Failed to start service jboss.deployment.subunit."Message.ear"."MessageEJB.jar".PARSE: org.jboss.msc.service.StartException in service jboss.deployment.subunit."Message.ear"."MessageEJB.jar".PARSE: WFLYSRV0153: Failed to process phase PARSE of subdeployment "MessageEJB.jar" of deployment "Message.ear"
at org.jboss.as.server@23.0.1.Final//org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:179)
at org.jboss.msc@1.5.2.Final//org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1617)
at org.jboss.msc@1.5.2.Final//org.jboss.msc.service.ServiceControllerImpl$StartTask.execute(ServiceControllerImpl.java:1580)
at org.jboss.msc@1.5.2.Final//org.jboss.msc.service.ServiceControllerImpl$ControllerTask.run(ServiceControllerImpl.java:1438)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.jboss.msc.service.ServiceNotFoundException: service jboss.ejb.default-resource-adapter-name-service not found
at org.jboss.msc@1.5.2.Final//org.jboss.msc.service.ServiceContainerImpl.getRequiredService(ServiceContainerImpl.java:673)
at org.jboss.as.ejb3@31.0.0.Final//org.jboss.as.ejb3.deployment.processors.MessageDrivenComponentDescriptionFactory.getDefaultResourceAdapterName(MessageDrivenComponentDescriptionFactory.java:230)
at org.jboss.as.ejb3@31.0.0.Final//org.jboss.as.ejb3.deployment.processors.MessageDrivenComponentDescriptionFactory.processMessageBeans(MessageDrivenComponentDescriptionFactory.java:111)
at org.jboss.as.ejb3@31.0.0.Final//org.jboss.as.ejb3.deployment.processors.MessageDrivenComponentDescriptionFactory.processAnnotations(MessageDrivenComponentDescriptionFactory.java:65)
at org.jboss.as.ejb3@31.0.0.Final//org.jboss.as.ejb3.deployment.processors.AnnotatedEJBComponentDescriptionDeploymentUnitProcessor.processAnnotations(AnnotatedEJBComponentDescriptionDeploymentUnitProcessor.java:128)
at org.jboss.as.ejb3@31.0.0.Final//org.jboss.as.ejb3.deployment.processors.AnnotatedEJBComponentDescriptionDeploymentUnitProcessor.deploy(AnnotatedEJBComponentDescriptionDeploymentUnitProcessor.java:65)
at org.jboss.as.server@23.0.1.Final//org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:172)
... 8 more
Man könnte "standalone.xml" um die Konfiguration für JMS erweitern. Einfacher ist es, das "Full Profile" aus "standalone-full.xml" zu verwenden.standalone.bat -c standalone-full.xml
<extensions>
...
<extension module="org.wildfly.extension.messaging-activemq"/>
...
</extensions>
Weiter unten wird diese Konfiguration als Subsystem verwendet. Dort wird ein "server" namens "default" definiert: <subsystem xmlns="urn:jboss:domain:messaging-activemq:16.0">
<server name="default">
...
<server>
</subsystem>
Die Schema-Definition für diesen Bereich findet man in der Datei "wildfly-messaging-activemq_16_0.xsd" (in "%WILDFLY_HOME%\docs\schema"). <http-connector name="http-connector" endpoint="http-acceptor" socket-binding="http"/>
<http-connector name="http-connector-throughput" endpoint="http-acceptor-throughput" socket-binding="http">
<param name="batch-delay" value="50"/>
</http-connector>
<in-vm-connector name="in-vm" server-id="0"/>
<http-acceptor name="http-acceptor" http-listener="default"/>
<http-acceptor name="http-acceptor-throughput" http-listener="default">
<param name="batch-delay" value="50"/>
<param name="direct-deliver" value="false"/>
<in-vm-acceptor name="in-vm" server-id="0"/>
</http-acceptor>
Hier geht es um den Empfang von Nachrichten: der "in-vm-acceptor" akzeptiert Nachrichten aus der gleichen virtuellen Maschine,
die "http-acceptor" und "http-acceptor-throughput" empfangen Nachrichten über das Netzwerk, und zwar horchen sie an den
im "http-listener" angegebenen HTTP-Listener. <subsystem xmlns="urn:jboss:domain:undertow:14.0">
<server name="default-server">
<http-listener name="default" redirect-socket="https" socket-binding="http"/>
<host name="default-host" alias="localhost">
...
</host>
</server>
Dieser Listener verweist auf ein "socket-binding" namens "http", das schon oben beim HTTP-Connector gezeigt wurde. <security-setting name="#">
<role name="guest"
delete-non-durable-queue="true"
create-non-durable-queue="true"
consume="true"
send="true"/>
</security-setting>
Hier sind die Permissions für "send" und "consume" relevant: nur ein Benutzer, der sich in der deklarierten Rolle "guest" befindet,
darf Nachrichten abschicken/empfangen. Über das "name"-Attribut wird definiert, für welche Queue oder welches Topic diese Deklaration gilt.
Im obigen Ausschnitt ist "#" die Wildcard für "alle". <connection-factory
name="InVmConnectionFactory"
entries="java:/ConnectionFactory"
connectors="in-vm"/>
<connection-factory
name="RemoteConnectionFactory"
entries="java:jboss/exported/jms/RemoteConnectionFactory"
connectors="http-connector"/>
<pooled-connection-factory
name="activemq-ra"
transaction="xa"
entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory"
connectors="in-vm"/
<socket-binding-group name="standard-sockets" ...>
...
<socket-binding name="http" port="${jboss.http.port:8080}"/>
...
</socket-binding-group>
<outbound-socket-binding name="myremotemessaging">
<remote-destination host="otherhost" port="5445"/>
</outbound-socket-binding>
Dieser Connector müsste im "socket-binding"-Attribut den Namen dieses Socket Binding, also "myremotemessaging", stehen haben.
Ein Beispiel hierfür gibt es in der Konfiguration des JavaEE-ApplicationClient.Queue
(Punkt-zu-Punkt-Verbindung, der Client schickt
die Nachricht an einen bestimmten Empfänger, wie eine Telefonverbindung) oder ein Topic
(es gibt eine unbekannte Anzahl
von Empfängern, vergleichbar mit dem Radio-Senden) handelt.package de.hsrm.jakartaee.knauf.mdb;
import jakarta.ejb.ActivationConfigProperty;
import jakarta.ejb.MessageDriven;
import jakarta.jms.Message;
import jakarta.jms.MessageListener;
@MessageDriven(
activationConfig = { @ActivationConfigProperty(
propertyName = "destinationType", propertyValue = "jakarta.jms.Queue"), @ActivationConfigProperty(
propertyName = "destination", propertyValue = "jms/queue/MessageBeanQueue")
},
mappedName = "jms/queue/MessageBeanQueue")
public class MessageBean implements MessageListener
{
public MessageBean()
{
}
public void onMessage(Message message)
{
}
}
Anmerkung: das Attribut "mappedName" ist in meinem Beispielcode nicht enthalten, es geht also auch ohne.onMessage
steckt die Implementierung der Bean: private static final Logger logger = Logger.getLogger ( MessageBean.class.getName() );
public void onMessage(Message message)
{
try
{
MessageBean.logger.info("onMessage: Message vom Typ " + message.getClass().toString() + " erhalten");
if (message instanceof TextMessage)
{
TextMessage textMessage = (TextMessage) message;
MessageBean.logger.info("TextMessage enthält diesen Text: " + textMessage.getText() );
}
else
MessageBean.logger.info("Sonstige Message. toString() = " + message.toString() );
}
catch (JMSException jex)
{
MessageBean.logger.log( Level.SEVERE, "Fehler beim Verarbeiten der Message: " + jex.getMessage(), jex );
throw new EJBException ("Fehler beim Verarbeiten der Message: " + jex.getMessage(), jex );
}
}
<jms-queue name="MessageBeanQueue" entries="java:/jms/queue/MessageBeanQueue"/>
Jetzt können wir den Server starten und unsere Bean publizieren.
[standalone@localhost:9990 /] jms-queue add --queue-address=MessageBeanQueue --entries=queue/MessageBeanQueue
Der JNDI-Name wird hier unter "--entries" angegeben, der Queue-Name bei "--queue-address".[standalone@localhost:9990 /] jms-queue remove --queue-address=MessageBeanQueue
<?xml version="1.0" encoding="UTF-8"?>
<messaging-deployment xmlns="urn:jboss:messaging-activemq-deployment:1.0">
<server>
<jms-destinations>
<jms-queue name="MessageBeanQueue">
<entry name="jms/queue/MessageBeanQueue"/>
</jms-queue>
</jms-destinations>
</server>
</messaging-deployment>
Eine "schemaLocation" können wir hier nicht angeben, da die Datei wohl nicht im Web verfügbar ist. Sie steckt im WildFly-Verzeichnis unter
"%WILDFLY_HOME%\docs\schema" und heißt "wildfly-messaging-activemq-deployment_1_0.xsd". Der JBossTools-Plugin stellt automatisch einen
Eintrag unter "urn:jboss:messaging-activemq-deployment:1.0" im XML Catalog zur Verfügung, d.h. die XSD wird von Eclipse aufgelöst.@javax.jms.JMSDestinationDefinition
<subsystem xmlns="urn:jboss:domain:messaging-activemq:16.0">
<server name="default">
<security elytron-domain="ApplicationDomain"/>
<statistics enabled="${wildfly.messaging-activemq.statistics-enabled:${wildfly.statistics-enabled:false}}"/>
Für "enabled" wird "true" eingetragen. /subsystem=messaging-activemq/server=default/jms-queue=MessageBeanQueue:read-attribute(name=messages-added)
{
"outcome" => "success",
"result" => 2L
}
Thread.sleep
eingebaut wird):[standalone@localhost:9990 /] jms-queue --queue-address=MessageBeanQueue count-messages
Eine Langform des gleichen Befehls (diese hat den Vorteil, dass man die Operationen wie "count-messages" per Code completion angezeigt bekommt):[standalone@localhost:9990 /] /subsystem=messaging-activemq/server=default/jms-queue=MessageBeanQueue:count-messages
[standalone@localhost:9990 /] jms-queue --queue-address=MessageBeanQueue list-messages
[standalone@localhost:9990 /] /subsystem=messaging-activemq/server=default/jms-queue=MessageBeanQueue:read-resource
19:37:33,522 INFO [org.jboss.as.server.deployment] (MSC service thread 1-1) WFLYSRV0027: Starting deployment of "Message.ear" (runtime-name: "Message.ear")
19:37:33,687 INFO [org.jboss.as.server.deployment] (MSC service thread 1-1) WFLYSRV0207: Starting subdeployment (runtime-name: "MessageClient.jar")
19:37:33,687 INFO [org.jboss.as.server.deployment] (MSC service thread 1-4) WFLYSRV0207: Starting subdeployment (runtime-name: "MessageEJB.jar")
19:37:33,931 INFO [org.jboss.as.ejb3.deployment] (MSC service thread 1-5) WFLYEJB0473: JNDI bindings for session bean named 'MessageBean' in deployment unit 'subdeployment "MessageEJB.jar" of deployment "Message.ear"' are as follows:
19:37:34,048 ERROR [org.jboss.as.controller.management-operation] (Thread-45) WFLYCTL0013: Operation ("deploy") failed - address: ([("deployment" => "Message.ear")]) - failure description: {
"WFLYCTL0412: Required services that are not installed:" => ["jboss.naming.context.java.ConnectionFactory"],
"WFLYCTL0180: Services with missing/unavailable dependencies" => ["service jboss.naming.context.java.module.Message.MessageClient.env.jms.MBConnectionFactory is missing [jboss.naming.context.java.ConnectionFactory]"]
}
19:37:34,048 ERROR [org.jboss.as.controller.management-operation] (Thread-45) WFLYCTL0013: Operation ("deploy") failed - address: ([("deployment" => "Message.ear")]) - failure description: {
"WFLYCTL0412: Required services that are not installed:" => ["jboss.naming.context.java.ConnectionFactory"],
"WFLYCTL0180: Services with missing/unavailable dependencies" => ["service jboss.naming.context.java.module.Message.MessageClient.env.jms.MBConnectionFactory is missing [jboss.naming.context.java.ConnectionFactory]"]
}
19:37:34,049 ERROR [org.jboss.as.server] (Thread-45) WFLYSRV0021: Deploy of deployment "Message.ear" was rolled back with the following failure message:
{
"WFLYCTL0412: Required services that are not installed:" => ["jboss.naming.context.java.ConnectionFactory"],
"WFLYCTL0180: Services with missing/unavailable dependencies" => ["service jboss.naming.context.java.module.Message.MessageClient.env.jms.MBConnectionFactory is missing [jboss.naming.context.java.ConnectionFactory]"]
}
Also öffnen wir "%WILDFLY_HOME%\appclient\configuration\appclient.xml" und fügen folgendes hinzu:
Im Element "extensions" steht bereits die Aktivierung der Module "org.wildfly.extension.messaging-activemq" und "org.wildfly.extension.elytron", die wir hier benötigen.
In früheren Versionen musste dies noch händisch eingetragen werden.
<extensions>
...
<extension module="org.wildfly.extension.elytron"/>
<extension module="org.wildfly.extension.messaging-activemq"/>
...
</extensions>
Im Element "profile" suchen wir das Subsystem "urn:jboss:domain:messaging-activemq:15.0", das leer ist, und befüllen es so: <subsystem xmlns="urn:jboss:domain:messaging-activemq:15.0">
<server name="default">
<security elytron-domain="ApplicationDomain"/>
<address-setting name="#" message-counter-history-day-limit="10" page-size-bytes="2097152" max-size-bytes="10485760" expiry-address="jms.queue.ExpiryQueue" dead-letter-address="jms.queue.DLQ"/>
<http-connector name="http-connector" endpoint="http-acceptor" socket-binding="http"/>
<!--
<jms-queue name="MessageBeanQueue" entries="java:/jms/queue/MessageBeanQueue"/>
-->
<connection-factory name="RemoteConnectionFactory" entries="java:/ConnectionFactory" connectors="http-connector"/>
</server>
</subsystem>
Hier wird ein einziger Connector deklariert, da wir in der Anwendung nur eine Verbindung zu einem fernen Server aufbauen wollen.
Deshalb nehmen wir als Typ des Connectors einen "http-connector", der das Socket Binding "http" verwendet (siehe nächster Schritt).elytron-domain
ist nötig, da wir kein anonymes Senden an die Queue durchführen können und stattdessen eine Anmeldung mit Username und Passwort durchführen.urn:wildfly:elytron:17.0
, das wir ebenfalls vorfinden.
Hier wird der fett markierte Teil zugefügt: <subsystem xmlns="urn:wildfly:elytron:17.0" final-providers="elytron" disallowed-providers="OracleUcrypto">
<providers>
<provider-loader name="elytron" module="org.wildfly.security.elytron"/>
</providers>
<security-domains>
<security-domain name="ApplicationDomain"/>
</security-domains>
</subsystem>
<socket-binding-group name="standard-sockets" default-interface="public">
...
<outbound-socket-binding name="http">
<remote-destination host="localhost" port="8080"/>
</outbound-socket-binding>
</socket-binding-group>
queueConnectionFactory.createQueueConnection();
), kommt eine solche Exception
im Client:2024-02-15 19:54:40,595 ERROR [stderr] (AWT-EventQueue-0) jakarta.jms.JMSSecurityException: AMQ229031: Unable to validate user from /127.0.0.1:51650. Username: tester; SSL certificate subject DN: unavailable
2024-02-15 19:54:40,595 ERROR [stderr] (AWT-EventQueue-0) at org.apache.activemq.artemis.client@2.31.2//org.apache.activemq.artemis.core.protocol.core.impl.ChannelImpl.sendBlocking(ChannelImpl.java:560)
2024-02-15 19:54:40,595 ERROR [stderr] (AWT-EventQueue-0) at org.apache.activemq.artemis.client@2.31.2//org.apache.activemq.artemis.core.protocol.core.impl.ChannelImpl.sendBlocking(ChannelImpl.java:452)
Also verwenden wir das Script "%JBOSS_HOME%\bin\add-user.bat", um einen neuen User anzulegen:User: tester does not have permission='SEND' on address jms.queue.MessageBeanQueue
)javax.swing.JFrame
zugefügt.Main-Class
eingetragen werden. private void sendMessage()
{
try
{
InitialContext initialContext = new InitialContext();
QueueConnectionFactory queueConnectionFactory = (QueueConnectionFactory) initialContext.lookup("java:comp/env/jms/MBConnectionFactory");
//Die konfigurierte Queue holen:
Queue queue = (Queue) initialContext.lookup("java:comp/env/jms/MBQueueRef");
//Verbindung erzeugen:
//Hier muss der User angegeben werden!
QueueConnection queueConnection = queueConnectionFactory.createQueueConnection("tester", "test123!");
QueueSession queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
QueueSender queueSender = queueSession.createSender(queue);
//Senden der Nachricht:
TextMessage textMessage = queueSession.createTextMessage();
textMessage.setText(this.jTextFieldMessage.getText());
queueSender.send(textMessage);
//Alles sauber aufräumen:
queueSender.close();
queueSession.close();
queueConnection.close();
//Fertig.
JOptionPane.showMessageDialog(this, "Nachricht wurde gesendet und sollte im Serverlog stehen !");
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
An den InitialContext müssen keine Parameter übergeben werden. <resource-ref>
<res-ref-name>jms/MBConnectionFactory</res-ref-name>
<res-type>jakarta.jms.QueueConnectionFactory</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<resource-ref>
<res-ref-name>jms/MBQueueRef</res-ref-name>
<res-type>jakarta.jms.Queue</res-type>
<res-auth>Container</res-auth>
</resource-ref>
version="9.0"
zu (optional)res-ref-name
in "jboss-client.xml" den gleichen Wert haben wie die zugehörigen Elemente in
"application-client.xml"!<?xml version="1.0" encoding="UTF-8"?>
<jboss-client xmlns="urn:jboss:jakartaee:1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:jboss:jakartaee:1.0 https://www.jboss.org/schema/jbossas/jboss-client_9_0.xsd"
version="9.0">
<jndi-name>MessageClient</jndi-name>
<resource-ref>
<res-ref-name>jms/MBConnectionFactory</res-ref-name>
<jndi-name>java:/ConnectionFactory</jndi-name>
</resource-ref>
<resource-ref>
<res-ref-name>jms/MBQueueRef</res-ref-name>
<jndi-name>java:/jms/queue/MessageBeanQueue</jndi-name>
</resource-ref>
</jboss-client>
Die ConnectionFactory wird an den Namen "java:/ConnectionFactory" gebunden. Wie dieser konfiguriert wird, sehen wir im nächsten Abschnitt.%WILDFLY_HOME%\bin\appclient.bat Message.ear#MessageClient.jar
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private static final java.lang.Object javax.swing.JFrame.defaultLookAndFeelDecoratedKey accessible:
module java.desktop does not \"opens javax.swing\" to unnamed module @f7cd57e"}
set JAVA_OPTS=--add-opens=java.desktop/javax.swing=ALL-UNNAMED --add-opens=java.desktop/java.awt=ALL-UNNAMED
%WILDFLY_HOME%\bin\appclient.bat Message.ear#MessageClient.jar
--illegal-access=permit
setzen, aber dies wurde in Java 17 entfernt. @Resource(name="jms/MBConnectionFactory")
private static QueueConnectionFactory queueConnectionFactory;
@Resource(name="jms/MBQueueRef")
private static Queue queue;
Für Queue
und QueueConnectionFactory
greife ich auf einen Eintrag aus dem ENC zu (siehe letzter Abschnitt). @Resource(mappedName="ConnectionFactory")
private static QueueConnectionFactory queueConnectionFactory;
@Resource(mappedName="queue/MessageBeanQueue")
private static Queue queue;
<?xml version="1.0" encoding="UTF-8"?>
<application-client version="10"
xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/application-client_10.xsd">
<display-name>MessageClient</display-name>
<resource-ref>
<res-ref-name>jms/MBConnectionFactory</res-ref-name>
<res-type>jakarta.jms.QueueConnectionFactory</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<message-destination-ref>
<message-destination-ref-name>jms/MBQueueRef</message-destination-ref-name>
<message-destination-type>jakarta.jms.Queue</message-destination-type>
</message-destination-ref>
</application-client>
jboss-client.xml:<?xml version="1.0" encoding="UTF-8"?>
<jboss-client xmlns="urn:jboss:jakartaee:1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:jboss:jakartaee:1.0 https://www.jboss.org/schema/jbossas/jboss-client_9_0.xsd"
version="9.0">
<jndi-name>MessageClient</jndi-name>
<resource-ref>
<res-ref-name>jms/MBConnectionFactory</res-ref-name>
<jndi-name>java:/ConnectionFactory</jndi-name>
</resource-ref>
<message-destination-ref>
<message-destination-ref-name>jms/MBQueueRef</message-destination-ref-name>
<jndi-name>java:/jms/queue/MessageBeanQueue</jndi-name>
</message-destination-ref>
</jboss-client>
Wichtig ist, dass die Queue nicht als resource-ref
eingetragen wird, sondern als message-destination-ref
!<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/ejb-jar_4_0.xsd"
version="4.0">
<display-name>MessageEJB</display-name>
<enterprise-beans>
<message-driven>
<display-name>MessageBean</display-name>
<ejb-name>MessageBean</ejb-name>
<ejb-class>de.hsrm.jakartaee.knauf.mdb.MessageBean</ejb-class>
<messaging-type>jakarta.jms.MessageListener</messaging-type>
<transaction-type>Container</transaction-type>
<message-destination-type>jakarta.jms.Queue</message-destination-type>
<activation-config>
<activation-config-property>
<activation-config-property-name>destinationType</activation-config-property-name>
<activation-config-property-value>jakarta.jms.Queue</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>destination</activation-config-property-name>
<activation-config-property-value>queue/MessageBeanQueue</activation-config-property-value>
</activation-config-property>
</activation-config>
</message-driven>
</enterprise-beans>
</ejb-jar>
Die Elemente "messaging-type", "transaction-type" und "message-destination-type" sind scheinbar optional,
die Anwendung hat jedenfalls auch ohne funktioniert.jakarta.jms.JMSDestinationDefinition
verwendet:@MessageDriven (activationConfig=
{
@ActivationConfigProperty(propertyName="destinationType", propertyValue="jakarta.jms.Queue"),
@ActivationConfigProperty(propertyName="destination", propertyValue="java:app/jms/queue/MessageBeanQueue")
})
@JMSDestinationDefinition(
name = "java:app/jms/queue/MessageBeanQueue",
interfaceName = "jakarta.jms.Queue",
destinationName = "MessageBeanQueue"
)
public class MessageBean implements MessageListener
}
Man beachte, dass die Queue hier ins private JNDI der Anwendung gebunden wird (siehe https://community.jboss.org/thread/235447)[standalone@localhost:9990 /] /deployment=Message.ear/subdeployment=MessageEJB.jar/subsystem=messaging-activemq/server=default/jms-queue=MessageBeanQueue:list-messages
{
"outcome" => "success",
"result" => []
}
jakarta.jms.JMSContext
arbeiten, der das Senden der Nachricht vereinfacht.
Die ConnectionFactory und die Queue muss man allerdings wie gehabt aus dem JNDI holen. QueueConnectionFactory queueConnectionFactory = (QueueConnectionFactory) initialContext.lookup("java:comp/env/jms/MBConnectionFactory");
Queue queue = (Queue) initialContext.lookup("java:comp/env/jms/MBQueueRef");
JMSContext context = queueConnectionFactory.createContext("tester", "test123!");
TextMessage textMessage = context.createTextMessage();
textMessage.setText(this.jTextFieldMessage.getText());
context.createProducer().send(queue, textMessage);
context.close();
Der JMSContext
wird hier über die jakarta.jms.ConnectionFactory
geholt, dabei wird das Passwort übergeben.@Inject
annotation). <resource-ref>
<res-ref-name>jms/MBQueueRef</res-ref-name>
<jndi-name>java:/jms/queue/MessageBeanQueue</jndi-name>
</resource-ref>
<subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0">
<server name="default">
<security-setting name="#">
<role name="guest" delete-non-durable-queue="true" create-non-durable-queue="true" consume="true" send="true"/>
</security-setting>
<address-setting name="#" message-counter-history-day-limit="10" page-size-bytes="2097152" max-size-bytes="10485760" expiry-address="jms.queue.ExpiryQueue" dead-letter-address="jms.queue.DLQ"/>
<http-connector name="http-connector" endpoint="http-acceptor" socket-binding="http"/>
<jms-queue name="MessageBeanQueue" entries="java:/jms/queue/MessageBeanQueue"/>
<connection-factory name="RemoteConnectionFactory" entries="java:/ConnectionFactory" connectors="http-connector"/>
</server>
</subsystem>
<resource-ref>
<res-ref-name>jms/MBQueueRef</res-ref-name>
<jndi-name>java:app/jms/queue/MessageBeanQueue</jndi-name>
</resource-ref>
20:23:10,912 ERROR [org.jboss.as.controller.management-operation] (Thread-42) WFLYCTL0013: Operation ("deploy") failed - address: ([("deployment" => "Message.ear")]) - failure description: {
"WFLYCTL0412: Required services that are not installed:" => ["jboss.naming.context.java.app.Message.jms.queue.MessageBeanQueue"],
"WFLYCTL0180: Services with missing/unavailable dependencies" => ["jboss.naming.context.java.module.Message.MessageClient.env.jms.MBQueueRef is missing [jboss.naming.context.java.app.Message.jms.queue.MessageBeanQueue]"]
}
20:23:10,913 ERROR [org.jboss.as.server] (Thread-42) WFLYSRV0021: Deploy of deployment "Message.ear" was rolled back with the following failure message:
{
"WFLYCTL0412: Required services that are not installed:" => ["jboss.naming.context.java.app.Message.jms.queue.MessageBeanQueue"],
"WFLYCTL0180: Services with missing/unavailable dependencies" => ["jboss.naming.context.java.module.Message.MessageClient.env.jms.MBQueueRef is missing [jboss.naming.context.java.app.Message.jms.queue.MessageBeanQueue]"]
}