JMeter中JSR223 Sampler发布JMS报InvalidDestinationException错误求助
JMeter JSR223 Sampler 发布JMS时触发 InvalidDestinationException 问题
问题详情
在JMeter中使用JSR223 Sampler向JMS队列/主题发送消息执行性能测试时,出现以下错误:
javax.script.ScriptException: javax.jms.InvalidDestinationException: Not allowed to create destination.
已完成验证:
- JMS团队确认所有队列/主题配置信息无误
- 相关JMS客户端Jar包已放置在JMeter的
lib目录下 - 相同配置在Eclipse中可成功发送消息,但JMeter测试环境下失败
现有Groovy代码
import java.util.Properties; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Message; import javax.jms.MessageProducer; import javax.jms.Session; import javax.naming.*; // message submission initial phase String providerURL = "ldap://sample.com"; String CFDestination = "connection factory details"; //connection factory String destination = "Topic name"; // Queue or Topic String CONTEXT_FACTORY = "Client specific TibcoInitialContext"; String login = "User"; String passwd = "pwd"; String file = null; int maxLimit = -1; int counter = 0; Properties lookup = new Properties(); lookup.setProperty( Context.INITIAL_CONTEXT_FACTORY, CONTEXT_FACTORY ); lookup.setProperty( Context.PROVIDER_URL, providerURL ); InitialContext context = new InitialContext(lookup); ConnectionFactory factory = (ConnectionFactory) context.lookup( "fxClientUID=" + CFDestination ); //ConnectionFactory factory = (ConnectionFactory) context.lookup("fxClientDestinationUID=" + CFDestination); Connection connection = factory.createConnection(login, passwd); Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE ); MessageProducer producer = session.createProducer(session.createTopic(destination)); CFDestination.setPubSubDomain(true); // end of initial phase // message submission long iTrackingNumber; String DS_TrackingNbr = "123456789"; iTrackingNumber= iTrackingNumber.valueOf(DS_TrackingNbr); String sTrackingNumber = ""; //for ( int i =0 ; i<30000; i++) for ( int i =0 ; i<1; i++) { iTrackingNumber = iTrackingNumber +1; sTrackingNumber = String.valueOf(iTrackingNumber); String strPart1 = """Message to publish"""; String messageString = strPart1;//+sTrackingNumber+strPart2; Message message = session.createTextMessage(messageString); //message.setStringProperty("TriggerEventType","CE"); message.setStringProperty("TriggerEventType", "CE"); message.setStringProperty("SourceType", "ITIH"); message.setStringProperty("GEOCODE", "REU"); producer.send(message); sleep(1); } // end of message submission // post submission phase connection.close(); session.close(); context.close(); // end of post submission
问题原因与解决方案
核心问题
错误提示"Not allowed to create destination"表明JMS服务器禁止动态创建主题/队列,必须通过JNDI查找服务器上预先配置好的目标对象,而非通过session.createTopic()或session.createQueue()动态生成。
同时代码存在一处明显错误:CFDestination.setPubSubDomain(true);,CFDestination是字符串变量,无法调用setPubSubDomain方法,这行代码会直接抛出异常,需删除或修正。
修改后的代码示例
将动态创建主题改为JNDI查找目标,同时修正无效代码:
import java.util.Properties; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Message; import javax.jms.MessageProducer; import javax.jms.Session; import javax.jms.Topic; import javax.naming.*; // message submission initial phase String providerURL = "ldap://sample.com"; String CFDestination = "connection factory details"; //connection factory String destinationJndiName = "Topic name"; // 服务器预定义的主题JNDI名称 String CONTEXT_FACTORY = "Client specific TibcoInitialContext"; String login = "User"; String passwd = "pwd"; Properties lookup = new Properties(); lookup.setProperty( Context.INITIAL_CONTEXT_FACTORY, CONTEXT_FACTORY ); lookup.setProperty( Context.PROVIDER_URL, providerURL ); InitialContext context = new InitialContext(lookup); // 查找连接工厂 ConnectionFactory factory = (ConnectionFactory) context.lookup( "fxClientUID=" + CFDestination ); // 查找预定义主题(替换为实际JNDI前缀,比如fxClientDestinationUID=) Topic targetTopic = (Topic) context.lookup("fxClientDestinationUID=" + destinationJndiName); Connection connection = factory.createConnection(login, passwd); Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE ); MessageProducer producer = session.createProducer(targetTopic); // 部分JMS实现需要显式启动连接 connection.start(); // end of initial phase // message submission long iTrackingNumber = Long.valueOf("123456789"); String sTrackingNumber = ""; for (int i = 0 ; i < 1; i++) { iTrackingNumber++; sTrackingNumber = String.valueOf(iTrackingNumber); String strPart1 = """Message to publish"""; String messageString = strPart1; Message message = session.createTextMessage(messageString); message.setStringProperty("TriggerEventType", "CE"); message.setStringProperty("SourceType", "ITIH"); message.setStringProperty("GEOCODE", "REU"); producer.send(message); sleep(1); } // end of message submission // post submission phase producer.close(); // 显式关闭生产者 session.close(); connection.close(); context.close(); // end of post submission
额外注意事项
- 确认目标的JNDI名称与服务器配置完全一致(包括前缀,比如
fxClientDestinationUID=) - 重启JMeter确保
lib目录下的Jar包被正确加载 - 部分JMS实现需显式调用
connection.start()才能发送消息 - 确保JMeter运行用户拥有访问JMS目标的权限
内容的提问来源于stack exchange,提问作者Veera
相关产品推荐
相关产品推荐

