or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdconnection-management.mdcore-operations.mddestination-resolution.mdindex.mdmessage-conversion.mdmessage-listeners.md

destination-resolution.mddocs/

0

# Destination Resolution

1

2

Pluggable destination resolution supporting JNDI lookups, dynamic destination creation, bean factory integration, and caching for flexible destination management. Spring JMS provides multiple strategies for resolving JMS destinations to accommodate various deployment environments and naming conventions.

3

4

## Capabilities

5

6

### DestinationResolver Interface

7

8

Core strategy interface for resolving destination names to JMS Destination objects, enabling pluggable destination resolution strategies.

9

10

```java { .api }

11

/**

12

* Strategy interface for resolving JMS destination names to Destination objects

13

*/

14

public interface DestinationResolver {

15

16

/**

17

* Resolve the given destination name to a JMS Destination

18

* @param session the current JMS session

19

* @param destinationName the name of the destination to resolve

20

* @param pubSubDomain whether the domain is pub-sub (topic) or point-to-point (queue)

21

* @return the resolved Destination object

22

* @throws JMSException in case of JMS errors

23

* @throws DestinationResolutionException in case of resolution errors

24

*/

25

Destination resolveDestinationName(Session session, String destinationName, boolean pubSubDomain)

26

throws JMSException;

27

}

28

```

29

30

### DynamicDestinationResolver

31

32

Default destination resolver that creates destinations dynamically using JMS Session methods, suitable for JMS providers that support dynamic destination creation.

33

34

```java { .api }

35

/**

36

* Default destination resolver that creates destinations dynamically

37

*/

38

public class DynamicDestinationResolver implements DestinationResolver {

39

40

public DynamicDestinationResolver();

41

42

/**

43

* Resolve destination name by creating queue or topic dynamically

44

* @param session the JMS session

45

* @param destinationName the destination name

46

* @param pubSubDomain true for topics, false for queues

47

* @return the resolved destination

48

* @throws JMSException in case of JMS errors

49

*/

50

@Override

51

public Destination resolveDestinationName(Session session, String destinationName, boolean pubSubDomain)

52

throws JMSException;

53

54

// Template methods for creating destinations

55

protected Queue resolveQueueName(Session session, String queueName) throws JMSException;

56

protected Topic resolveTopicName(Session session, String topicName) throws JMSException;

57

}

58

```

59

60

### JndiDestinationResolver

61

62

JNDI-based destination resolver that looks up destinations from a JNDI directory, commonly used in Java EE application servers.

63

64

```java { .api }

65

/**

66

* Destination resolver that uses JNDI lookups

67

*/

68

public class JndiDestinationResolver extends JndiLocatorSupport implements DestinationResolver {

69

70

// Constructors

71

public JndiDestinationResolver();

72

73

// JNDI configuration

74

public void setJndiTemplate(JndiTemplate jndiTemplate);

75

public void setJndiEnvironment(Properties jndiEnvironment);

76

public void setResourceRef(boolean resourceRef);

77

78

// Caching configuration

79

public void setCache(boolean cache);

80

public boolean isCache();

81

public void clearCache();

82

83

// Fallback configuration

84

public void setFallbackToDynamicDestination(boolean fallbackToDynamicDestination);

85

public boolean isFallbackToDynamicDestination();

86

87

// Lookup methods

88

protected Destination lookupDestination(String destinationName) throws NamingException;

89

protected Queue lookupQueue(String queueName) throws NamingException;

90

protected Topic lookupTopic(String topicName) throws NamingException;

91

92

// Resolution method

93

@Override

94

public Destination resolveDestinationName(Session session, String destinationName, boolean pubSubDomain)

95

throws JMSException;

96

}

97

```

98

99

### BeanFactoryDestinationResolver

100

101

Destination resolver that resolves destinations as Spring-managed beans from the application context, providing integration with Spring's dependency injection.

102

103

