ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » IBM MQ API Support » XMS .net Exception Listener Not Firing - Please Help

Post new topic  Reply to topic Goto page 1, 2  Next
 XMS .net Exception Listener Not Firing - Please Help « View previous topic :: View next topic » 
Author Message
pdclark
PostPosted: Thu Aug 29, 2013 8:18 am    Post subject: XMS .net Exception Listener Not Firing - Please Help Reply with quote

Novice

Joined: 29 Aug 2013
Posts: 11

For the last week I have been trying to get an exception thrown using XMS for .net. I am successfully connecting to and receiving messages from the server, however, when I physically break the connection (pull the Ethernet cable) no exception is thrown.

The trace logs actually stop writing during the time the cable is pulled so they are of no help.

I tried WMQ_CM_CLIENT_UNMANAGED as suggested on several forums but still no exception.

Could someone please point me in the right direction as I need to start receiving message, but don't want to go live till I can handle exceptions.

Thank You
Pat C






Code:


    Private Sub OnQ1Exception(ex As IBM.XMS.IExceptionDetail)

        Console.WriteLine("We got Q2 error : " & DirectCast(ex, IBM.XMS.IExceptionDetail).Explanation)
        ' Terminate the current process
        'Environment.[Exit](1)
        KillConnection2()
        System.Threading.Thread.Sleep(10000)
        ReceiveQ1Messages()

    End Sub

    Dim aQ As String = "Q1"

        connectionFactory.SetStringProperty(IBM.XMS.XMSC.WMQ_HOST_NAME, aQ)
        connectionFactory.SetStringProperty(IBM.XMS.XMSC.WMQ_CHANNEL, "***.SVRCONN")
        connectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_PORT, ****)
        connectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_BROKER_VERSION, IBM.XMS.XMSC.WMQ_BROKER_V2)
        connectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_CONNECTION_MODE, IBM.XMS.XMSC.WMQ_CM_CLIENT)
        'seconds
        connectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_CLIENT_RECONNECT_TIMEOUT, 15)

        'XMSC_ASYNC_EXCEPTIONS_ALL XMSC_ASYNC_EXCEPTIONS
        connection = connectionFactory.CreateConnection()


        Dim exListener As New IBM.XMS.ExceptionListener(AddressOf OnQ1Exception)
        connection.ExceptionListener = exListener

        session = connection.CreateSession(False, IBM.XMS.AcknowledgeMode.AutoAcknowledge)

        destination = session.CreateQueue("APA.UPDATE.SEQUENCE")
        consumer = session.CreateConsumer(destination)

        Console.WriteLine("Waiting for messages on Q1...")

        ' Create and register the listener
        Dim messageListener As New IBM.XMS.MessageListener(AddressOf OnQ1MessageCallback)
        consumer.MessageListener = messageListener
        ' Start the connection
        connection.Start()


Last edited by pdclark on Thu Aug 29, 2013 6:45 pm; edited 2 times in total
Back to top
View user's profile Send private message
pdclark
PostPosted: Thu Aug 29, 2013 6:33 pm    Post subject: Reply with quote

Novice

Joined: 29 Aug 2013
Posts: 11

Well to help others:

It turns out it was a very simple, innocuous error that prevented the exception throwing.

The MessageListener and ExceptionListener methods work in much the same way with ONE minor exception – the delegate definition.

The definition for the MessageListener handler is :
Code:

MessageListener(IMessage someMessage)

while the ExceptionListener is :
Code:
 ExceptionListener(Exception someException)

In my code I defined –
Code:

OnNewMessage(someMessage As IBM.XMS.IMessage)
and
OnException(someException As IBM.XMS.IExceptionDetail)

The damn someException parameter is defined as an Exception NOT an IExeptionDetail.

MQ was actually throwing the exception, but the call to the handler was failing because the parameter could not be cast as an IExceptionDetail. The exception handler wasn’t firing because there was an exception to the exception handler! When using managed code the exception to the exception was not being written to the trace logs, so the first few dozen times I looked I couldn’t find it. Well, after setting the unmanaged code flag, I found it in the trace logs.

It does take 5 minutes or so to fire the exception (couldn’t find a timeout property anywhere) after breaking a connection, but it does now successfully fire.
Back to top
View user's profile Send private message
Vitor
PostPosted: Fri Aug 30, 2013 4:55 am    Post subject: Reply with quote

Grand High Poobah

Joined: 11 Nov 2005
Posts: 26093
Location: Texas, USA

