Notification not received

Hi all,

I have a class implementing the NotificationEmitter interface which delegates notification management to a NotificationBroadcasterSupport object.

My addNotificationListener method looks like:

publicvoid addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback)throws IllegalArgumentException{

this.broadcaster.addNotificationListener(listener, filter, handback);

Notification n = stateDump();

// Should send n to all registered listeners, included the one which hit this method

this.broadcaster.sendNotification(n);

log.info("sent");

}

The problem is that the notification is never received by NotificationListener objects while if I invoke any method using the MBeanServerConnection it works fine.

Any idea?

Michele

[1055 byte] By [michele81a] at [2007-10-3 9:15:11]
# 1

Hi Michele,

If you are invoking addNotificationListener() through an MBeanServerConnection you

should know that addNotificationListener() will be called *only once* on your MBean,

no matter how often you call addNotificationListener() from remote.

This will happen the first time a remote client (whatever it is - may not even be yours)

calls addNotificationListener() on whatever MBean (might not even be yours) through

an MBeanServerConnection obtained from the same JMXConnectorServer.

In other words, if anybody already registered for whatever notifications with whatever

MBean through the JMXConnectorServer you're using, then addNotificationListener

will not be invoked on your MBean at the time you call addNotificationListener()

from remote.

This is because the JMXConnectorServer and JMXConnectorClients 'conspire' to make

it possible for notifications to reach the remote side. The JMXConnectorServer registers

its own unique NotificationListener with all MBeans, and then does the dispatching to

