Apache NiFi JMS integration with ActiveMQ Artemis

Connect Apache NiFi to ActiveMQ Artemis queues and topics with ConsumeJMS and PublishJMS, using a JMSConnectionFactoryProvider and client JARs from a local directory, and replace the deprecated GetJMSQueue and PutJMS processors.

On this page

Apache NiFi JMS integration with ActiveMQ Artemis: what it does and how it connects

A team that runs JMS queues or topics on ActiveMQ Artemis and needs NiFi to consume from or publish to them should build on ConsumeJMS and PublishJMS, paired with a JMSConnectionFactoryProvider controller service. These are the processors NiFi 2 supports for JMS. The older GetJMSQueue, GetJMSTopic and PutJMS processors were deprecated in NiFi 1.3.0 and are replaced by ConsumeJMS and PublishJMS, so any flow still built on the old names will need to be rebuilt during the move to 2.x. The ConsumeJMS component documentation describes the consuming side, including how the processor handles the connection factory it is given.

NiFi does not bundle JMS client libraries, so the connection depends on files you supply. The JMSConnectionFactoryProvider points to a local directory of client JAR files, and those JARs must match the Artemis client version your broker runs. The NiFi 2.0 migration guide uses ActiveMQ Artemis as its example for this setup, which makes it the natural reference for your configuration. Confirm the exact client JARs, the connection factory class and the broker URL with your Artemis administrator before you write the flow, and confirm that every node in a NiFi cluster can read the same library directory.

Decide early which message types the flow must handle. ConsumeJMS accepts BytesMessage, TextMessage, ObjectMessage, MapMessage and StreamMessage, copies JMS headers and properties to FlowFile attributes, and converts MapMessages to JSON. Map each queue or topic to the message type its producers actually send, and test with real samples from each producer. Ask the producing teams whether they use ObjectMessage, since deserializing Java objects from a queue is a security concern that needs its own review.

What you need before configuring the JMS flow

Most JMS problems in NiFi start before any processor is configured. The runtime, client libraries, broker account, network path and client version all have to line up on every node that will run the flow. Check these five items first, and record the answers so the flow design rests on them.

NiFi 2 runtime on Java 21

The NiFi administration guide lists Java 21 as the minimum runtime, so confirm every node runs that version or later before you install extensions. Mixed JVM versions across a cluster make failures hard to reproduce. Also confirm you are on NiFi 2, because the JMS processors in this topic are the replacements for the deprecated 1.x components. If you still run 1.x, plan the upgrade path first.

Artemis client JARs on every node

ConsumeJMS and PublishJMS do not bundle JMS libraries. Copy the ActiveMQ Artemis client JARs into one local directory on each node, and keep the paths identical so the JMSConnectionFactoryProvider resolves the same files everywhere. Record which JAR set came from which build, because copies that drift between nodes produce errors that appear only on some nodes.

Broker account with queue permissions

Request a dedicated broker account for NiFi rather than sharing an application login. Ask the broker team to grant consume rights on the queues or subscriptions the flow reads and send rights on the destinations it writes to. For topics, confirm who creates durable subscriptions, since a missing subscription can silently hide messages from the consumer.

Network path and TLS to the broker

Confirm that each NiFi node can reach the broker host and port, and that firewalls allow the connection in both directions where the protocol requires it. Decide whether the connection uses TLS, obtain the broker CA certificate, and store it where the NiFi truststore can reference it. Test from each node, not only from one, because cluster nodes often sit in different subnets.

Client and broker version match

Confirm that the Artemis client version is compatible with your broker version using the ActiveMQ Artemis vendor documentation. Do not assume that a newer client works with an older broker, or the reverse. Write the confirmed pair into the change record, and repeat the check whenever either side is upgraded.

How to configure ConsumeJMS and PublishJMS step by step