pdclark wrote:
Well to help others:

It turns out it was a very simple, innocuous error that prevented the exception throwing.


We thank you for posting this.

pdclark wrote:
It does take 5 minutes or so to fire the exception (couldn’t find a timeout property anywhere)


Someone who knows more about .NET than I do will be along in a minute.
_________________
Honesty is the best policy.
Insanity is the best defence.
Back to top
View user's profile Send private message
pdclark
PostPosted: Fri Aug 30, 2013 9:34 am    Post subject: Reply with quote

Novice

Joined: 29 Aug 2013
Posts: 11

Vitor wrote:
pdclark wrote:
Well to help others:

It turns out it was a very simple, innocuous error that prevented the exception throwing.


We thank you for posting this.

pdclark wrote:
It does take 5 minutes or so to fire the exception (couldn’t find a timeout property anywhere)


Someone who knows more about .NET than I do will be along in a minute.


Thanks.

Here's another question.
Now that I have the exception firing if I enable:
Code:

connectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_CLIENT_RECONNECT_OPTIONS, IBM.XMS.XMSC.WMQ_CLIENT_RECONNECT_Q_MGR)
      connectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_CLIENT_RECONNECT_TIMEOUT, 150)



the Message Listener never restarts.
I have to kill the connection & restart manually in the exception handler.

Could someone explain how to implement an automatic reconnection?

Thanks
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Fri Aug 30, 2013 12:27 pm    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20696
Location: LI,NY

Is your exception listener trying to "start" the connection?
What is the state of the new connection after reconnect?...
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
pdclark
PostPosted: Fri Aug 30, 2013 3:36 pm    Post subject: Reply with quote

Novice

Joined: 29 Aug 2013
Posts: 11

Thank you for taking the time to reply. I am currently handling the re-connection in Exception method. My thinking was I could avoid the call to Kill Connection & RecieveMessages entirely by enabling:
Code:

       'connectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_CLIENT_RECONNECT_OPTIONS, IBM.XMS.XMSC.WMQ_CLIENT_RECONNECT_Q_MGR)
        'connectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_CLIENT_RECONNECT_TIMEOUT, 150)


But when I pull the plug the exception gets thrown but messages do not resume. It just hangs.

If I include my "Kill" & "RecieveMessages ", everything works great after I put the plug back in.

Here is the complete listing:


Code:



Imports System.Data.SqlClient
Imports System.Transactions
Imports System.Threading

