SOLVED
I found the answer from IBM Technote IZ66146
Hope it helps others with same problem.
I wrote a simple method to a read messages from an MQ Queue.
In a loop, I try to read a message (with waitInterval). After reading a message successfully from the queue, a 2195 return code is returned. How can I resolve this?
Here is simplified version of my code without exception handling or any other thing.
public static void main(String args[]) {
MQException.logExclude(MQException.MQRC_NO_MSG_AVAILABLE);
MQException.logExclude(MQException.MQRC_UNEXPECTED_ERROR);
MQException.log = null;
while (true) {
incomeDeployMsg = readFromQueue(waitReadInterval);
System.out.println(dateFormater.format(new Date()) + " Income msg");
}
}
public String readFromQueue(int waitInterval) throws MQException{
MQMessage message = new MQMessage();
try {
if (m_inQueue == null || !m_inQueue.isOpen())
m_inQueue = m_mqQmgr.accessQueue(m_inQueueName, CMQC.MQOO_INQUIRE + CMQC.MQOO_FAIL_IF_QUIESCING + CMQC.MQOO_INPUT_SHARED);
message.messageId = CMQC.MQMI_NONE;
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = CMQC.MQGMO_WAIT;
gmo.waitInterval = waitInterval;
m_inQueue.get(message, gmo);
return message.readStringOfCharLength(message.getMessageLength());
} catch (MQException mqe) {
throw mqe;
} finally {
message.clearMessage();
}
}
The first line in the result is not from my code!!! I think it is IBM's classes that print it out on standard output. How can I resolve the error?
Result:
MQJE001: Completion Code '2', Reason '2195'.
2013-05-15 11:44:27 Income msg
Comment out the 2 lines with MQException.logExclude() and just use:
MQException.log = null;
If you don't want this, then in your catch block, check if the exception's reason code is 2195 and write the code accordingly.
Like:
catch (MQException mqe) {
if(mqe.reasonCode==2195)
{
/* DO NOTHING FOR THIS ERROR */
}
else
{
throw mqe;
}
}
I have face the problem, even I set
MQException.log = null;
It still printed out "MQJE001: Completion Code '2', Reason '2195'. "
End up i found out, the line is printed from MQDataException.
Added below line to solve the issue.
MQDataException.log = null;
Related
Every line of code is executed -> Event -> Important Java code lines skipped
# Client-Server # AssumeNoCodeOptimization # IDE:Processing (Processing.org by MIT)
There is a Thread "ConnectionHandler" that stays in a loop where it either sends or receives data. Before it receives the first data, every line of code is executed. After that, the program seems to pause at a System.out.println()!?
Then, when more data arrive, certain lines of Java Code are executed again, but the very same System.out.println() - in addition other things - I mentioned before is skipped.
The very problem is actually that a method sendOutput() is skipped. This is what really grinds my gears. Please help.
I am programming in an environment called Processing, developed by the MIT. As far as I know it only wraps more Java code arround your code.
Below the following code snippets I will explain why I think that code optimization by JIT or AOT is not the problem (At the end I guess I will be wrong. I hope the opposite because you can not pass System variables to Processing to suppress optimization)
private void runConnectionHandler() {
final BufferedReader inFromClient = getBufferedReader(socket);
final DataOutputStream dataOutputStream = getDataOutputStream(socket);
while (true) {
getInput(inFromClient);
sendOutput(dataOutputStream);
System.out.println("Cycle ends");
}
}
private void getInput(final BufferedReader input) {
System.out.println("Get");
try {
String clientSentence = null;
if (input.ready()) {
while ((clientSentence = input.readLine()) != null) {
inputQueue.add(new GameData(clientSentence));
System.out.println("Received se: \"" + clientSentence + "\"");
System.out.println("1");
}
System.out.println("2");
}
System.out.println("3");
}
catch (final Exception e) {
e.printStackTrace();
}
}
private void sendOutput(final DataOutputStream dataOutputStream) {
System.out.println("Send");
while (outputQueue.peek() != null) {
try {
String out = outputQueue.poll().toString();
dataOutputStream.writeBytes(out + "\r\n");
dataOutputStream.flush();
System.out.println("Sent \"" + out + "\"");
}
catch (final Exception e) {
e.printStackTrace();
}
}
}
OUTPUT: Before first data:
Having no idea about optimization I would think that it should also come to effect here, but it does not?
...
Get
3
Send
Cycle ends
...
OUTPUT: First data arrive
After the "1" the ouput stops. Why is System.out.println("2"); and so on not executed?! Why does it stop?!?!
...
Get
3
Send
Cycle ends
Get
Received se: "SET PLAY MODE"
1
OUTPUT: Manually sent more data
Gad dayium, I mean where went my System.out.println("Get"); and everything?!
...
Get
Received se: "SET PLAY MODE"
1
Received se: "Hey Ho1"
1
OUTPUT: Server shuts down
When I shut down the other side (Server), every line of code is executed again ?!?! Futhermore neither it stops, nor an execution is thrown (But maybe different issue).
...
Get
3
Send
Cycle ends
...
Also if my concept is deeply broken I would appreciate a lot of hints.
public static void main() {
String fileName = "cardNumbers.txt";
String line = null;
try {
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
while((line = bufferedReader.readLine()) != null)
{
CreditCard card = new CreditCard(line);
if (card.creditCardType().equalsIgnoreCase("Unknown"))
{
System.out.println("Card number " + card.getCardNumber() + "is an unknown credit card type.");
}
else if (card.isValid())
{
System.out.println(card.creditCardType() + " number" + card.getCardNumber() + " is valid.");
}
else if (!card.isValid())
{
System.out.println(card.creditCardType() + " number " + card.getCardNumber() + " is not valid.");
}
}
}
catch (FileNotFoundException ex)
{
System.out.println("file not found exception thrown");
}
catch (IOException ex)
{
System.out.println("error while reading the file");
}
finally
{
System.exit(0);
}
}
When I run this method it just says ProcessCardNumbers.main(); VM Terminated. Instead of actually printing out the content.
If I add a print at the very start of the function or in the finally block, they are printed.
Im not sure why this is happening or how I can fix it.
As you told us that:
Adding a println at the start is printed
and
Adding a println in the finally works too
we can deduce that your code is working. It's just that when you reach while((line = bufferedReader.readLine()) != null), line stays null, so you never enter your while.
Why is that? Well, your file may be empty to begin with. If it is not, double-check the encoding of your file: it may not be using the proper returns symbols, hence not having a "completed line".
This seems that in your text file cardNumbers.txt has no data. When this program will execute within while loop bufferedReader.readLine()). will return null. So loop will terminate. After termination you have written System.exit(0); function in finally block which terminate JVM on the spot. So JVM is terminated now that's why you are not able to see anything after working of this code.
If you want to check working, write one SOP statement in finally block. Probably that will execute without termination of JVM.
The problem here is not the bug in your code but the design problem that does not let you see the bug.
You are probably getting an undeclared exception (RuntimeException) and the VM can't print it because you kill it before in the finally.
You have several options:
Remove the System.exit(0); and let it die normally. This may fail if there is another non-daemon thread running. You may try to stop it. You can, for example, cancel a Timer.
Add a catch (RuntimeException e) { section before the finally and print the captured error. e.printStackTrace(); should do the trick.
With any of those you should see the exception on console so you can fix it.
Your main method signature must look like this:
public static void main(String[] args)
instead of
public static void main()
I am getting the following exception while getting a message from MQ local queue.this is my code for connection.after running the code i am getting following exception
MQJE001: An MQException occurred: Completion Code 2, Reason 2009
MQJE016: MQ queue manager closed channel immediately during connect
Closure reason = 2009
MQJE001: An MQException occurred: Completion Code 2, Reason 2009
MQJE016: MQ queue manager closed channel immediately during connect
Closure reason = 2009
com.ibm.mq.MQException: MQJE001: An MQException occurred:
Completion Code 2, Reason 2009
MQJE016: MQ queue manager closed channel immediately during connect
Closure reason = 2009
Here is my code
public class Demo {
private MQQueueManager _queueManager = null;
public int port = 1422;
public String hostname = "192.168.1.5";//IP OF HOST
public String channel = "QM_ORANGE.QM_APPLE";//channel name
public String qManager = "QM_ORANGE";//queue manager name
public String inputQName = "Q1";//remote q type
public String outputQName = "QM_APPLE";//queue manager
public Demo() {
super();
}
private void init(String[] args) throws IllegalArgumentException {
// Set up MQ environment
MQEnvironment.hostname = hostname;
MQEnvironment.channel = channel;
MQEnvironment.port = port;
}
public static void main(String[] args) {
Demo readQ = new Demo();
try {
readQ.init(args);
readQ.selectQMgr();
readQ.read();
readQ.write();
} catch (IllegalArgumentException e) {
System.out
.println("Usage: java MQRead <-h host> <-p port> <-c channel> <-m QueueManagerName> <-q QueueName>");
System.exit(1);
} catch (MQException e) {
System.out.println(e);
System.exit(1);
}
}
private void read() throws MQException {
int openOptions = MQC.MQOO_INQUIRE + MQC.MQOO_FAIL_IF_QUIESCING
+ MQC.MQOO_INPUT_SHARED;
MQQueue queue = _queueManager.accessQueue(inputQName, openOptions,
null, // default q manager
null, // no dynamic q name
null); // no alternate user id
System.out.println("MQRead v1.0 connected.\n");
int depth = queue.getCurrentDepth();
System.out.println("Current depth: " + depth + "\n");
if (depth == 0) {
return;
}
MQGetMessageOptions getOptions = new MQGetMessageOptions();
getOptions.options = MQC.MQGMO_NO_WAIT + MQC.MQGMO_FAIL_IF_QUIESCING
+ MQC.MQGMO_CONVERT;
while (true) {
MQMessage message = new MQMessage();
try {
queue.get(message, getOptions);
byte[] b = new byte[message.getMessageLength()];
message.readFully(b);
System.out.println(new String(b));
message.clearMessage();
} catch (IOException e) {
System.out.println("IOException during GET: " + e.getMessage());
break;
} catch (MQException e) {
if (e.completionCode == 2
&& e.reasonCode == MQException.MQRC_NO_MSG_AVAILABLE) {
if (depth > 0) {
System.out.println("All messages read.");
}
} else {
System.out.println("GET Exception: "+e);
}
break;
}
}
queue.close();
_queueManager.disconnect();
}
private void selectQMgr() throws MQException {
_queueManager = new MQQueueManager(qManager);
}
private void write() throws MQException {
int lineNum = 0;
int openOptions = MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING;
try {
MQQueue queue = _queueManager.accessQueue(outputQName, openOptions,
null, // default q manager
null, // no dynamic q name
null); // no alternate user id
DataInputStream input = new DataInputStream(System.in);
System.out.println("MQWrite v1.0 connected");
System.out.println("and ready for input, terminate with ^Z\n\n");
// Define a simple MQ message, and write some text in UTF format..
MQMessage sendmsg = new MQMessage();
sendmsg.format = MQC.MQFMT_STRING;
sendmsg.feedback = MQC.MQFB_NONE;
sendmsg.messageType = MQC.MQMT_DATAGRAM;
sendmsg.replyToQueueName = "ROGER.QUEUE";
sendmsg.replyToQueueManagerName = qManager;
MQPutMessageOptions pmo = new MQPutMessageOptions(); // accept the
// defaults,
// same
// as MQPMO_DEFAULT constant
String line = "test message";
sendmsg.clearMessage();
sendmsg.messageId = MQC.MQMI_NONE;
sendmsg.correlationId = MQC.MQCI_NONE;
sendmsg.writeString(line);
// put the message on the queue
queue.put(sendmsg, pmo);
System.out.println(++lineNum + ": " + line);
queue.close();
_queueManager.disconnect();
} catch (com.ibm.mq.MQException mqex) {
System.out.println(mqex);
} catch (java.io.IOException ioex) {
System.out.println("An MQ IO error occurred : " + ioex);
}
}
}
The commentors are correct that based on the naming that looks like an MCA channel and not an MQI channel. However, when I test a client connection to a RCVR channel I get back 2539=MQRC_CHANNEL_CONFIG_ERROR.
On the other hand, there are many causes for a 2009 when using clients connecting to MQI channels. Almost all of them show up in the QMgr's error logs so if the question is "How to solve 2009?" the answer is "By recreating the error and immediately looking in the QMgr's AMQERR01.LOG file."
Some possibilities include...
Closed by an exit.
Closed by CONNAUTH.
QMgr resource error.
Channel has been configuration-locked.
Many MQ development issues can only be resolved by looking at the diagnostic messages produced at the queue manager. Among other reasons, limiting the information that can leak to an attacker is part of the security design. It's OK for the MQ Admin to know the details but the attacker is supposed to get back a rather vague result. In a legitimate app development environment the developers are expected to have access to the QMgr diagnostics that an attacker would not. So go get the error log.
If for some reason you are unable to convince the MQ Admins to provide the log data or it is otherwise inaccessible, you can set up your own fully functional, fully licensed, free MQ server on your desktop. Information on how to download MQ Advanced for Developers is available from the ibm-mq tag wiki. (Hover over the tag and click 'info' from the fly-out dialog to go there.)
You can also watch No-Cost, Fully Licensed IBM MQ Sandbox which is a video tutorial explaining how to create a dedicated Red Hat virtual machine with MQ Advanced for Developers, using all free and fully licensed software, including where to go to obtain the virtualization software and Red Hat OS.
Once you have that set up, create a QMgr configured like your Integration Test QMgr recreate the error and check the logs. If you connect OK and can't recreate the error at least you can go back to the MQ Admins knowing it's not your code that's the problem.
I want my program exceptions to be sent to each of the following, preferably simultaneously:
the console which starts it (not necessarily)
a gui
a txt file.
How can I achieve this?
My attempts:
System.setErr(PrintStream err) will forward all exceptions to a new stream. I am not able to state more than
one stream though.
Calling System.setErr(PrintStream err) on a manually written OutputStream:
"You can write your own stream class that forwards to multiple streams and call System.setOut on an instance of that class" – Jeffrey Bosboom
I found a way to do this. It is very nasty though. It "collects" PrintStream's write-bytes, puts them in a puffer (500 ms timeout) and finally shows it to the user (Proceed):
/* ErrorOutput.java */
public static t_ErrBuffer t_activeErrBuffer = new t_ErrBuffer("");
public static void setStdErrToFile(final File file) {
ps = new PrintStream(fos) {
#Override
public void write(byte[] buf, int off, int len) {
byte[] bn = new byte[len];
for (int i = off, j = 0; i < (len + off); i++, j++) {
bn[j] = buf[i];
}
String msg = null;
try {
msg = new String(bn, "UTF-8");
} catch (UnsupportedEncodingException e1) {}
if (msg.matches("[\\w\\W]*[\\w]+[\\w\\W]*")) { // ^= contains at least one word character
if( ! t_activeErrBuffer.isAlive() ) {
t_activeErrBuffer = new t_ErrBuffer(msg);
t_activeErrBuffer.start();
} else {
t_activeErrBuffer.interrupt();
t_activeErrBuffer = new t_ErrBuffer(t_activeErrBuffer.getErrBuffer() + "\n" + msg); // ^= append to buffer and restart.
t_activeErrBuffer.start();
}
}
}
};
System.setErr(ps);
}
/* t_ErrBuffer.java */
public class t_ErrBuffer extends Thread {
private String errBuffer;
public t_ErrBuffer(String buffer) {
this.errBuffer = buffer;
}
protected class Proceed implements Runnable {
public String msg = null;
public Proceed(String msg) {
this.msg = msg;
}
#Override
public void run() {
// todo PRINT ERROR MESSAGE: DO THINGS WITH msg: console, gui, JOptionPane
}
}
#Override
public void run() {
try {
Thread.sleep(500); // collect error lines before output. Needed because PrintStream's "write"-method writes ErrorMessages in multiple pieces (lines)
// each time some new exception line comes in, the thread is stopped, buffer is being appended and thread new started
} catch (InterruptedException e) {
return; // stop
}
// after 500 ms of wait, no new error message line has come in. Print the message out:
Thread t_tmp = new Thread(new Proceed("\n" + this.errBuffer));
t_tmp.start();
return;
}
public String getErrBuffer() {
return this.errBuffer;
}
}
is this what I am expected to do?
Create new exception class which does it for me. Would probably work, but other exceptions than that (IO, FileNotFound, ...) will still be treated the old way
Instead of stating [method name] throws Exception I could enclose all of my code in try/catch-blocks, get the exception and forward it to a method of mine, like this:
/* AnyMethod.java */
// ...
try {
// ... do everything here
} catch (IOException | FileNotFoundException e) { // as many as you like
ErrorOutput.crash(e);
}
// ...
/* ErrorOutput.java */
public static void crash(Exception e) {
FileOutputStream fos_errOutput = new FileOutputStream(new File("ErrorOutput.txt"), true);
// 1st
if (!System.out.equals(fos_errOutput)) {
System.out.println(e.getMessage() + " :"); // to console or the preferred StdOut
e.printStackTrace();
}
// 2nd
JOptionPane.showMessageDialog(Gui.frame, "THE PROGRAM HAS CRASHED!" + "\n\n" + e.getMessage() + "\n\nFor a more detailed report, see ErrorLog.txt"); // gui output
// 3rd
PrintStream ps = new PrintStream(fos_errOutput);
ps.print(new Date().toString() + ":"); // write to file
e.printStackTrace(ps);
ps.close();
// 4th
System.exit(0); // this could also be "throw new Exception" etc., but I don't know why one should do that.
}
this would probably also work, but I'd have to put everything into try/catch-blocks. This cannot be good programming style at all.
Using a logger:
"use log4j and set up a method to write to GUI and also to log to
stdout, and file" – Scary Wombat
Loggers only help me printing my exceptions into desired streams, but they don't help me catching them, right?
But you really should use a logging package for this -- even java.util.logging can do what you need – Jeffrey Bosboom
I have to tell my logging package where and what to log. But this is exactly what I am searching for.
I now can, as user3159253 suggested, use Thread.UncaughtExceptionHandler to catch unhandled exceptions specifically.
What is the right way to handle all thrown exceptions the way I want them to? What else do I have to consider apart from Thread.UncaughtExceptionHandler and System.setErr()(see above)?
First you need get hold of all exception instances thrown from/within your thread (may be try/catch or Thread.UncoughtExceptionHandler or ThreadPoolExecutor.afterExecute(Runnable r, Throwable t)).
Then once you have the exception instance you can simply log it using log4j but configure Log4j appenders to send your exception messages to multiple destinations. You can use File, Console, JDBC, JMS etc types of appenders depending upon your requirement. Also it is best to wrap them with Async appender.
Refer - https://logging.apache.org/log4j/2.x/manual/appenders.html
About pushing the exception message to GUI, it can be implemented in various ways depending upon what tech stack your are using in your application. In our application we are storing the message events (only critical ones) in database which are then picked by event monitoring threads from server and then pushed back to GUI (JQuery, JavaScript) using http://cometd.org/documentation/cometd-java.
Creating an object that extends PrintStream should work. Whenever it receives a line, it can display it and log it as required. Alternatively, all exceptions can be caught and redirected into a method that receives an Exception as a parameter, and the method can take care of logging/displaying the exception, and terminating the program cleanly.
I'm getting the following error message and I can't seem to figure out the problem. Would really appreciate any help. The error message reads as:-
BaseStaInstance.java:68: cannot find symbol
symbol : constructor StringTokenizer(java.lang.Object,java.lang.String)
location: class java.util.StringTokenizer
st = new StringTokenizer(buf,",");
^
Here, BaseStaInstance is my main public class.
The class that implements this StringTokenizer is as follows:-
class ServerConnect extends Thread {
Socket skt;
int iProcessId, iInProcessId;
int iOwnTimeStamp, iInTimeStamp;
ServerConnect scnt = null;
ObjectOutputStream myOutput;
ObjectInputStream myInput;
ServerConnect(){}
ServerConnect(Socket connection, int iProcessNo) {
this.skt = connection;
this.iProcessId = iProcessNo;
}
public void run() {
try {
//initialize the object "scnt" using the parameterized constructor
ServerConnect scnt = new ServerConnect(skt, iProcessId);
myInput = new ObjectInputStream(skt.getInputStream());
while(true) {
try{
iOwnTimeStamp = Global.iTimeStamp;
Object buf = myInput.readObject();
//if we got input, print it out and write a message back to the remote client...
if(buf != null){
scnt.replyChoice(buf);
}
}catch(ClassNotFoundException e) {
e.printStackTrace();
}
}
} catch(IOException e) {
e.printStackTrace();
}
}
void replyChoice(Object buf){
try{
String sDeferReply = "";
myOutput = new ObjectOutputStream(skt.getOutputStream());
//the place where the basestation reads the request from the other basestation
System.out.println("Server read:[ "+buf+" ]");
//extract out the process id and the timestamp from the incoming request
buf = buf.toString();
***StringTokenizer st = new StringTokenizer(buf,",");***
//skip the word request
st.nextToken();
iInProcessId = Integer.parseInt(st.nextToken());
iInTimeStamp = Integer.parseInt(st.nextToken());
//check request is made
//there is a possibility of entering the else loop only on the very first iteration
//the control flows into the if loop even if one request has been made
if(iOwnTimeStamp != 0){
//if the incoming request has a larger timestamp (logical clock value, process id) than the current process, we defer the reply
if(iOwnTimeStamp < iInTimeStamp || iProcessId < iInProcessId){
sDeferReply="iInTimeStamp"+","+"iInProcessId";
Global.v.addElement(new String(sDeferReply));
}
//incoming request has a smaller timestamp than the basestation request itself
else{
myOutput.writeObject("Reply");
myOutput.flush();
}
}
//if the current process is in the critical section then we defer replies
else if(Global.iCriticalSection==1){
sDeferReply="iInTimeStamp"+","+"iInProcessId";
Global.v.addElement(new String(sDeferReply));
}
//start of execution of the thread, there is a possibility that the basestation hasn't issued a request
else{
myOutput.writeObject("Reply");
myOutput.flush();
}
}catch(IOException e){
e.printStackTrace();
}
}
}
The part that implements the StringTokenizer function has *** surrounding it.
Thanks in advance to anyone who might be able to help me out.
Try
StringTokenizer st = new StringTokenizer((String) buf,",");
The reason why you're getting that error is because buf, while referring to a String at that point, is still of type Object.
As an additional tip, you really should make the effort to try to understand the error message given by the compiler. Look at the following:
cannot find symbol constructor StringTokenizer(java.lang.Object,java.lang.String)
location: class java.util.StringTokenizer st = new StringTokenizer(buf,",");
Compiler error messages don't always make sense, but this is as good as it gets. It tells you that:
It found the right type, java.util.StringTokenizer, so it's not an import or name obscuring problem, etc.
It's telling you that a specific method with the given signature can not be found. Indeed, a quick check with the API confirms that StringTokenizer does NOT have a constructor that takes a (java.lang.Object, java.lang.String).
It's telling you exactly the line of code in your program that tries to invoke this non-existent method. And indeed, the type of your first argument is a java.lang.Object, and the type of your second argument is a java.lang.String!!!
That was how I was able to quickly pinpoint the problem in the source code and suggest a quick fix.
Being able to process error messages given by the compiler is an essential skill that you must develop, so I hope this proves to be an educational experience for you.