This sequence takes a NiFi 2 cluster from an empty canvas to a working ActiveMQ Artemis connection, with a verified consumer on a queue, a verified consumer on a topic and a publisher that sends a test message back to the broker.

  1. Place the Artemis client libraries in a local directory

    Before touching the NiFi canvas, copy the JMS client JAR files that your ActiveMQ Artemis version requires into a local directory on every NiFi node. Your broker or middleware team should confirm the exact client library set for the Artemis version in use, since NiFi does not bundle JMS libraries. Use the same path on each node and make sure the NiFi service account can read the files. You know this step is done when a listing of that directory on each node shows the same JAR files with matching sizes and checksums.

  2. Create the JMSConnectionFactoryProvider controller service

    In the NiFi canvas, open the controller services configuration at the root process group level and add a JMSConnectionFactoryProvider. Set its client library directory to the local JAR path from the previous step and set the connection factory class and broker URL that your Artemis administrator provides. Keep the broker URL, username and password in their sensitive property fields so NiFi encrypts them at rest, and do not paste credentials into descriptions or parameter values that are visible to all users. The service stays disabled until the next step, so do not expect it to validate yet.

  3. Enable the controller service and confirm validation

    Enable the JMSConnectionFactoryProvider from the controller services list. Enabling it should move the state to enabled with no validation errors. If the service reports that it cannot load the connection factory class or a required library, the JAR path, file permissions or client library version is the likely cause, and you should correct it before creating processors. Repeat the check on the cluster view if your nodes run the same configuration. You know this step is done when the service shows as enabled on the controller services page and no node reports a validation error.

  4. Add ConsumeJMS for a queue

    Add a ConsumeJMS processor to the canvas and set its JMS Connection Factory Provider property to the enabled service. Set the destination name to your Artemis queue and set the destination type to queue. Choose the message types you expect, such as TextMessage or MapMessage, and confirm how your team wants JMS headers and properties mapped to FlowFile attributes. Start the processor and send a test text message from the broker side. You know this step is done when a FlowFile appears in the success relationship with the expected content and attributes such as the JMS message ID and any custom properties, and the message no longer sits in the queue.

  5. Add ConsumeJMS for a topic

    Add a second ConsumeJMS processor for the topic and set the destination type to topic. Decide whether the subscription should be durable and agree the subscription name with your broker administrator, because a durable subscription keeps receiving messages while NiFi is stopped and a non-durable one does not. Keep topic consumers separate from queue consumers so that failures and backpressure on one path do not hide the other. Publish a test message to the topic and confirm that a FlowFile arrives with the expected attributes. You know this step is done when the topic processor shows FlowFiles in its success relationship and the attributes match the test message.

  6. Add PublishJMS to send messages to the broker

    Add a PublishJMS processor and point it at the same JMSConnectionFactoryProvider. Set the destination name and destination type to match the queue or topic you want to write to, and choose the message type that downstream consumers expect. Connect an upstream processor, such as one that generates a small test FlowFile with known content, to the PublishJMS input. Send a single FlowFile first so you can check the result before scaling up. You know this step is done when the processor reports the FlowFile on its success relationship and a consumer on the destination, such as the ConsumeJMS processor from the earlier steps, receives the same content.

  7. Run an end-to-end test and record the configuration

    Run one round trip through the flow: publish a test message with PublishJMS, consume it with ConsumeJMS, and compare the content and attributes at the end with what you sent. Check the failure and retry relationships for any FlowFiles and review the bulletin board for warnings about connection or library problems. Export the flow definition through your normal change process and record the controller service settings, the destination names and the client library version for your audit trail. You know this step is done when the round trip matches, no processor has unexplained bulletins, and the configuration is stored under version control or your change record.

How ConsumeJMS handles queues, topics and message types

ConsumeJMS accepts five JMS message types: BytesMessage, TextMessage, ObjectMessage, MapMessage and StreamMessage. Each received message becomes one FlowFile, and the JMS headers and properties are copied to FlowFile attributes. Those attributes carry values such as the message ID, correlation ID, destination and any custom properties your producers set, so routing and filtering can happen on attributes before the content is parsed. Check which properties your producers actually set, because a missing property simply produces a missing attribute, and downstream RouteOnAttribute logic will quietly send those messages to the wrong branch.

MapMessages are converted to JSON, which means the content your flow sees is no longer the raw JMS map. TextMessages and BytesMessages arrive as the payload you sent, so a record reader must match the format the producer wrote. If your flow expects a schema-driven reader, confirm that the JSON produced from MapMessages matches the schema you configured, including field types, nested values and null handling. ObjectMessage content is serialized Java objects, which NiFi does not interpret for you. Unless you control both producer and consumer and have an agreed deserialization path, treat ObjectMessages as opaque bytes and plan to convert them at the producer side, not in NiFi.