```java { .api }

104

/**

105

* Destination resolver that resolves destinations as Spring beans

106

*/

107

public class BeanFactoryDestinationResolver implements DestinationResolver, BeanFactoryAware {

108

109

public BeanFactoryDestinationResolver();

110

public BeanFactoryDestinationResolver(BeanFactory beanFactory);

111

112

// Bean factory configuration

113

public void setBeanFactory(BeanFactory beanFactory);

114

protected BeanFactory getBeanFactory();

115

116

// Resolution method

117

@Override

118

public Destination resolveDestinationName(Session session, String destinationName, boolean pubSubDomain)

119

throws JMSException;

120

121

// Template method for bean lookup

122

protected Destination resolveDestinationName(String destinationName);

123

}

124

```

125

126

### CachingDestinationResolver

127

128

Decorator for destination resolvers that caches resolved destinations for improved performance by avoiding repeated resolution calls.

129

130

```java { .api }

131

/**

132

* Caching wrapper for destination resolvers

133

*/

134

public class CachingDestinationResolver implements DestinationResolver {

135

136

// Constructors

137

public CachingDestinationResolver();

138

public CachingDestinationResolver(DestinationResolver targetResolver);

139

140

// Target resolver configuration

141

public void setTargetResolver(DestinationResolver targetResolver);

142

public DestinationResolver getTargetResolver();

143

144

// Cache management

145

public void clearCache();

146

public int getCacheSize();

147

148

// Resolution method with caching

149

@Override

150

public Destination resolveDestinationName(Session session, String destinationName, boolean pubSubDomain)

151

throws JMSException;

152

}

153

```

154

155

### JmsDestinationAccessor

156

157

Abstract base class for JMS accessor objects that use destination resolvers, providing common configuration for destination resolution and pub/sub domain handling.

158

159

```java { .api }

160

/**

161

* Base class for JMS accessor objects with destination resolution support

162

*/

163

public abstract class JmsDestinationAccessor extends JmsAccessor {

164

165

// Destination resolver configuration

166

public void setDestinationResolver(DestinationResolver destinationResolver);

167

public DestinationResolver getDestinationResolver();

168

169

// Pub/Sub domain configuration

170

public void setPubSubDomain(boolean pubSubDomain);

171

public boolean isPubSubDomain();

172

173

// Destination resolution methods

174

protected Destination resolveDestinationName(Session session, String destinationName) throws JMSException;

175

protected Queue resolveQueueName(Session session, String queueName) throws JMSException;

176

protected Topic resolveTopicName(Session session, String topicName) throws JMSException;

177

}

178

```

179

180

### Destination Resolution Exceptions

181

182

Exception hierarchy for destination resolution errors with specific error categorization.

183

184

```java { .api }

185

/**

186

* Exception thrown when destination resolution fails

187

*/

188

public class DestinationResolutionException extends JmsException {

189

190

public DestinationResolutionException(String msg);

191

public DestinationResolutionException(String msg, Throwable cause);

192

}

193

```

194

195

**Usage Examples:**

196

197