Public Class MqMsgs

    Dim sqlConn As SqlConnection = Nothing
    Dim sqlConnString As [String] = "Data Source=****;Initial Catalog=****;Persist Security Info=True;User ID=****;Password=*****"

    Private aFactory As IBM.XMS.XMSFactoryFactory = IBM.XMS.XMSFactoryFactory.GetInstance(IBM.XMS.XMSC.CT_WMQ)

    Private connectionFactory As IBM.XMS.IConnectionFactory = aFactory.CreateConnectionFactory()
    Private connection As IBM.XMS.IConnection
    Private session As IBM.XMS.ISession
    Private destination As IBM.XMS.IDestination
    Private consumer As IBM.XMS.IMessageConsumer

    Private messagesReceived As Integer = 0
    Private lastPullTime As DateTime = Now
    Private qName As String

    Delegate Sub RtbAppendTextCallback(theText As String, ctrl As RichTextBox, color As Color)
    Private Sub RtbAppendText(ByVal theText As String, ctrl As RichTextBox, color As Color)
        If ctrl.InvokeRequired Then
            Dim d As New RtbAppendTextCallback(AddressOf RtbAppendText)
            Me.Invoke(d, New Object() {theText, ctrl, color})
        Else
            ctrl.SelectionColor = color
            ctrl.SelectedText = theText & vbCrLf
            ctrl.SelectionStart = ctrl.Text.Length
            ctrl.ScrollToCaret()
        End If

    End Sub

    Delegate Sub SetTextCallback(theText As String, ctrl As ToolStripStatusLabel, color As Color)
    Private Sub SetText(ByVal theText As String, ctrl As ToolStripStatusLabel, color As Color)
        If StatusStrip1.InvokeRequired Then
            Dim d As New SetTextCallback(AddressOf SetText)
            Me.Invoke(d, New Object() {theText, ctrl, color})
        Else
            ctrl.ForeColor = color
            ctrl.Text = theText
        End If
    End Sub

    Private Sub OnException(ex As Exception)

        RtbAppendText("We got an error on " & qName & " at " & Now.ToString & vbCrLf & ex.Message & vbCrLf, RichTextBoxStatus, Color.Red)
        RtbAppendText("We got an error on " & qName & " at " & Now.ToString, RichTextBoxMessages, Color.Red)

        For i = 30 To 1 Step -1
            SetText("Exception thrown, will attempt reset on " & qName & " in " & i.ToString & " seconds.", ToolStripStatusLabel1, Color.Red)
            System.Threading.Thread.Sleep(1000)
        Next

        KillConnection()
        ReceiveMessages(qName)

        SetText("Back to listening... ", ToolStripStatusLabel1, Color.Blue)

    End Sub

    Private Sub OnNewMessageCallback(message As IBM.XMS.IMessage)
        ' The try block below is unlikely to throw a runtime exception, but as
        ' a general good practice an asynchronous consumer's message listener or
        ' callback should catch a potential runtime exception, and optionally
        ' divert the message in question to an application-specific destination.
        Try
            ' Increment the counter
            messagesReceived += 1

            ' Display received message
            DisplayMessage(message)
            ' Sleep for a while to allow the user to see the output on the screen
            ' System.Threading.Thread.Sleep(500)
        Catch ex As Exception
            RtbAppendText("Exception caught in OnNewMessageCallback: " & ex.Message, RichTextBoxStatus, Color.Red)

            ' We have at least two choices now - (1) re-throw ex. In this case the control
            ' passes back to XMS and which may attempt to redeliver the message, depending
            ' on session's acknowledge mode, or (2) terminate the process. Orthogonally, we
            ' may divert the message to an application-specific destination.

            ' Terminate the current process
            'Environment.[Exit](1)
            'Throw ex

        End Try
    End Sub

    Private Sub KillConnection()
        Try
            If Not IsNothing(consumer) Then
                consumer.Close()
                consumer.Dispose()
            End If
            If Not IsNothing(destination) Then
                destination.Dispose()
            End If
            If Not IsNothing(session) Then
                session.Dispose()
            End If
            If Not IsNothing(connection) Then
                connection.Close()
                connection.Dispose()
            End If

            RtbAppendText("Queue stopped", RichTextBoxStatus, Color.Red)

        Catch ex As Exception
            RtbAppendText(ex.Message, RichTextBoxStatus, Color.Red)

        End Try

    End Sub


    Private Sub ReceiveMessages(q As String)

        sqlConn = New SqlConnection(sqlConnString)
        sqlConn.Open()

        connectionFactory.SetStringProperty(IBM.XMS.XMSC.WMQ_HOST_NAME, q)
        connectionFactory.SetStringProperty(IBM.XMS.XMSC.WMQ_CHANNEL, "****")
        connectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_PORT, 5160)
        connectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_CONNECTION_MODE, IBM.XMS.XMSC.WMQ_CM_CLIENT_UNMANAGED)
        connectionFactory.SetIntProperty(IBM.XMS.XMSC.RTT_BROKER_PING_INTERVAL, 6000)

        'connectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_CLIENT_RECONNECT_OPTIONS, IBM.XMS.XMSC.WMQ_CLIENT_RECONNECT_Q_MGR)
        'connectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_CLIENT_RECONNECT_TIMEOUT, 150)

        connection = connectionFactory.CreateConnection()

        Dim exListener As New IBM.XMS.ExceptionListener(AddressOf OnException)
        connection.ExceptionListener = exListener

        session = connection.CreateSession(False, IBM.XMS.AcknowledgeMode.AutoAcknowledge)

        destination = session.CreateQueue("****")
        consumer = session.CreateConsumer(destination)

        RtbAppendText("Waiting for messages on " & q, RichTextBoxStatus, Color.Blue)

        ' Create and register the listener
        Dim messageListener As New IBM.XMS.MessageListener(AddressOf OnNewMessageCallback)
        consumer.MessageListener = messageListener
        ' Start the connection
        connection.Start()

    End Sub


    Private Sub DisplayMessage(msg As IBM.XMS.ITextMessage)
        Dim ms = Now - lastPullTime

        Dim aText = ("Message " & messagesReceived & " received asynchronously on " & qName & " : " & Now.ToString & " : " & ms.ToString)
        RtbAppendText(aText, RichTextBoxMessages, Color.Black)

        Dim JmsMsgId As [String] = msg.JMSMessageID.Substring(3)
        'Insert the received message from MSMQ into a SQL server
        Dim insertCmd As New SqlCommand("INSERT INTO MQMSGS (MSGID, QUEUE, MSGINTIME, MSGBODY) " + "Values ('" + JmsMsgId + "','" + qName + "','" + Now.ToString + "','" + msg.Text + "')", sqlConn)

        ' Execute
        insertCmd.ExecuteNonQuery()
        'Thread.Sleep(500)
        lastPullTime = Now
    End Sub



    Private Sub ButtonKillQ1_Click(sender As Object, e As EventArgs) Handles ButtonKillQ1.Click
        KillConnection()
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ReceiveMessages(qName)
    End Sub