Test every message type you expect in production before go-live, using messages produced by the same client library and broker configuration your real producers use. Send one sample of each type through a queue and a topic, then inspect the FlowFile attributes, content and provenance for each. Confirm the behavior of your chosen record reader on malformed and empty payloads, and confirm that unexpected types fail visibly rather than passing through silently. Your Artemis administrators and application owners should sign off on the list of supported types, since a new producer sending a different type later is a common cause of parse failures.

How JMS headers, properties and message bodies map to FlowFiles

This table compares each JMS message part with where it lands in a NiFi FlowFile when ConsumeJMS reads it and where it goes when PublishJMS sends it. Read it as a checklist for the flow design review, then confirm each exact attribute name against the ConsumeJMS and PublishJMS documentation for the NiFi 2 release you run. The main takeaway is that body type and header or property handling decide what downstream processors can read without extra parsing.

JMS partFlowFile result (ConsumeJMS)Reverse path (PublishJMS)Check before go-live
JMS headersCopied to FlowFile attributesSet from FlowFile attributes where the processor supports itConfirm the attribute names for your release
Custom message propertiesCopied to FlowFile attributesWritten as JMS message propertiesTest property names with dots or hyphens
TextMessage bodyText becomes FlowFile contentContent sent as text messageCheck character encoding end to end
BytesMessage bodyRaw bytes become FlowFile contentContent sent as bytes messageConfirm downstream parsers expect binary input
ObjectMessage bodySerialized object becomes FlowFile contentNot a typical publish targetAvoid Java serialization across trust boundaries
MapMessage fieldsConverted to JSON contentMap fields must be rebuilt from record or JSON contentVerify field types after conversion
StreamMessage bodyHandled as a supported message typeConfirm publish support in the release usedTest with a sample message from the producer
Message type selectionDetermined by the JMS message classSet by the publish configurationRecord which type each queue or topic carries

Securing the JMS connection in NiFi

The JMS connection carries broker credentials, client libraries and message content, so each part needs its own control. The cards below cover where secrets live, who can change the connection, how the broker link is protected, how broker accounts are scoped, and how the client JAR directory is kept intact on every node.

Store broker credentials as sensitive values

Put the broker username and password into sensitive parameters or a parameter provider rather than typing them into controller service fields in plain text. NiFi encrypts sensitive values at rest in the flow, so the secret does not appear in exported flow definitions. Check that the parameter context holding the secret is restricted to the people who maintain the connection, and confirm how your chosen secrets store integrates with NiFi before the build starts.

Restrict changes to the connection

The JMSConnectionFactoryProvider controller service determines which broker, client libraries and credentials every ConsumeJMS and PublishJMS processor uses. Limit edit and enable rights on that controller service and on the parameter contexts it reads to a small group of administrators. Review the NiFi policies for these components so that flow developers can run and inspect flows without being able to repoint them at another broker.

Protect the broker link with TLS

Configure the broker URL and connection settings to use the TLS-enabled transport your ActiveMQ Artemis deployment offers, and verify the broker certificate chain against a trust store that NiFi nodes can read. Without transport encryption, credentials and message bodies cross the network in readable form. Confirm the exact URL scheme, trust store settings and certificate requirements with the broker vendor documentation for your Artemis version.

Scope broker accounts to each queue or topic

Create a separate broker user for each NiFi integration, granting send rights only on the destinations a PublishJMS flow writes to and receive or browse rights only on the queues or topics a ConsumeJMS flow reads. Avoid running NiFi under an administrative broker account. Confirm the permission model, address settings and wildcard behavior in the Artemis security documentation, since these details differ between broker configurations.

Lock the client JAR directory on each node

The client library directory referenced by the connection factory provider is loaded by every cluster node, so a file changed on one node can cause different behavior across the cluster. Make the directory writable only by the NiFi service account for deployment, and only through your change process. Verify checksums of the client JARs on each node after each update, and confirm that the JAR versions match the broker version you support.

Common ConsumeJMS and PublishJMS failures and their fixes

This table lists the failures teams most often hit when running ConsumeJMS and PublishJMS against ActiveMQ Artemis, with the likely cause and the fix for each. Read it when a processor is invalid, stalls, or silently drops messages, and work down the rows from configuration to runtime behavior.

