> For the complete documentation index, see [llms.txt](https://docs.xplatform.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.xplatform.com/talon/developing-applications/configuring-messaging/configuring-bus-connections/solace-binding.md).

# Solace Binding

Configuration reference for the Solace message bus binding.

## Overview

The Solace binding provides native integration with Solace PubSub+ message brokers using either Solace's JCSMP (Java) API or CCSMP (C via JNI) API. The JNI binding supports zero-garbage messaging in steady state but is Linux-only, while the Java binding works on all platforms.

For conceptual information about the Solace binding, see [Solace Binding](/talon/concepts-and-architecture/messaging-model/solace-binding.md).

## JNI vs Java Binding Selection

Control which Solace client library is used:

| Property    | Default | Description                                                                               |
| ----------- | ------- | ----------------------------------------------------------------------------------------- |
| `usejni`    | -       | When `true`, mandates JNI usage (fails if unavailable). When `false`, never uses JNI.     |
| `preferjni` | true    | When `true`, silently falls back to JCSMP if JNI unavailable. Ignored if `usejni` is set. |

{% hint style="info" %}
The JNI binding is only available on Linux platforms and provides zero-garbage messaging capabilities.
{% endhint %}

## Bus Descriptor Format

Solace buses can be configured using a descriptor string or decomposed DDL format.

### Descriptor String

```
solace://<address>:<port>&prop1=val1&propN=valN
```

**Example**:

```
solace://192.168.1.9:55555&usejni=true&vpn_name=default&username=test&password=test
```

### Decomposed DDL Format

```xml
<buses>
  <bus name="my-bus">
    <provider>solace</provider>
    <address>192.168.1.9</address>
    <port>55555</port>
    <properties>
      <usejni>true</usejni>
      <vpn_name>default</vpn_name>
      <username>test</username>
      <password>test</password>
    </properties>
    <channels>
      <!-- channel configuration -->
    </channels>
  </bus>
</buses>
```

### As Descriptor (Substitution Support)

```xml
<buses>
  <bus name="my-bus" descriptor="solace://${solace.host}:${solace.port}&vpn_name=${solace.vpn}&username=${solace.user}&password=${solace.password}">
    <channels>
      <!-- channel configuration -->
    </channels>
  </bus>
</buses>
```

## Solace Provider Properties

### Passed Through Properties

Provider properties specified in the bus descriptor are passed through to the Solace connection with the following processing:

1. Properties described in [`SolaceBindingProperties`](https://build.neeveresearch.com/core/javadoc/LATEST/com/neeve/solace/SolaceBindingProperties.html) are stripped out
2. General bus properties from [`MessageBusDescriptor`](https://build.neeveresearch.com/core/javadoc/LATEST/com/neeve/sma/MessageBusDescriptor.html) are stripped out
3. Rationalized properties (see below) are translated based on JNI vs Java binding and passed through
4. If `usejni=true`: Properties not starting with `FLOW_` or `SESSION_` are stripped, rest passed through
5. If `usejni=false`: Properties not starting with `jcsmp` are stripped, rest passed through

{% hint style="warning" %}
Neeve does not test properties not explicitly documented on this page or in the javadoc. End users should test any passed-through properties thoroughly.
{% endhint %}

### Rationalized Passed Through Properties

These common properties are automatically translated between JCSMP (Java) and CCSMP (JNI):

| Binding Property             | Default    | JCSMP Property                                     | CCSMP Property                          |
| ---------------------------- | ---------- | -------------------------------------------------- | --------------------------------------- |
| `vpn_name`                   | -          | `jcsmp.vpn_name`                                   | `SESSION_VPN_NAME`                      |
| `username`                   | vpn\_name  | `jcsmp.username`                                   | `SESSION_USERNAME`                      |
| `password`                   | username   | `jcsmp.password`                                   | `SESSION_PASSWORD`                      |
| `publish_window_size`        | 255        | `jcsmp.pub_ack_window_size`                        | `SESSION_PUB_WINDOW_SIZE`               |
| `reconnect_retry_count`      | 100        | `jcsmp.CLIENT_CHANNEL_PROPERTIES.ReconnectRetries` | `SESSION_RECONNECT_RETRIES`             |
| `connect_retry_count`        | 3          | `jcsmp.CLIENT_CHANNEL_PROPERTIES.ConnectRetries`   | `SESSION_CONNECT_RETRIES`               |
| `tcp_nodelay`                | auto-tuned | `jcsmp.CLIENT_CHANNEL_PROPERTIES.tcpNoDelay`       | `SESSION_TCP_NODELAY`                   |
| `reapply_subscriptions`      | true       | `jcsmp.REAPPLY_SUBSCRIPTIONS`                      | `SESSION_REAPPLY_SUBSCRIPTIONS`         |
| `ignore_subscriptions_error` | true       | `jcsmp.IGNORE_DUPLICATE_SUBSCRIPTION_ERROR`        | `SESSION_IGNORE_DUP_SUBSCRIPTION_ERROR` |
| (address from descriptor)    | -          | `jcsmp.HOST`                                       | `SESSION_HOST`                          |

### Additional Properties

See [`SolaceBindingProperties`](https://build.neeveresearch.com/core/javadoc/LATEST/com/neeve/solace/SolaceBindingProperties.html) javadoc for the complete list of binding-specific properties.

### Auto Tuning

When not explicitly set, these properties are automatically configured based on `nv.optimizefor`:

| Binding Property                        | `nv.optimizefor=latency`                                                                                                                                              | `nv.optimizefor=throughput`                                                                                                                                           | No Optimization |
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- |
| `tcp_nodelay`                           | true                                                                                                                                                                  | false                                                                                                                                                                 | false           |
| `detached_sends_queue_wait_strategy`    | See [`XRuntime.createWaitStrategy`](https://build.neeveresearch.com/core/javadoc/LATEST/com/neeve/ci/XRuntime.html#createWaitStrategy\(java.lang.String,%20boolean\)) | See [`XRuntime.createWaitStrategy`](https://build.neeveresearch.com/core/javadoc/LATEST/com/neeve/ci/XRuntime.html#createWaitStrategy\(java.lang.String,%20boolean\)) | Blocking        |
| `detached_dispatch_queue_wait_strategy` | See [`XRuntime.createWaitStrategy`](https://build.neeveresearch.com/core/javadoc/LATEST/com/neeve/ci/XRuntime.html#createWaitStrategy\(java.lang.String,%20boolean\)) | See [`XRuntime.createWaitStrategy`](https://build.neeveresearch.com/core/javadoc/LATEST/com/neeve/ci/XRuntime.html#createWaitStrategy\(java.lang.String,%20boolean\)) | Blocking        |

## Session Configuration

By default, the binding creates two separate sessions — one for consuming (suffixed with `-IN`) and one for producing (suffixed with `-OUT`) — to avoid network flow control deadlocks and improve throughput.

| Property                      | Default                | Description                                                                                                                                                                                                                                         |
| ----------------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `single_session`              | false                  | Use a single session for both publishing and consuming. Default uses separate consumer and producer sessions to avoid network flow control deadlocks. Single session uses fewer threads and resources and is suitable for unidirectional messaging. |
| `client_name`                 | username or queue name | Unique client name to identify the session on the appliance. Suffixed with `-IN` and `-OUT` unless `single_session=true`. If `use_default_queue_name_as_default_client_id` is set, the default queue name is used instead.                          |
| `session_open_retry_count`    | 5                      | Number of retry attempts to establish a session after transient errors. Permanent errors (e.g., invalid client name, dynamic clients not allowed, endpoint property mismatch) are not retried.                                                      |
| `session_open_retry_interval` | 1                      | Interval in seconds between session open retry attempts.                                                                                                                                                                                            |
| `consumer_cpu_affinity_mask`  | 0                      | CPU affinity mask for the Solace consumer session's Context receiver thread. Not to be confused with the detached dispatcher thread.                                                                                                                |
| `producer_cpu_affinity_mask`  | 0                      | CPU affinity mask for the Solace producer session's Context receiver thread. Not to be confused with the detached sender thread.                                                                                                                    |

## Queue Configuration

A Solace queue must be provisioned for the binding to support guaranteed messaging. The queue holds messages for the application while it is disconnected.

| Property                                      | Default                 | Description                                                                                                                                                                                         |
| --------------------------------------------- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `queue_name`                                  | X-SMA-{name}-{userName} | Solace queue name for guaranteed messaging. When not specified, a default name is generated from the bus name and user name. When set to blank (empty string), no queue is used.                    |
| `use_default_queue_name`                      | true                    | Whether to use the auto-generated default queue name when `queue_name` is not specified. Disabling this without setting `queue_name` means no queue is used, compromising guaranteed messaging QoS. |
| `use_default_queue_name_as_default_client_id` | false                   | Use the default queue name as the client name when `client_name` is not explicitly set.                                                                                                             |
| `provision_queue`                             | true                    | Attempt to provision the queue on a best-effort basis. Requires endpoint management to be enabled on the appliance. If the queue cannot be provisioned, a warning is logged.                        |
| `queue_quota`                                 | 2048                    | Queue quota in MB when provisioning a queue (default 2 GB).                                                                                                                                         |

## Detached Sends

The binding can create a detached sender thread to offload message marshalling and Solace API send calls from the application thread, improving throughput.

{% hint style="info" %}
Talon AepEngine users should note that this is separate from the detached send specified for the AEP bus. Enabling this property in conjunction with detached send in AEP results in two detached send threads.
{% endhint %}

| Property                             | Default    | Description                                                                                                                                           |
| ------------------------------------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `detached_sends`                     | false      | Create a detached sender thread for published messages. Offloads message marshalling and Solace API calls to improve throughput.                      |
| `detached_sends_queue_depth`         | 1024       | Disruptor ring buffer queue depth for the detached sender.                                                                                            |
| `detached_sends_queue_wait_strategy` | auto-tuned | Wait strategy for the detached sends disruptor queue (e.g., `BusySpinWaitStrategy`, `YieldingWaitStrategy`, `BlockingWaitStrategy`). See Auto Tuning. |
| `detached_sends_cpu_affinity_mask`   | 0          | CPU affinity mask for the detached sender thread.                                                                                                     |

## Detached Dispatch

The binding can create a detached dispatch thread for message deserialization and dispatch, allowing the Solace receiver thread to exclusively handle I/O work.

| Property                                | Default    | Description                                                                                                                                              |
| --------------------------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `detached_dispatch`                     | false      | Create a detached dispatch thread for received messages. Offloads deserialization and dispatch from the Solace receiver thread to improve throughput.    |
| `detached_dispatch_queue_depth`         | 128        | Disruptor ring buffer queue depth for the detached dispatcher.                                                                                           |
| `detached_dispatch_queue_wait_strategy` | auto-tuned | Wait strategy for the detached dispatch disruptor queue (e.g., `BusySpinWaitStrategy`, `YieldingWaitStrategy`, `BlockingWaitStrategy`). See Auto Tuning. |
| `dispatcher_cpu_affinity_mask`          | 0          | CPU affinity mask for the detached dispatcher thread.                                                                                                    |

## Wire Metadata

| Property               | Default | Description                                                                                                                                                                                                                                                                                                                  |
| ---------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sma_metadata_version` | 1       | Controls the version of SMA metadata encoded in outbound messages. The Solace binding encodes SMA message metadata in the message's SDTMap keyed by `x-sma-metadata`. Use `2` for more efficient metadata if no receivers use versions prior to 1.8.396. The metadata version must be supported by all downstream receivers. |

## Message Handling

| Property                                 | Default | Description                                                                                                                                                                |
| ---------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `set_key_on_receipt`                     | false   | Sets the topic on a per-message basis. Accessible via `message.getMessageKeyAsRaw()`.                                                                                      |
| `fail_on_inbound_message_handling_fault` | false   | Fail the binding unconditionally when an inbound message handling fault occurs. When `false`, an `UnhandledMessageEvent` is dispatched, leaving the application to decide. |
| `treat_non_x_inbound_as_fault`           | true    | Treat receipt of non-X (non-SMA) messages as a fault. When `false`, non-X messages are handled gracefully.                                                                 |

## Orphan Subscription Checks

When a Solace bus binding has a queue name specified, it can detect "orphan" subscriptions - subscriptions on the queue that don't match those issued by the application (presumably left over from an earlier session).

### Policies

| Policy                  | Description                                                                                                                                      |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| None                    | Appliance is not queried for subscriptions (default).                                                                                            |
| Ignore                  | Query appliance and trace orphan subscriptions at info level. Report to subscription validator if registered.                                    |
| LogExceptionAndContinue | Query appliance and log exception if orphans found.                                                                                              |
| NoOrphan                | Query appliance and throw exception from binding start method if orphans found.                                                                  |
| Unsubscribe             | With this policy enabled, the appliance is queried for subscriptions and orphan subscriptions are then removed (unsubscribed) from the appliance |

### Configuration

To perform subscription checks, SEMP must be enabled:

| Property                               | Usage       | Default       | Description                                                                                                                                                                                                                                                      |
| -------------------------------------- | ----------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `enable_semp`                          | optional    | false         | Enable Solace SEMP over messaging requests. Required for subscription checks. Requires appliance has SEMP over messaging enabled and user is authorized. **NOTE**: SEMP operations are experimental and not recommended for production without rigorous testing. |
| `orphan_subscription_check`            | optional    | None          | Orphan subscription check policy. Performed after subscriptions created but before messaging started. Requires `enable_semp=true` for policies other than None.                                                                                                  |
| `orphan_subscription_check_batch_size` | optional    | 200           | Batch size for sequenced fetch of subscriptions during orphan subscription check. Used when the subscription count exceeds what can be returned in a single response.                                                                                            |
| `discard_semp_prestart_messages`       | optional    | true          | Discard BestEffort messages received before SEMP checks complete during binding startup. Prevents the dispatch thread from blocking on SEMP requests. Only disable if the bus's event handler will not block on messages received before `start()` returns.      |
| `semp_version`                         | recommended | soltr/7\_1\_1 | SEMP version. Must match messaging appliance version. If not set, version auto-detected on first request.                                                                                                                                                        |
| `semp_request_timeout`                 | recommended | 10000         | Timeout for SEMP requests in milliseconds. Test under load to ensure sufficient.                                                                                                                                                                                 |
| `subscription_validator`               | unsupported | -             | Legacy property for custom subscription validation. Use only with Neeve support guidance.                                                                                                                                                                        |

{% hint style="warning" %}
**SEMP Operations Warning**: SEMP operations are experimental. Not recommended for production without rigorous end-user testing. Solace may drop SEMP over messaging support in future versions. Reliance on SEMP may limit ability to connect to appliances with incompatible SEMP models.
{% endhint %}

## Enforcing Max Queue Bind Count

When using Guaranteed messaging, queues can be provisioned with max bind count of 1 to ensure only one application instance can bind. The binding can enforce this via SEMP:

| Property                 | Usage    | Default | Description                                                                                                                                                                                                                                                                                                                |
| ------------------------ | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `enable_semp`            | optional | false   | Must be enabled (see above).                                                                                                                                                                                                                                                                                               |
| `enforce_max_bind_count` | optional | 0       | Set to positive value to enforce match against provisioned queue's max bind count. When set, binding issues SEMP request at start to verify queue's max bind count matches this value. Ensures exclusive connectivity with `enforce_max_bind_count=1`. Ignored if no queue configured or value ≤ 0. Requires SEMP enabled. |

{% hint style="info" %}
**Since 3.8**: `enforce_max_bind_count` provides protection against network partitioning by ensuring two instances cannot both consume messages.
{% endhint %}

## Trace Logging

The Solace binding logs trace messages using two loggers:

### The `nv.sma` Logger

Controls trace level and messages emitted by the binding code itself (not the Solace client library).

### The `nv.sol` Logger

Controls trace level and messages emitted by the Solace client runtime.

#### JNI Enabled (CCSMP)

When using JNI, the binding:

1. Maps `nv.sol` logger level to CCSMP trace level (see table below)
2. Registers callback with CCSMP to intercept trace messages
3. Logs CCSMP messages via `nv.sol` logger

**nv.sol to CCSMP Mapping**:

| nv.sol Level                   | CCSMP Level |
| ------------------------------ | ----------- |
| SEVERE                         | ERROR       |
| WARNING                        | WARNING     |
| INFO, CONFIG                   | NOTICE      |
| FINE, FINER, DIAGNOSE, VERBOSE | INFO        |
| FINEST, DEBUG, ALL             | DEBUG       |

**CCSMP to nv.sol Mapping** (for logged messages):

| CCSMP Level     | nv.sol Level |
| --------------- | ------------ |
| CRITICAL, ERROR | SEVERE       |
| WARNING         | WARNING      |
| NOTICE          | INFO         |
| INFO            | FINE         |
| DEBUG           | FINEST       |

#### JNI Disabled (JCSMP)

When using JCSMP, the binding:

1. Maps `nv.sol` logger level to set `com.solacesystems.jcsmp` logger level
2. Assumes all JCSMP logging uses the `com.solacesystems.jcsmp` logger

**nv.sol to com.solacesystems.jcsmp Mapping**:

| nv.sol Level              | com.solacesystems.jcsmp Level |
| ------------------------- | ----------------------------- |
| SEVERE                    | SEVERE                        |
| WARNING                   | WARNING                       |
| INFO                      | INFO                          |
| CONFIG                    | CONFIG                        |
| FINE                      | FINE                          |
| FINER                     | FINER                         |
| DIAGNOSE, VERBOSE, FINEST | FINEST                        |
| DEBUG, ALL                | ALL                           |

See [Trace Logging](/talon/developing-applications/authoring-user-code/trace-logging.md) for information on configuring loggers.

## See Also

* [Solace Binding](/talon/concepts-and-architecture/messaging-model/solace-binding.md) - Conceptual overview
* [Configuring Bus Connections](/talon/developing-applications/configuring-messaging/configuring-bus-connections.md) - General bus configuration
* [Solace Documentation](https://solace.com/products/message-routers) - Solace PubSub+ information