```java

198

import org.springframework.jms.support.destination.*;

199

import javax.naming.Context;

200

import java.util.Properties;

201

202

// Configuration for different destination resolution strategies

203

@Configuration

204

public class DestinationConfig {

205

206

// Dynamic destination resolver (default)

207

@Bean

208

public DestinationResolver dynamicDestinationResolver() {

209

return new DynamicDestinationResolver();

210

}

211

212

// JNDI destination resolver for Java EE environments

213

@Bean

214

public DestinationResolver jndiDestinationResolver() {

215

JndiDestinationResolver resolver = new JndiDestinationResolver();

216

resolver.setResourceRef(true); // Use java:comp/env/ prefix

217

resolver.setCache(true); // Enable caching for performance

218

resolver.setFallbackToDynamicDestination(true); // Fallback if JNDI lookup fails

219

220

// Configure JNDI environment

221

Properties jndiProps = new Properties();

222

jndiProps.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.activemq.jndi.ActiveMQInitialContextFactory");

223

jndiProps.setProperty(Context.PROVIDER_URL, "tcp://localhost:61616");

224

resolver.setJndiEnvironment(jndiProps);

225

226

return resolver;

227

}

228

229

// Bean factory destination resolver

230

@Bean

231

public DestinationResolver beanFactoryDestinationResolver() {

232

return new BeanFactoryDestinationResolver();

233

}

234

235

// Caching destination resolver wrapper

236

@Bean

237

public DestinationResolver cachingDestinationResolver() {

238

return new CachingDestinationResolver(jndiDestinationResolver());

239

}

240

241

// Define destinations as Spring beans

242

@Bean

243

public Queue orderQueue() {

244

return new ActiveMQQueue("order.queue");

245

}

246

247

@Bean

248

public Topic notificationTopic() {

249

return new ActiveMQTopic("notification.topic");

250

}

251

252

// JmsTemplate with custom destination resolver

253

@Bean

254

public JmsTemplate jmsTemplate() {

255

JmsTemplate template = new JmsTemplate(connectionFactory());

256

template.setDestinationResolver(cachingDestinationResolver());

257

return template;

258

}

259

260

// Message listener container with destination resolver

261

@Bean

262

public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {

263

DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();

264

factory.setConnectionFactory(connectionFactory());

265

factory.setDestinationResolver(cachingDestinationResolver());

266

return factory;

267

}

268

}

269

270

// Service using destination resolution

271

@Service

272

public class MessagingService {

273

274

@Autowired

275

private JmsTemplate jmsTemplate;

276

277

@Autowired

278

private DestinationResolver destinationResolver;

279

280

// Using destination names (resolved automatically by JmsTemplate)

281

public void sendToQueue(String queueName, Object message) {

282

jmsTemplate.convertAndSend(queueName, message);

283

}

284

285

public void sendToTopic(String topicName, Object message) {

286

jmsTemplate.setPubSubDomain(true);

287

jmsTemplate.convertAndSend(topicName, message);

288

}

289

290

// Manual destination resolution

291

public void sendWithManualResolution(String destinationName, Object message) {

292

jmsTemplate.send(session -> {

293

// Manually resolve destination

294

Destination destination = destinationResolver.resolveDestinationName(

295

session, destinationName, false); // false = queue, true = topic

296

297

MessageProducer producer = session.createProducer(destination);

298

ObjectMessage objMessage = session.createObjectMessage((Serializable) message);

299

producer.send(objMessage);

300

301

return objMessage;

302

});

303

}

304

}

305

306

// Custom destination resolver implementation

307

@Component

308

public class CustomDestinationResolver implements DestinationResolver {

309

310

private final Map<String, String> destinationMappings = new HashMap<>();

311

private final DestinationResolver fallbackResolver = new DynamicDestinationResolver();

312

313

@PostConstruct

314

public void initializeMappings() {

315

// Map logical names to physical destinations

316

destinationMappings.put("orders", "app.orders.v1");

317

destinationMappings.put("notifications", "app.notifications.v1");

318

destinationMappings.put("audit", "app.audit.v1");

319

}

320

321

@Override

322

public Destination resolveDestinationName(Session session, String destinationName, boolean pubSubDomain)

323

throws JMSException {

324

325

// Apply destination mapping

326

String physicalName = destinationMappings.getOrDefault(destinationName, destinationName);

327

328

// Add environment prefix

329

String environment = System.getProperty("app.environment", "dev");

330

String resolvedName = environment + "." + physicalName;

331

332

// Use fallback resolver for actual destination creation

333

return fallbackResolver.resolveDestinationName(session, resolvedName, pubSubDomain);

334

}

335

}

336

337

// Destination resolver with conditional logic

338

@Component

339

@Profile("production")

340

public class ProductionDestinationResolver implements DestinationResolver {

341

342

@Autowired

343

private JndiDestinationResolver jndiResolver;

344

345

@Autowired

346

private DynamicDestinationResolver dynamicResolver;

347

348

@Override

349

public Destination resolveDestinationName(Session session, String destinationName, boolean pubSubDomain)

350

throws JMSException {

351

352

// Try JNDI first for production destinations

353

try {

354

return jndiResolver.resolveDestinationName(session, destinationName, pubSubDomain);

355

} catch (DestinationResolutionException e) {

356

// Fallback to dynamic resolution for temporary destinations

357

if (destinationName.startsWith("temp.") || destinationName.startsWith("reply.")) {

358

return dynamicResolver.resolveDestinationName(session, destinationName, pubSubDomain);

359

}

360

throw e;

361

}

362

}

363

}

364

```