FailureLikely causeFix
Provider reports an invalid or missing client JAR pathThe JMSConnectionFactoryProvider points to a directory that does not exist or is not readable by the NiFi service userConfirm the directory path in the controller service, check that the NiFi process user can read it, then re-enable the service and the processor
ClassNotFoundException for Artemis or JMS classesThe directory holds JARs from a different Artemis or JMS client version than the broker, or it lacks a dependency JARCopy the full client set matching your broker version from the Artemis distribution into one directory and remove older versions
Connection refused or authentication rejectedWrong broker URL, user name or password, or the broker user lacks permission to connectVerify the broker URL and credentials in the provider, then check the Artemis security settings for that user
Authorization denied on a queue or topicThe broker user can connect but lacks send or consume rights on the destination addressGrant the user consume or send permission on the specific queue or topic address in the broker security configuration
Topic consumer misses messages published while it was stoppedThe subscription is non-durable, so messages sent while no subscriber is active are not retained for itUse a durable subscription with a stable client identifier and subscription name if the flow must not lose topic messages, and test restart behavior
Messages fail or are routed as unsupportedThe message body type is outside the types ConsumeJMS reads, or a MapMessage is not converted as expectedCheck the message type on the producer side, convert unsupported payloads upstream, and confirm MapMessage output after conversion to JSON
Only the primary node can reach the JAR directoryThe client library directory exists on one cluster node only, so other nodes fail to load the providerInstall the identical directory with the same JARs on every node at the same path, and verify each node before scheduling the processors
Consumer runs but downstream gets no attributesJMS headers and properties are expected as attributes, but the flow reads the wrong attribute namesInspect the FlowFile attributes in the provenance view and reference the names ConsumeJMS actually writes before building routing rules

Replacing GetJMSQueue and PutJMS in existing flows

GetJMSQueue, GetJMSTopic and PutJMS were deprecated in 1.3.0, and the replacements are ConsumeJMS and PublishJMS. Treat the swap as a rebuild of each processor rather than a find-and-replace of the processor type, because the new processors read their connection details from a JMSConnectionFactoryProvider controller service and a local directory of client JAR files, not from settings on the processor itself. For each deprecated processor, list every property in use (destination name, destination type, connection factory, client library path, acknowledgement behavior, and any message or header handling), then confirm the property mapping for the replacement against the ConsumeJMS component documentation and the NiFi 2.0 migration guidance. Do not assume a one-to-one name match. Record the mapping in a change ticket so reviewers can check it.

Test the replacement against a copy of the queue before any production traffic moves. Ask your ActiveMQ Artemis administrator to create a test address and queue, or a copy of the existing one, and run the new ConsumeJMS and PublishJMS flow against it with representative messages: text, map and object payloads, plus messages carrying custom properties. Compare the FlowFile attributes and content with what the old flow produced, paying attention to how MapMessages are converted to JSON and how JMS headers and properties become attributes. Confirm that downstream processors still find the attributes they depend on.

Plan the cutover so messages are neither duplicated nor lost. Stop the old consumer first, let it drain or confirm its last acknowledged message, and only then start ConsumeJMS on the same queue, because two consumers on one queue will split messages between them and a half-finished cutover can leave messages in limbo. Keep the old flow disabled but available for rollback, and watch queue depth and the consumer count on the broker during the switch. Agree with the producing teams whether any messages published during the window need replay, and confirm with the broker operator how unacknowledged messages are redelivered if NiFi stops mid-batch.

Questions teams ask before connecting NiFi to ActiveMQ Artemis

What drives the effort of a JMS integration with NiFi?

The effort is driven by how many queues and topics the flow touches, how many distinct message types arrive on them, and how much each message must change before it leaves NiFi. A single queue carrying text messages that are passed through unchanged is a small job. Ten topics carrying a mix of map, object and binary messages, each needing parsing, routing and error handling, is a much larger one. Broker security settings, TLS, and whether messages must be acknowledged exactly once also add work. Ask any partner to break the quote down by flow count, message type and security scope.

Can our own team configure ConsumeJMS and PublishJMS in-house?