End Class

Back to top
View user's profile Send private message
pdclark
PostPosted: Fri Aug 30, 2013 3:50 pm    Post subject: Reply with quote

Novice

Joined: 29 Aug 2013
Posts: 11

And the result after cable pull, "Kill" & "RecieveMessages" reinsert cable :

Back to top
View user's profile Send private message
pdclark
PostPosted: Sat Aug 31, 2013 5:31 am    Post subject: Apparently I'm not alone Reply with quote

Novice

Joined: 29 Aug 2013
Posts: 11

Well it seems this problem has gone unanswered before. Are there any .net XMS experts here that could jump in?

sijtom0703 wrote:
Hi,

I have an existing XMS .Net client application and I am trying to add the Reconnecting Client feature to it. The client version is
Quote:
Name: WebSphere MQ
Version: 7.0.1.1


Code:
private static IConnectionFactory cf = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ).CreateConnectionFactory();

        public string WMQ_HOST_NAME { set { cf.SetStringProperty(XMSC.WMQ_HOST_NAME, value); } }
        public int WMQ_PORT { set { cf.SetIntProperty(XMSC.WMQ_PORT, value); } }
        public string WMQ_QUEUE_MANAGER { set { cf.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, value); } }
        public string WMQ_CHANNEL { set { cf.SetStringProperty(XMSC.WMQ_CHANNEL, value); } }
public int WMQ_CONNECTION_MODE
        {
            set
            {
                if (value < 0)
                    value = XMSC.WMQ_CM_CLIENT_UNMANAGED;
                cf.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, value);
                //set to non RFH header
                //cf.SetIntProperty(XMSC.WMQ_TARGET_CLIENT, XMSC.WMQ_TARGET_DEST_MQ);
            }
        }



Theoretically will it work with Reconnecting feature if I add the below two lines to this??

Code:
//Adding Client Reconnecting Parameters
        public int WMQ_CLIENT_RECONNECT { set { cf.SetIntProperty(XMSC.WMQ_CLIENT_RECONNECT_OPTIONS, XMSC.WMQ_CLIENT_RECONNECT);} }
        public int WMQ_CLIENT_RECONNECT_TIMEOUT { set { cf.SetIntProperty(XMSC.WMQ_CLIENT_RECONNECT_TIMEOUT, 150);} }
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Sat Aug 31, 2013 6:15 am    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20696
Location: LI,NY

You did not say what other reconnect options were available. You only showed us you used client reconnect... (it might not be the one for the behavior you seek)
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
pdclark
PostPosted: Sat Aug 31, 2013 6:53 am    Post subject: Reply with quote

Novice

Joined: 29 Aug 2013
Posts: 11

fjb_saper wrote:
You did not say what other reconnect options were available. You only showed us you used client reconnect... (it might not be the one for the behavior you seek)


Thank you

If by reconnect options you mean other queues, than I have no other options. This is the only server & q available so I must try to reconnect to it. There are no other fail-over servers.

I'm guessing now that automatic reconnect options relate to attempting to grab a different msg server?
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Sat Aug 31, 2013 7:27 am    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20696
Location: LI,NY

pdclark wrote:
fjb_saper wrote:
You did not say what other reconnect options were available. You only showed us you used client reconnect... (it might not be the one for the behavior you seek)


Thank you

If by reconnect options you mean other queues, than I have no other options. This is the only server & q available so I must try to reconnect to it. There are no other fail-over servers.

I'm guessing now that automatic reconnect options relate to attempting to grab a different msg server?

No with a multi-instance scenario you are supposed to reconnect to the same qmgr. I was thinking to check whether you had the possibility of specifying a server option instead of a client option for client reconnect...
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
pdclark
PostPosted: Sat Aug 31, 2013 8:08 am    Post subject: Reply with quote

Novice

Joined: 29 Aug 2013
Posts: 11

