Issue connecting to a remote JMS queue from standalone client - jms

I am new to JMS and have an issue connecting to a remote JMS queue from my standalone client. Any hints on resolving this issue would be highly appreciated.
Right now I have a JavaFX standalone application that runs on multiple clients and a glassfish server 3.1.2.2 running on a remote Unix machine. I am having a hard time pushing messages from my standalone app on to the queue that is residing on the server.
Client Mc: Windows PC (No server installed)
Remote Mc: Unix (GlassFish 3.1.2.2 installed)
JMS resources on the server:
JMS Destination Resource
JNDI Name: jms/ReferralQueue
Physical Destination Name: ReferralQueue
Resource Type: javax.jms.Queue
JMS Connection Factory
Pool Name: jms/ReferralConnectionFactory
JNDI Name: jms/ReferralConnectionFactory
Resource Type: javax.jms.QueueConnectionFactory
JMS Service Type: Embedded
JMS Message Store Type: File
Client Side Code to connect to the server:
jms.properties:
org.omg.CORBA.ORBInitialHost=UNIX MC URL
org.omg.CORBA.ORBInitialPort=7676
Service Locator design to implement resource caching
public class JMSServiceLocator {
private static JMSServiceLocator singletonService = null;
private static QueueConnectionFactory qFactory;
private static Queue queue;
private InitialContext context;
private static Properties properties = new Properties();
private Map cache;
static {
try {
singletonService = new JMSServiceLocator();
} catch (Exception e) {
//error handling
}
}
private JMSServiceLocator() {
try {
loadProperties();
context = new InitialContext(properties);
cache = Collections.synchronizedMap(new HashMap());
} catch (Exception e) {
//error handling
}
}
public static JMSServiceLocator getInstance() {
return singletonService;
}
public QueueConnectionFactory getQueueConnectionFactory() {
String qConnFactoryName = "jms/ReferralConnectionFactory";
qFactory = null;
try {
System.out.println("/********************Comment after Testing*****************************/");
Hashtable env = context.getEnvironment();
System.out.println("**env.size::" + env.size());
Enumeration names = env.keys();
while (names.hasMoreElements()) {
String str = (String) names.nextElement();
System.out.println("**" + str + "=" + env.get(str));
}
System.out.println("/**********************************************************************/");
if (cache.containsKey(qConnFactoryName)) {
qFactory = (QueueConnectionFactory) cache.get(qConnFactoryName);
} else {
qFactory = (QueueConnectionFactory) context.lookup(qConnFactoryName);
cache.put(qConnFactoryName, qFactory);
}
} catch (Exception e) {
//error handling
}
return qFactory;
}
public Queue getQueue() {
String queueName = "jms/ReferralQueue";
queue = null;
try {
if (cache.containsKey(queueName)) {
queue = (Queue) cache.get(queueName);
} else {
queue = (Queue) context.lookup(queueName);
cache.put(queueName, queue);
}
} catch (Exception e) {
//error handling
}
return queue;
}
private static void loadProperties() {
//Load jms properties
}
}
Eventually sending message to the server:
JMSServiceLocator jmsLocator = JMSServiceLocator.getInstance();
QueueConnectionFactory qConnFactory = jmsLocator.getQueueConnectionFactory();
qConnection = qConnFactory.createQueueConnection();
session = qConnection.createSession(false, ession.AUTO_ACKNOWLEDGE);
queue = jmsLocator.getQueue();
// Push and publish the message
messageProducer = session.createProducer(queue);
textMessage = session.createTextMessage();
textMessage.setText(message);
messageProducer.send(textMessage);
Hmmm... Now I observe a strange behavior...
I created a new GlassFish 3.1.2.2 server instance on the client machine with no jndi, no connection factories, and no jms queues what so ever.
I have started this server instance and executed the standalone client application. Strangely, everything works fine and the message is directly being pushed to the remote queue.
Did any one come across this kind of issue? I am suspecting that probably the application is loading the dependent GlassFish jars in the classpath only when a server instance (could be any random instance, totally unrelated) is started.
I have the following jars in my standalone application classpath:
*C:\Program Files\glassfish-3.1.2.2\glassfish\lib\gf-client.jar
*C:\Program Files\glassfish-3.1.2.2\glassfish\lib\appserv-rt.jar
*C:\Program Files\glassfish-3.1.2.2\glassfish\lib\install\applications\jmsra\imqbroker.jar
*C:\Program Files\glassfish-3.1.2.2\glassfish\lib\install\applications\jmsra\imqjmsra.jar
I have also posted this on Oracle JMS and GlassFish forums and haven't got a solution. Any help on this issue would be highly appreciated.
Thanks.