A team with NiFi operations experience can usually configure a single consume or publish flow in-house, provided it has the broker's client libraries and a test broker. The processors need a JMSConnectionFactoryProvider that points to a local directory of client JAR files, and NiFi does not bundle those libraries, so someone must source and version them correctly. Teams new to JMS should expect a learning curve around acknowledgement, message types and redelivery. A partner is most useful for designing the flow pattern, reviewing it, and handing over a tested runbook.

What does the integration need from broker and network teams?

Your broker team must provide the connection factory details, a dedicated service account with only the queue or topic permissions the flow needs, and confirmation of which destinations are queues and which are topics. Your network team must open the broker port from every NiFi node, not just the primary node, and confirm TLS requirements. Teams should also agree on who owns destination naming, dead-letter handling and retention on the broker side. Confirm these items with your broker vendor documentation and your own change process before the build starts.

How long does a JMS integration take?

Duration depends on the number of flows, the message types they handle, and the number of environments that must be tested and approved. No duration is set by the NiFi project, so timelines should come from a written scope rather than a general rule. A small, well-defined integration with one consumer and one publisher moves quickly through build and test. Each additional destination adds design, testing and change-control steps. Ask for a timeline that lists milestones per flow and per environment.

What changes when we migrate off GetJMSQueue and PutJMS?

GetJMSQueue, GetJMSTopic and PutJMS were deprecated in NiFi 1.3.0 and are replaced by ConsumeJMS and PublishJMS. The new processors do not bundle JMS libraries, so the connection factory and client JAR directory must be configured explicitly. Message handling changes too: ConsumeJMS reads BytesMessage, TextMessage, ObjectMessage, MapMessage and StreamMessage types, copies JMS headers and properties to FlowFile attributes, and converts MapMessages to JSON. Flows that depended on the old attribute names or message shapes need review and regression testing before cutover. Plan a parallel run where possible.

Is a NiFi 2 upgrade required before we start this integration?

If your environment still runs NiFi 1.x, the upgrade should be planned before the JMS work begins, because the integration targets NiFi 2 processors. The NiFi project states that 1.28 is the last minor release of the version 1 series and that 1.x cannot be maintained further. The migration guidance requires upgrading to NiFi 1.27.0 before moving to 2.0.0. Confirm the exact upgrade path against the NiFi migration guidance and your flow inventory, since other components may also need changes.

When should we bring in outside help for this integration?

Bring in outside help when the integration carries business-critical messages, involves many destinations, or must meet audit requirements for how data moves and is logged. It also makes sense when your team lacks JMS or NiFi cluster experience, or when a migration from the deprecated processors must happen on a fixed date. DeployOpen plans and implements these integrations under a written, fixed scope, and provides testing and documentation. Ask for a scope that names each flow, message type, environment and acceptance test before any work starts.

How DeployOpen scopes and delivers the NiFi JMS integration

DeployOpen plans, builds, tests and documents NiFi JMS flows inside your own infrastructure, including the ConsumeJMS and PublishJMS flows, the JMSConnectionFactoryProvider and the ActiveMQ Artemis client libraries. Engagements are fixed-scope, with the scope, deliverables and timelines agreed in writing before work starts.

How we scope

  • We list each queue and topic, its message types and the direction of every flow before any build begins.
  • We confirm the Artemis broker version, network paths, TLS and authentication requirements with your messaging team.
  • We record which GetJMSQueue, GetJMSTopic or PutJMS flows must be replaced, and agree the cutover approach in the written scope.

How we build

  • We configure the JMSConnectionFactoryProvider and place the approved client JAR files in a controlled local directory.
  • We map MapMessage, TextMessage, BytesMessage and other types to record handling and FlowFile attributes with tested parsing rules.
  • We test redelivery, duplicate handling, failed messages and node restarts in a staging NiFi cluster before production.

How we hand over

  • You receive flow definitions, controller service settings and a record of every client library version and its source.
  • We document the queue and topic contracts, acknowledgement behavior and the runbook for broker or NiFi outages.
  • Your team runs a walkthrough of the flows and the handover checklist agreed in the written scope.

How we support

  • Ongoing support, upgrades and continuous testing are available as a retainer, scoped separately from the build.
  • We plan retesting of JMS flows when you change the Artemis broker version or the NiFi release line.
  • Support requests cover flow changes, client library updates and troubleshooting that your team agrees to in writing.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.