fjb_saper wrote:
pdclark wrote:
fjb_saper wrote:
You did not say what other reconnect options were available. You only showed us you used client reconnect... (it might not be the one for the behavior you seek)


Thank you

If by reconnect options you mean other queues, than I have no other options. This is the only server & q available so I must try to reconnect to it. There are no other fail-over servers.

I'm guessing now that automatic reconnect options relate to attempting to grab a different msg server?

No with a multi-instance scenario you are supposed to reconnect to the same qmgr. I was thinking to check whether you had the possibility of specifying a server option instead of a client option for client reconnect...


Thanks again.

Still not sure I understand what you're saying. At his point I have posted everything I know about the server. It is remote & I have no access to any of its settings. I noticed last night with the code posted above the client must have hung at some point with no exceptions written to the handler.

I know this because the count seemed low so I clicked "Kill" & she started firing off another 1500 or so messages.

I'm considering using straight MQ.

I haven't even attempted launching multiple listening threads which I'll need to do because of the number of messages that will need to be processed.

Not looking forward to that.

Pat


Last edited by pdclark on Sat Aug 31, 2013 6:29 pm; edited 1 time in total
Back to top
View user's profile Send private message
mqjeff
PostPosted: Sun Sep 01, 2013 5:05 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

"It just hangs" may simply mean that you haven't waited long enough according to the timeouts you have specified.
Back to top
View user's profile Send private message
pdclark
PostPosted: Sun Sep 01, 2013 5:15 am    Post subject: Reply with quote

Novice

Joined: 29 Aug 2013
Posts: 11

mqjeff wrote:
"It just hangs" may simply mean that you haven't waited long enough according to the timeouts you have specified.


Thanks. I suspected that as well but the only timeouts specified are whatever the defaults are and:

connectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_CLIENT_RECONNECT_TIMEOUT, 150)

(Is 150 = seconds?)

I have no others defined. I've looked through ALL the XMS properties and can't find those that apply to listening timeouts. Could you please be more specific as to which to set. Or those at the server which I may need to ask the server admin to adjust?
Back to top
View user's profile Send private message
pdclark
PostPosted: Thu Sep 05, 2013 7:43 pm    Post subject: Reply with quote

Novice

Joined: 29 Aug 2013
Posts: 11

FYI :

Wish I had found this earlier.

Decided earlier today to abandon asynchronous comm because no matter what I tried, the app eventually hung. Reworked to run synchronously (using 10 threads) and it's been running smoothly for the last 12 hours.

Then tonight I just found this : http://www-01.ibm.com/support/docview.wss?uid=swg1IC93350

(Summarized below)

We are using -> 7.5.02

The fix pack is v7.5 7.5.0.3 ( Not yet out.)


--------------------------------------------------------------------------------------------------------------------------------
IBM: IC93350: INCORRECT MULTI-THREADED XMS .NET APPLICATION BEHAVIOR WHEN USING ASYNC CALLBACK METHOD FOR RECEIVING MESSAGES.


APAR status

Closed as program error.

Error description WebSphere MQ XMS .NET multi threaded applications behaves
incorrectly when using async callback method for receiving
messages.

For example, if an application is multi-threaded:
Thread #1 will connect to queue manager QM1 and register
QUEUE1 to the callback method Thread1.MyMessageListener1
Thread #2 will connect to queue manager QM1 and register
QUEUE2 to the callback method Thread2.MyMessageListener1
.
Messages posted to QUEUE1 will arrive on the callback method
Thread2.MyMessageListener1 that was registered for QUEUE2.

Local fix - Use sync callback method.

Problem summary
****************************************************************
USERS AFFECTED:
Users of WebSphere MQ multi threaded XMS .Net application
using async callback method to receive messages in unmanaged
mode.


Platforms affected:
Windows

****************************************************************
PROBLEM SUMMARY:
NMQI code was incorrectly handling the register and
de-register operation for message listeners. The registration
and the de-registration of the message callback was not
capable of handling objects from multi threaded environment. The
object that last registered receives all the messages.
Problem conclusion

NMQI code has been modified such that register and de-register
operations for message listeners are handled correctly for a
multi threaded application

---------------------------------------------------------------
The fix is targeted for delivery in the following PTFs:

Version Maintenance Level
v7.1 7.1.0.5
v7.0 7.0.1.12
v7.5 7.5.0.3
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic  Reply to topic Goto page 1, 2  Next Page 1 of 2

MQSeries.net Forum Index » IBM MQ API Support » XMS .net Exception Listener Not Firing - Please Help
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.