I think you found out by now what the problem was:
the JMS client jars were missing on the client (Client Mc: Windows PC (No server installed)).
You don't need a full Glassfish installation on the clients but only the JMS client jars (gf-client.jar) plus all the other jars referenced by gf-client.jar.

Related

No mannaged connection when using jms

I am using wildfly jms queue... I'm using wildfly 9.0.2.Final
I make the producer like this :
#Inject
private JMSContext jmsContext;
private JMSProducer jmsProducer;
#Resource(mappedName = "java:/jboss/exported/jms/queue/TosDownloadReport")
private Queue queueDownloadReport;
public void downloadReport(String adminId, DownloadReportFilter filter){
try {
jmsProducer = jmsContext.createProducer();
String requestParam = Json.getInstance().getObjectMapper().writeValueAsString(filter);
LOG.info("requestParam {}", requestParam);
String id = UUID.randomUUID().toString().replace("-", "");
RoutingRequest request = new RoutingRequest();
request.putProperty("id", id);
request.putProperty("adminId", adminId);
request.putProperty("parameterRequest", requestParam);
QueueMsgDownloadReport message = new QueueMsgDownloadReport();
message.setId(id);
message.setAdminId(adminId);
String jsonMsg = Json.getInstance().getObjectMapper().writeValueAsString(message);
gatewayService.send(RESOURCE, METHOD, request);
jmsProducer.send(queueDownloadReport, jsonMsg);
} catch (Exception e) {
LOG.error(e.getMessage(),e);
}
}
But sometimes i get exception like this and i must restart wildfly
2017-05-05 11:08:20,004 ERROR [com.daksa.tos.infrastructure.api.TosTimer] (EJB default - 7) Could not create a session: IJ000453: Unable to get managed connection for java:/JmsXA: javax.jms.JMSRuntimeException: Could not create a session: IJ000453: Unable to get managed connection for java:/JmsXA
Caused by: javax.resource.ResourceException: IJ000655: No managed connections available within configured blocking timeout (30000 [ms])
From what i read, i don't need to call jmsContext.close() if i'm using inject right?
Please tell me what i do wrong...Thx

A connection pool error in CloudBees Java EE/Glassfish 4 Full plateform