'remote' listeners internally (I'm simplifying a bit here). The only listener that gets

registered with the MBean is thus the JMXConnectorServer's listener, and it gets

registered only once, the first time a client registers for whatever Notification from

whatever MBean.

If you really want to understand the Notifications mechanism of JMX Remote API,

I suggest that you read the JSR 160 specification (which you can get from

http://www.jcp.org/)

Note that one of the prospective feature for JMX 2.0 (JSR 255) is an event service

that may provide a different behaviour.

The question I would ask is why would you want to send a Notification in

addNotificationListener() in the first place? What is your use case for wanting to

doing this?

best regards,

-- daniel

JMX, SNMP, Java, etc...

http://blogs.sun.com/jmxetc

dfuchsa at 2007-7-15 4:27:48 > top of Java-index,Core,Monitoring & Management...
# 2

Hi Daniel,

thanks for your explanation.

>

> This will happen the first time a remote client

> (whatever it is - may not even be yours)

> calls addNotificationListener() on whatever MBean

> (might not even be yours) through

> an MBeanServerConnection obtained from the same

> JMXConnectorServer.

>

ahhh, I see.

>

> This is because the JMXConnectorServer and

> JMXConnectorClients 'conspire' to make

> it possible for notifications to reach the remote

> side. The JMXConnectorServer registers

> its own unique NotificationListener with all MBeans,

> and then does the dispatching to

> 'remote' listeners internally (I'm simplifying a bit

> here). The only listener that gets

> registered with the MBean is thus the

> JMXConnectorServer's listener, and it gets

> registered only once, the first time a client

> registers for whatever Notification from

> whatever MBean.

>

So, if I well understand, the JMXConnectorServer acts as proxy - that is it receives all notifications from "all" MBeans - and then it'll dispatch each notification to the appropriate NotificationListener object (when I say "all" I mean all the MBeans which have a NotificationListener coming from that JMXConnectorServer).

> If you really want to understand the Notifications

> mechanism of JMX Remote API,

> I suggest that you read the JSR 160 specification

> (which you can get from

> http://www.jcp.org/)

>

Thanks.

> The question I would ask is why would you want to

> send a Notification in

> addNotificationListener() in the first place? What is

> your use case for wanting to

> doing this?

>

I would like to send a mbean snapshot when a new listener registers (actually I would like to send it only to the new listener by modifying the NotificationBroadcasterSupport class). Does it make any sense?

Thanks,

Michele

michele81a at 2007-7-15 4:27:48 > top of Java-index,Core,Monitoring & Management...
# 3

> Hi Daniel,

> So, if I well understand, the JMXConnectorServer acts

> as proxy - that is it receives all notifications from

> "all" MBeans - and then it'll dispatch each

> notification to the appropriate NotificationListener

> object (when I say "all" I mean all the MBeans which

> have a NotificationListener coming from that

> JMXConnectorServer).

Yes - the client listener (= your listener) is in the client JVM - while the

MBeans are in the server JVM - so obviously the Notifications need to be

transmitted from the server side to the client side where the client listener

can be invoked.

The JMXConnectorServer thus acts as a listener proxy. Notifications are

actually pulled from the server by the client - to simplify firewall configuration

issues (avoids to establish a reverse connection). Complex considerations

about client states, garbage collection, and connection handling, have driven

the spec to define a mechanism where the client states stay on the client, and

are only weakly stored on the server side. The JMXConnectorServer will thus

listen to all Notifications in order to be able to return those that match its client

filters when the client pulls Notifications from the server.

> > The question I would ask is why would you want to

> > send a Notification in addNotificationListener() in the first place?

> > What is your use case for wanting to doing this?

> >

> I would like to send a mbean snapshot when a new

> listener registers (actually I would like to send it

> only to the new listener by modifying the

> NotificationBroadcasterSupport class). Does it make

> any sense?

I am afraid there isn't a way to do that from the server side.

The only way I see would be to instantiate your own <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/management/remote/rmi/RMIConnectorServer.html">RMIConnectorServer</a>.

The RMIConnectorServer has a constructor that takes an <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/management/remote/rmi/RMIServer.html">RMIServer</a> as

input. You could possibly provide your own custom subclass of

RMI[<a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/management/remote/rmi/RMIJRMPServerImpl.html">JRMP</a>|<a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/management/remote/rmi/RMIIIOPServerImpl.html">IIOP</a>]ServerImpl, which would return your own subclass of

<a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/management/remote/rmi/RMIConnectionImpl.html">RMIConnectionImpl</a>, in which you could "trap"

<a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/management/remote/rmi/RMIConnectionImpl.html#addNotificationListeners(javax.management.ObjectName[],%20java.rmi.MarshalledObject[],%20javax.security.auth.Subject[])">addNotificationListeners(ObjectName[] ....)</a> requests made by the remote client

side. However generating a Notification from there wouldn't be easy. You would

have to recognize that your MBean is one of the MBeans named in the

ObjectName[] array, and somehow call a method on that MBean so that it

generates the Notifications. And even so it would be impossible to send the

notification only to the new listener. All listeners that had registered with your

MBean would get it. So my advice is: <b>stay away from this</b>.

What you could do instead is modify your MBean by adding a getSnapshot()

method that returns the snap shot, (or alternatively use getMBeanInfo()+

getAttributes()) and call this method from the client side.

If you still want to use Notifications to transmit the snapshot, you could add some

logic to fake the emission of such a notification on the client side.

You could add that logic either by wrapping the MBeanServerConnection returned

by your JMXConnector, or if your client uses proxies, you could possibly embed that

logic in an invocation handler - (you could subclass <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/management/MBeanServerInvocationHandler.html">MBeanServerInvocationHandler</a>

to implement your own proxy - and provided that you code your client to use

proxies created by your subclass of MBeanServerInvocationHandler, you could fake

the emission of the notification in addNotificationListener() within the proxy,

from the client side.

Alternatively, you could also change your client to explicitely

<ol><li>register for notifications, and then</li>

<li>get a snapshot by</li>

<ul><li>calling your getSnapshot() method, or</li>

<li>if you don't want to code a getSnapshot() in your MBean, you could use one of

those <a href="http://blogs.sun.com/jmxetc/entry/jmx_nick_stephen_blogs_on">SnapshotProxies</a> that <a href="http://blogs.sun.com/nickstephen">Nick</a> was talking about...</li>

</ul>

</ol>

Hope this helps,

-- daniel

JMX, SNMP, Java, etc...

http://blogs.sun.com/jmxetc

>

> Thanks,

> Michele

dfuchsa at 2007-7-15 4:27:48 > top of Java-index,Core,Monitoring & Management...
# 4

>

> > > The question I would ask is why would you want

> to

> > > send a Notification in addNotificationListener()

> in the first place?

> > > What is your use case for wanting to doing this?

> > >

> > I would like to send a mbean snapshot when a new

> > listener registers (actually I would like to send

> it

> > only to the new listener by modifying the

> > NotificationBroadcasterSupport class). Does it

> make

> > any sense?

>

> I am afraid there isn't a way to do that from the

> server side. So my advice is: <b>stay away

> from this</b>.

>

Ok, sure! :)

> Alternatively, you could also change your client to

> explicitely

> <ol><li>register for notifications, and then</li>

> <li>get a snapshot by</li>

> <ul><li>calling your getSnapshot() method, or</li>

> <li>if you don't want to code a

> getSnapshot() in your MBean, you could use one of

> hose <a

> href="http://blogs.sun.com/jmxetc/entry/jmx_nick_steph

> en_blogs_on">SnapshotProxies</a> that <a

> href="http://blogs.sun.com/nickstephen">Nick</a> was

> talking about...</li>

> </ul>

This confirms what I've already done (first alternative). I'll also take a look to the article you've suggested me.

> Hope this helps,

> -- daniel

> JMX, SNMP, Java, etc...

> http://blogs.sun.com/jmxetc

Yes, it did.

Thanks,

Michele

michele81a at 2007-7-15 4:27:48 > top of Java-index,Core,Monitoring & Management...