My code receives the message from the queue multiple time, I want to receive it only one time. How can I do it? - queue

I am new, so my question is relatively easy, I guess.
I am using Websphere Application Server platform and default JMS provider to send and receive message from queue. This is how my app looks like:
Saytime is my main servlet which reroute my code to a .jsp file. The "Produce" button sends the app following code and generate the message written in box:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String queueName = "jms/helloqueue";
Context jndiContext = null;
QueueConnectionFactory queueConnectionFcatory = null;
QueueConnection queueConnection = null;
QueueSession queueSession = null;
QueueSender queueSender = null;
Queue queue = null;
TextMessage textMessage = null;
response.setContentType("text/html");
request.setCharacterEncoding("UTF-8"); // To information the that you may use Unicode characters
response.setCharacterEncoding("UTF-8");
String txt = request.getParameter("text");
try {
Properties initialProperties = new Properties();
initialProperties.put(InitialContext.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");
initialProperties.put(InitialContext.PROVIDER_URL, "iiop://localhost:2810");
jndiContext = new InitialContext(initialProperties);
} catch (NamingException e) {
e.printStackTrace();
System.exit(1);
}
try {
queueConnectionFcatory = (QueueConnectionFactory) jndiContext.lookup("jms/helloqcf");
queue = (Queue) jndiContext.lookup(queueName);
} catch (NamingException e) {
e.printStackTrace();
System.exit(1);
}
try {
queueConnection = queueConnectionFcatory.createQueueConnection();
queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queueSender = queueSession.createSender(queue);
textMessage = queueSession.createTextMessage();
textMessage.setText(txt);
queueSender.send(textMessage);
} catch (JMSException e) {
System.out.println("JMS Exception occured: "+ e.getMessage());
} finally {
if(queueConnection != null){
try{
Thread.sleep(6000);
queueConnection.close();
} catch(Exception e){}
}
}
RequestDispatcher rd = request.getRequestDispatcher("saytime");
rd.forward(request,response);
}
The "Receive" button sends my app to following servlet code and receives the message from queue:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String queueName = "jms/helloqueue";
Context jndiContext = null;
QueueConnectionFactory queueConnectionfactory = null;
QueueConnection queueConnection = null;
QueueSession queueSession = null;
QueueReceiver queueReceiver = null;
Queue queue = null;
String text = null;
try {
Properties initialProperties = new Properties();
initialProperties.put(InitialContext.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");
initialProperties.put(InitialContext.PROVIDER_URL,"iiop://localhost:2810");
jndiContext = new InitialContext(initialProperties);
} catch (NamingException e) {
System.out.println("JNDI exception occured: " + e.getMessage());
System.exit(1);
}
try {
queueConnectionfactory = (QueueConnectionFactory) jndiContext.lookup("jms/helloqcf");
queue = (Queue) jndiContext.lookup(queueName);
} catch (NamingException e) {
System.exit(1);
}
try {
queueConnection = queueConnectionfactory.createQueueConnection();
queueSession = queueConnection.createQueueSession(true,Session.AUTO_ACKNOWLEDGE);
queueReceiver = queueSession.createReceiver(queue);
//queueReceiver.setMessageListener(listener);
queueConnection.start();
text = queueReceiver.receive().toString();
} catch(JMSException e) {
System.out.println("Exception occured: "+ e.getMessage());
} finally {
if (queueConnection != null) {
try {
queueConnection.close();
} catch (JMSException e) {
}
}
}
if(text != null) {
request.setAttribute("message", text.toString());
}
RequestDispatcher rd = request.getRequestDispatcher("saytime");
rd.forward(request,response);
}
After that I print the message with this little code in my .jsp file:
<%
String getValues = (String) request.getAttribute("message");
%>
<%
if (getValues != null) {
out.println("<p>" + getValues + "</p>");
} else {
out.println("<p> There is no message </p>");
}
%>
The problem is this: I am able to take my produced message, but the button continues to receive the message till the count on JMSXDeliveryCount hit 5. Mostly JMSXDeliveryCount start with 1 and total I can receive the message 5 times. I want to receive it only once and then message to disappear.
Additionally, I want to know how I can print only my message. I print with additional details like you see in the picture. If it's possible, I don't want that.
I tried to limit redelivery number, but I am unable to come up with right code I guess. Also, I tried to use different acknowledgement mode but, it did not work either.
I got really confused with it, some help would be perfect. Thanks.