CloudBees is add a new Java EE 7/Glassfish 4 Full plateform in their clickstart. If I understand correctly, this mean that it support all Java EE 7 features(contain JMS app). But when I run my JMS app, it log a error "Failed to obtain/create connection from connection pool [ jms/__defaultConnectionFactory-Connection-Pool"
This is my code, it work in my localhost:
#Named
#RequestScoped
public class ReceiverBean {
static final Logger logger = Logger.getLogger("ReceiverBean");
#Inject
private JMSContext context;
#Resource(lookup = "java:comp/jms/webappQueue")
private Queue queue;
.....
public void getMessage() {
try {
JMSConsumer receiver = context.createConsumer(queue);
String text = receiver.receiveBody(String.class, 1000);
if (text != null) {
FacesMessage facesMessage =
new FacesMessage("Reading message: " + text);
FacesContext.getCurrentInstance().addMessage(null, facesMessage);
} else {
FacesMessage facesMessage =
new FacesMessage("No message received after 1 second");
FacesContext.getCurrentInstance().addMessage(null, facesMessage);
}
} catch (JMSRuntimeException t) {
logger.log(Level.SEVERE,
"ReceiverBean.getMessage: Exception: {0}",
t.toString());
}
}
The log of glassfish in CloudBees console:
[#|2013-11-19T07:36:43.737+0000|INFO|glassfish
4.0|javax.enterprise.resource.jms.com.sun.enterprise.connectors.jms.system|_ThreadID=21;_ThreadName=http-listener-1(1);_TimeMillis=1384846603737;_LevelValue=800;_MessageID=addresslist.setjmsservice.provider;|
JMS010: ADDRESSLIST in setJmsServiceProvider: mq://localhost:0/|#]
[#|2013-11-19T07:36:43.738+0000|INFO|glassfish
4.0|javax.enterprise.resource.jms.com.sun.enterprise.connectors.jms.system|_ThreadID=21;_ThreadName=http-listener-1(1);_TimeMillis=1384846603738;_LevelValue=800;_MessageID=jms.connection.url;|
JMS08: JMS Service Connection URL is : mq://localhost:0/|#]
[#|2013-11-19T07:36:44.552+0000|INFO|glassfish
4.0|javax.resourceadapter.mqjmsra.lifecycle|_ThreadID=21;_ThreadName=http-listener-1(1);_TimeMillis=1384846604552;_LevelValue=800;|
MQJMSRA_RA1101: GlassFish MQ JMS Resource Adapter: Version: 5.0
(Build 14-e) Compile: April 12 2013 0104|#]
[#|2013-11-19T07:36:44.559+0000|INFO|glassfish
4.0|javax.resourceadapter.mqjmsra.lifecycle|_ThreadID=21;_ThreadName=http-listener-1(1);_TimeMillis=1384846604559;_LevelValue=800;|
MQJMSRA_RA1101: GlassFish MQ JMS Resource Adapter starting: broker is
EMBEDDED, connection mode is Direct|#]
[#|2013-11-19T07:36:44.847+0000|INFO|glassfish
4.0|imq.log.Logger|_ThreadID=21;_ThreadName=http-listener-1(1);_TimeMillis=1384846604847;_LevelValue=800;|
[B1002]: An existing property file for imqbroker was not found, no
stored properties will be loaded |#]
[#|2013-11-19T07:36:45.558+0000|SEVERE|glassfish
4.0||_ThreadID=21;_ThreadName=Thread-4;_TimeMillis=1384846605558;_LevelValue=1000;|
Broker exiting.|#]
[#|2013-11-19T07:36:45.562+0000|INFO|glassfish
4.0|javax.resourceadapter.mqjmsra.lifecycle|_ThreadID=21;_ThreadName=http-listener-1(1);_TimeMillis=1384846605562;_LevelValue=800;|
MQJMSRA_RA1101: GlassFish MQ JMS Resource Adapter Started:EMBEDDED|#]
[#|2013-11-19T07:36:49.808+0000|WARNING|glassfish
4.0|javax.enterprise.resource.resourceadapter.com.sun.enterprise.connectors|_ThreadID=22;_ThreadName=http-listener-1(2);_TimeMillis=1384846609808;_LevelValue=900;_MessageID=poolmgr.get_connection_failure;|
RAR5117 : Failed to obtain/create connection from connection pool [
jms/__defaultConnectionFactory-Connection-Pool ]. Reason :
com.sun.appserv.connectors.internal.api.PoolingException|#]
[#|2013-11-19T07:36:49.811+0000|SEVERE|glassfish
4.0|SenderBean|_ThreadID=22;_ThreadName=http-listener-1(2);_TimeMillis=1384846609811;_LevelValue=1000;|
SenderBean.sendMessage: Exception:
com.sun.messaging.jms.MQRuntimeException: MQRA:DCF:allocation
failure:createConnection:Error in allocating a connection. Cause:
null|#]
Anyone could tell me why?
Many thanks in advance
CloudBees supports the web profile on the Glassfish stack, see here. JMS is only supported on the full profile, see here.
You can try the Glassfish 3 full profile here. It is a community stack.
"Glassfish 4 Full Profile" clickstack is a work in progress, it doesn't support JMS yet, neither does it support distributed EJB or comparable JavaEE stuff.

JMS application on cloudBees with Amazon EC2 broker

I have a Java ee 7 JMS app, I would like deploy it on CloudBees. I have tried a simple app with cloudAMQP, it work. But CloudAMQP offers hosted RabbitMQ service. I have to use JMS client, because my code is implement in java JMS.
The last day, I have create a glassfish 4 broker in Amazon Ec2, I have deployed a simple JMS app in CloudBees glassfish web profile platform and I have expected it can work with my Amazon glassfish broker. But there is a error.
My code is:
#JMSConnectionFactoryDefinition(
name="java:comp/jms/__defaultConnectionFactory",
maxPoolSize = 30,
minPoolSize= 20,
properties = {
"addressList=mq://ec2-54-194-27-99.eu-west-1.compute.amazonaws.com:7676",
"reconnectEnabled=true"
}
)
#JMSDestinationDefinition(
name = "java:comp/jms/webappQueue",
interfaceName = "javax.jms.Queue",
destinationName = "PhysicalWebappQueue")
#Named
#RequestScoped
public class ReceiverBean {
static final Logger logger = Logger.getLogger("ReceiverBean");
#Inject
private JMSContext context;
#Resource(lookup = "java:comp/jms/webappQueue")
private Queue queue;
.....
public void getMessage() {
try {
JMSConsumer receiver = context.createConsumer(queue);
String text = receiver.receiveBody(String.class, 1000);
if (text != null) {
FacesMessage facesMessage =
new FacesMessage("Reading message: " + text);
FacesContext.getCurrentInstance().addMessage(null, facesMessage);
} else {
FacesMessage facesMessage =
new FacesMessage("No message received after 1 second");
FacesContext.getCurrentInstance().addMessage(null, facesMessage);
}
} catch (JMSRuntimeException t) {
logger.log(Level.SEVERE,
"ReceiverBean.getMessage: Exception: {0}",
t.toString());
}
}
The error is
|2013-11-17T22:34:09.146+0000|SEVERE|glassfish 4.0|javax.enterprise.system.core|_ThreadID=45;_ThreadName=AutoDeployer;_TimeMillis=1384727649146;_LevelValue=1000;|
Exception while loading the app : CDI deployment failure:Exception
List with 2 exceptions:
Exception 0 :
org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied
dependencies for type [JMSContext] with qualifiers [#Default] at
injection point [[BackedAnnotatedField] #Inject private
javaeetutorial.websimplemessage.SenderBean.context]
Can you have some ideas for my case?
Thanks in advance.
Web profile don't include JMS, so this API and related annotation / injection isn't supported.
For this to work you need a full-profile JavaEE + adequate configuration set in container to plug your broker. Probably simpler to use vanila JMS API vs annotation-driven integration

jms sending message on any server

I want to write generic code for sending message on any jms server. so for that i thought if i have jndi.properties file then we can place server configuration in this file and we can access this file through the code but i am able to do this only for 'ActiveMQ Server'. Now i am facing problems to send the message on any other server like glassfish server or jboss server. can somebody help me to do this task.
Here is my code :
public class Producer
{
public Producer() throws JMSException, NamingException,IOException
{
InputStream is = getClass().getResourceAsStream("my.jndi.properties");
Properties jndiParamaters = new Properties();
jndiParamaters.load(is);
Context jndi = new InitialContext(jndiParamaters);
ConnectionFactory conFactory = (ConnectionFactory) jndi.lookup("connectionFactory");
Connection connection;
connection = conFactory.createConnection();
try
{
connection.start();
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
Destination destination = (Destination) jndi.lookup("Myqueue");
MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage("Hello World!");
producer.send(message);
System.out.println("Sent message '" + message.getText() + "'");
}
finally
{
connection.close();
}
}
public static void main(String[] args) throws JMSException
{
try
{
BasicConfigurator.configure();
new Producer();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
thanks
Have you tried using the Spring JMS Template? http://static.springsource.org/spring/docs/2.0.x/reference/jms.html
It provides an abstraction layer to JMS and could probably help you when your implementation changes.

IBM.XMS ExceptionListener not firing

I am using IBM.XMS 2.0.0.5 and MQ Client 7.0.1.5 and have created a connection, set the exception listener, started the connection and started listening for messages using a message listener. This works fine, except that the ExceptionListener does not fire when I disable the network connection. Instead I get an unhandled socket exception.
I have gone back to the example given on the IBM site and recreated the error:
If I disable the network connetion I get the unhandled socket exception and the exceptionListener does not get fired.
using System;
using System.Threading;
using IBM.XMS;
public class Sample
{
public static void Main()
{
XMSFactoryFactory factoryFactory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
IConnectionFactory connectionFactory = factoryFactory.CreateConnectionFactory();
connectionFactory.SetStringProperty(XMSC.WMQ_HOST_NAME, "**********");
connectionFactory.SetStringProperty(XMSC.WMQ_CHANNEL, "*****");
connectionFactory.SetIntProperty(XMSC.WMQ_PORT, 1414);
connectionFactory.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT);
connectionFactory.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, "*********");
//
// Create the connection and register an exception listener
//
IConnection connection = connectionFactory.CreateConnection();
connection.ExceptionListener = new ExceptionListener(OnException);
ISession session = connection.CreateSession(false, AcknowledgeMode.AutoAcknowledge);
IDestination queue = session.CreateQueue("queue://***********");
//
// Create the consumer and register an async message listener
//
IMessageConsumer consumer = session.CreateConsumer(queue);
consumer.MessageListener = new MessageListener(OnMessage);
connection.Start();
while (true)
{
Console.WriteLine("Waiting for messages....");
Thread.Sleep(1000);
}
}
static void OnMessage(IMessage msg)
{
Console.WriteLine(msg);
}
static void OnException(Exception ex)
{
Console.WriteLine(ex);
}
}
I'll put the answer up in the hope that it saves someone the time it wasted for me.
You need to use an unmanaged client connection in order to connect up an exception listener to your connection.
connectionFactory.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT_UNMANAGED);
If it's just worked in Unmanaged mode, then it's a bug at XMS .NET v2.0.0.5. It should work in Managed mode also (XMSC.WMQ_CM_CLIENT_MANAGED). Please move to the latest fix pack and test again.

Resources