The problem is you're creating the consumer's session as transacted. See this line:
queueSession = queueConnection.createQueueSession(true,Session.AUTO_ACKNOWLEDGE);
The acknowledgement mode will be ignored since the session is transacted (i.e. you're passing true in the first parameter). This is noted in the documentation which states:
If transacted is set to true then the session will use a local transaction which may subsequently be committed or rolled back by calling the session's commit or rollback methods. The argument acknowledgeMode is ignored.
Therefore, you should either acknowledge the message and commit the session manually, e.g.:
Message message = queueReceiver.receive();
text = message.toString();
message.acknowledge();
queueSession.commit();
Or you should use a non-transacted session and allow the message to be auto-acknowledged according to the acknowledgement mode, e.g.:
queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Typically transacted sessions are only used when multiple operations (i.e. send and receive) need to be combined together atomically. Since you're only consuming a single message here I would recommend you just use a non-transacted session.
Also, you will eventually want to cache the javax.jms.Connection or perhaps use a connection pool rather than creating a connection, session, & producer/consumer for every message. This is an anti-pattern and should be avoided whenever possible.

Related

FIX:How to send ,messages using FIX ,quickfixj

# Here is my settings.cfg file:
# Thank you.Here is what i tried.My settings.cfg file
[DEFAULT]
# Settings which apply to all the Sessions.
ConnectionType=initiator
LogonTimeout=30
ReconnectInterval=20
ResetOnLogon=Y
FileLogPath=C:\Work\QuickFIXJ\logs
FileStorePath=C:\Work\QuickFIXJ\logs
[SESSION]
# Settings specifically for one session
BeginString=FIX.4.4
SenderCompID=XYZ
TargetCompID=TYZ
TimeZone=Asia/Tokyo
StartTime=16:00:00
EndTime=13:30:00
HeartBtInt=60
SocketConnectPort=7200
SocketConnectHost=123.123.123.123
UseDataDictionary=Y
DataDictionary=C:\Work\QuickFIXJ\datadictionary\FIX44.xml
[GATEWAY]
Port=4444
[TRANSPORT]
Port=4444
and then
//initiator code:
public class TestQuickFixJConnectivity {
public static void main(String[] args) {
SocketInitiator socketInitiator = null;
try {
SessionSettings sessionSettings = new SessionSettings("C:\\Work\\QuickFixJ\\sessionSettings.txt");
Application application = new TestApplicationImpl();
FileStoreFactory fileStoreFactory = new FileStoreFactory(sessionSettings);
FileLogFactory logFactory = new FileLogFactory(sessionSettings);
MessageFactory messageFactory = new DefaultMessageFactory();
socketInitiator = new SocketInitiator(application,
fileStoreFactory, sessionSettings, logFactory,
messageFactory);
socketInitiator.start();
SessionID sessionId = socketInitiator.getSessions().get(0);
sendLogonRequest(sessionId);
int i = 0;
do {
try {
Thread.sleep(1000);
System.out.println(socketInitiator.isLoggedOn());
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
} while ((!socketInitiator.isLoggedOn()) && (i < 30));
} catch (ConfigError e) {
e.printStackTrace();
} catch (SessionNotFound e) {
e.printStackTrace();
} catch (Exception exp) {
exp.printStackTrace();
} finally {
if (socketInitiator != null) {
socketInitiator.stop(true);
}
}
}
private static void sendLogonRequest(SessionID sessionId) throws SessionNotFound {
Logon logon = new Logon();
Message msg=new Message();
Header header = msg.getHeader();
logon.set(new HeartBtInt(60));
logon.set(new ResetSeqNumFlag(true));
header.setField(new BeginString("FIX.4.4"));
header.setField(new MsgType("AP"));
header.setField(new SenderCompId("XYZ"));
header.setField(new TagetCompId("TYZ"));
header.setField(new ResetSeqNumFlag(true));
//here i m setting all the fields in the csv report .
msg.setField(705,new SortQty(""));
// ....
//below statement returning false
boolean sent = Session.sendToTarget(msg, sessionId);
System.out.println("Logon Message Sent : " + sent);
}
}
Please find my observations below:
In the event logs I am seeing as Created session: and the message which I am trying to send. Also I could see that the sender sequence number is getting incremented in the logs.
Messages.log and header.logs are blank and body.log has the message which i am trying to send.
Also onCreate and ToApp are being called when I try to run the code.
I want to know whether i have sent the message successfully ?
Also boolean sent = Session.sendToTarget(msg, sessionId); is returning false.
I don't see ToAdmin and FromAdmin being executed in my code. Also Do I need to write the acceptor code as well for the same, or just the initiator code will be fine. The DataDictionary which i am using has all the fields set, but I am not sure whether its being used by QuickFixJ when i try to execute the code.
Please advise whats going wrong in this?
OK your settings file looks ok and you're saying it works, but I don't think you need GATEWAY and TRANSPORT headings
As for your code, all you need to do to start with is setup the default QuickFIX Application, FileStoreFactory, LogFactory, MessageFactory and Initiator which you have done.
The default QuickFIX automatically logs on to the Target in your settings file, and if the logon is accepted then it begins to heartbeat. From your comments it sounds like this is happening.
So what's going wrong is your sendLogonRequest is not necessary. Also, if you do send "extra" logons then the target FIX engine will probably reject or ignore them. The reject message would be seen in the logs or file store.
So then you have the QuickFIX API with which to start with you can simply output messages to your own log.
Something like this
public void fromApp(Message msg, SessionID s) throws UnsupportedMessageType, FieldNotFound, IncorrectTagValue
{
log.debug(String.valueOf(LocalTime.now()) + " INITIATOR: FromApp " + msg.toString());
}
public void toApp(Message msg, SessionID s)
{
log.info(String.valueOf(LocalTime.now()) + " INITIATOR: ToApp " + msg.toString());
}
public void fromAdmin(Message msg, SessionID s) throws FieldNotFound, IncorrectTagValue
{
Log.trace("INITIATOR: FromAdmin " + msg.getClass() + " " + msg.toString());
}
public void onCreate(SessionID s)
{
log.info("INITIATOR: OnCreate " + s.toString());
}
public void onLogout(SessionID s)
{
log.error("INITIATOR: OnLogout " + s.toString());
}
public void onLogon(SessionID s)
{
log.info("INITIATOR: OnLogon " + s.toString());
}
public void toAdmin(Message msg, SessionID s)
{
log.trace("INITIATOR: ToAdmin " + msg.getClass() + " " + msg.toString());
}
Then when you want to send a message, try something like this:
QuoteReqID id = new QuoteReqID("1234");
// Create Quote Request message
QuoteRequest qr = new QuoteRequest(id);
// Setup outgoing group and specify an index for each group tag
NoRelatedSym g = new NoRelatedSym();
String instrument = m.getString("EUR/USD");
Symbol symbol = new Symbol(instrument);
g.setField(1, symbol);
QuoteRequestType qt = new QuoteRequestType(102);
g.setField(2, qt);
OrderQty qty = new OrderQty("1000000");
g.setField(3, qty);
SettlType sType = new SettlType("B");
g.setField(4, sType);
SettlDate sDate = new SettlDate("20170315");
g.setField(5, sDate);
Account account = new Account("357647");
g.setField(6, account);
// add group to request
qr.addGroup(g);
Session s = Session.lookupSession(i.getSessions().get(0));
s.send(qr);

JBoss JMS MessageConsumer waits indefinitely for response message

I am trying to create a synchronous request using JMS on JBoss
Code for MDB is:
#Resource(mappedName = "java:/ConnectionFactory")
private ConnectionFactory connectionFactory;
#Override
public void onMessage(Message message) {
logger.info("Received message for client call");
if (message instanceof ObjectMessage) {
Connection con = null;
try {
con = connectionFactory.createConnection();
con.start();
Requests requests = (Requests) ((ObjectMessage) message)
.getObject();
String response = getClient().get(getRequest(requests));
con = connectionFactory.createConnection();
Session ses = con.createSession(true, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = ses.createProducer(message
.getJMSReplyTo());
TextMessage replyMsg = ses.createTextMessage();
replyMsg.setJMSCorrelationID(message.getJMSCorrelationID());
replyMsg.setText(response);
logger.info("Sending reply to client call : " + response );
producer.send(replyMsg);
} catch (JMSException e) {
logger.severe(e.getMessage());
} finally {
if (con != null) {
try {
con.close();
} catch (Exception e2) {
logger.severe(e2.getMessage());
}
}
}
}
}
Code for client is:
#Resource(mappedName = "java:/ConnectionFactory")
private QueueConnectionFactory queueConnectionFactory;
#Resource(mappedName = "java:/queue/request")
private Queue requestQueue;
#Override
public Responses getResponses(Requests requests) {
QueueConnection connection = null;
try {
connection = queueConnectionFactory.createQueueConnection();
connection.start();
QueueSession session = connection.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);
MessageProducer messageProducer = session
.createProducer(requestQueue);
ObjectMessage message = session.createObjectMessage();
message.setObject(requests);
TemporaryQueue temp = session.createTemporaryQueue();
MessageConsumer consumer = session.createConsumer(temp);
message.setJMSReplyTo(temp);
messageProducer.send(message);
Message response = consumer.receive();
if (response instanceof TextMessage) {
logger.info("Received response");
return new Responses(null, ((TextMessage) response).getText());
}
} catch (JMSException e) {
logger.severe(e.getMessage());
} finally {
if (connection != null) {
try {
connection.close();
} catch (Exception e2) {
logger.severe(e2.getMessage());
}
}
}
return null;
}
The message is received fine on the queue, the response message is created and the MessageProducer sends the response without issue, with no errors. However the consumer just sits and waits indefinitely. I have also tried creating a separate reply queue rather then using a temporary queue and the result is the same.
I am guessing that I am missing something basic with this set up but I cannot for the life of me see anything I am doing wrong.
There is no other code, the 2 things I have read on this that can cause problems is that the connection.start() isn't called or the repsonses are going to some other different receiver, which isn't happening here (as far as I know - there are no other messaging parts to the code outside of these classes yet)
So I guess my question is, should the above code work or am I missing some fundamental understanding of the JMS flow?
So..I persevered and I got it to work.
The answer is that when I create the session, the transacted attribute in both the client and the MDB had to be set to false:
Session ses = con.createSession(true, Session.AUTO_ACKNOWLEDGE);
had to be changed to:
Session ses = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
for both client and server.
I know why now! I am effectively doing the below which is taken from the Oracle JMS documentation!
If you try to use a request/reply mechanism, whereby you send a message and then try to receive a reply to the sent message in the same transaction, the program will hang, because the send cannot take place until the transaction is committed. The following code fragment illustrates the problem:
// Don’t do this!
outMsg.setJMSReplyTo(replyQueue);
producer.send(outQueue, outMsg);
consumer = session.createConsumer(replyQueue);
inMsg = consumer.receive();
session.commit();

How can I marshal Objects from a Socket without closing it? (JAXB Marshaling from Inputstream via Socket)

I have tried in many different ways to send my xml document over a socket connection between a server and a client without closing the socket after sending (keep the outputstream open, for sending another document). I have found several sites who claimed that it should work, so I tried it in all the ways they sugested, but I did not found a way which works.
(that describes the same what I would like to do: http://jaxb.java.net/guide/Designing_a_client_server_protocol_in_XML.html)
The follwing code works perfectly if I am closing the socket after sending (#code marsh.marshal(element, xsw);), but it stucks on unmarshaling on the server side, if I try to keep the socket open.
Client Side....
public void sendMessage(String message){
JAXBContext jaxbContext;
try {
jaxbContext = JAXBContext.newInstance("cdl.wizard.library");
Marshaller marsh = jaxbContext.createMarshaller();
marsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marsh.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.example.org/WizardShema WizardsSchema.xsd");
ObjectFactory of = new ObjectFactory();
// the Dataset is the root element of the xml document
Dataset set = new Dataset("CONN01", "CONTR", "MCL01#localhost", "SV01#localhost:32000");
CommandSet cmdSet = new CommandSet();
Command cmd = new Command();
cmd.setFunctionName("RegisterAs");
Param p = new Param();
p.setString("RemoteClient");
cmd.addParameter(p);
cmdSet.addCommand(cmd);
set.setInstruction(cmdSet);
// creates a valid xml dataset, with startDocument, startElement...
JAXBElement<Dataset> element = of.createData(set);
XMLStreamWriter xsw = XMLOutputFactory.newInstance().createXMLStreamWriter(mOOS);
marsh.marshal(element, xsw);
xsw.flush();
} catch (JAXBException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (FactoryConfigurationError e) {
e.printStackTrace();
}
SERVER Side....
private void handleMessage() {
JAXBContext jaxbContext;
try {
jaxbContext = JAXBContext.newInstance("cdl.wizard.library") ;
Unmarshaller um = jaxbContext.createUnmarshaller();
XMLInputFactory xmlif = XMLInputFactory.newInstance();
// XMLEventReader xmlr = xmlif.createXMLEventReader(mOIS);
XMLStreamReader xmlr = xmlif.createXMLStreamReader(mOIS, "UTF8");
// move to the root element and check its name.
xmlr.nextTag();
System.out.println("TagName:" + xmlr.getLocalName());
xmlr.require(START_ELEMENT, null, "Data");
JAXBElement<Dataset> obj = um.unmarshal(xmlr, Dataset.class);
Dataset set = obj.getValue();
System.out.println("ID:"+ set.getID());
} catch (JAXBException e) {
e.printStackTrace();
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (FactoryConfigurationError e) {
e.printStackTrace();
}
}

Why I am receiving null in my output?

I want to send a message to my computer from my phone using TCP..My computer is the server and my phone is the client. I am able to send a message from my phone to my computer but in the output, I get null characters ..
I paste my codes below;;
Client ::
public void startApp() {
try {
// establish a socket connection with remote server
streamConnection =
(StreamConnection) Connector.open(connectString);
// create DataOuputStream on top of the socket connection
outputStream = streamConnection.openOutputStream();
dataOutputStream = new DataOutputStream(outputStream);
// send the HTTP request
dataOutputStream.writeChars("Hello");
dataOutputStream.flush();
// create DataInputStream on top of the socket connection
inputStream = streamConnection.openInputStream();
dataInputStream = new DataInputStream(inputStream);
// retrieve the contents of the requested page from Web server
String test="";
int inputChar;
System.out.println("Entering read...........");
while ( (inputChar = dataInputStream.read()) != -1) {
// test=test+((char)inputShar);
results.append((char) inputChar);
}
System.out.println("Leaving read...........");
// display the page contents on the phone screen
//System.out.println(" Result are "+results.toString());
System.out.println(" ");
resultField = new StringItem(null, results.toString());
System.out.println("Client says "+resultField);
resultScreen.append(resultField);
myDisplay.setCurrent(resultScreen);
} catch (IOException e) {
System.err.println("Exception caught:" + e);
} finally {
// free up I/O streams and close the socket connection
try {
if (dataInputStream != null)
dataInputStream.close();
} catch (Exception ignored) {}
try {
if (dataOutputStream != null)
dataOutputStream.close();
} catch (Exception ignored) {}
try {
if (outputStream != null)
outputStream.close();
} catch (Exception ignored) {}
try {
if (inputStream != null)
inputStream.close();
} catch (Exception ignored) {}
try {
if (streamConnection != null)
streamConnection.close();
} catch (Exception ignored) {}
}
}
My server :
public class Main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
try{
ServerSocket sck=new ServerSocket(880);
Socket client=sck.accept();
InputStream inp= client.getInputStream();
int i;
OutputStream out=client.getOutputStream();
out.write("Testing ".getBytes());
System.out.println("Server has responded ");
String str="";
while((i=inp.read())!=-1){
str=str+((char) i);
System.out.println("USer says "+ str);
}
}
catch(Exception e){
System.out.println("Error "+e);
}
}
}
My output for the server ;;
Server has responded
USer says null H
User says null H null
User says null H null e
etc etc
I am not supposed to get this null character,why I am getting it??
Another thing, my server is writing to the stream but the client is not able to receive that,why is that?Do I need to use a separate thread for that?
Thanks in adv
I would guess that isn't your real code, and that your real code initialized str to null.

linking my applet to a server dirctory to recieve or save a file from there?

I' m looking for a code to save the files created in a applet normally text files i want to save them on a server directory how can i do so.
Here is an example of how to send a String. In fact any Object can be sent this method so long as it's serializable and the same version of the Object exists on both the applet and the servlet.
To send from the applet
public void sendSomeString(String someString) {
ObjectOutputStream request = null;
try {
URL servletURL = new URL(getCodeBase().getProtocol(),
getCodeBase().getHost(),
getCodeBase().getPort(),
"/servletName");
// open the connection
URLConnection con = servletURL.openConnection();
con.setDoOutput(true);
con.setUseCaches(false);
con.setRequestProperty("Content-Type", "application/octet-stream");
// send the data
request =
new ObjectOutputStream(
new BufferedOutputStream(con.getOutputStream()));
request.writeObject(someString);
request.flush();
// performs the connection
new ObjectInputStream(new BufferedInputStream(con.getInputStream()));
} catch (Exception e) {
System.err.println("" + e);
} finally {
if (request != null) {
try {
request.close();
} catch (Exception e) {
System.err.println("" + e);
};
}
}
}
To retrieve on the server side
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response) {
try {
// get the input stream
ObjectInputStream inputStream = new ObjectInputStream(
new BufferedInputStream(request.getInputStream()));
String someString = (String)inputStream.readObject();
ObjectOutputStream oos = new ObjectOutputStream(
new BufferedOutputStream(response.getOutputStream()));
oos.flush();
// handle someString....
} catch (SocketException e) {
// ignored, occurs when connection is terminated
} catch (IOException e) {
// ignored, occurs when connection is terminated
} catch (Exception e) {
log.error("Exception", e);
}
}
No one is going to hand you this on a plate. You have to write code in your applet to make a socket connection back to your server and send the data. One way to approach this is to push the data via HTTP, and use a library such as commons-httpclient. That requires your server to handle the appropriate HTTP verb.
There are many other options, and the right one will depend on the fine details of the problem you are trying to solve.