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]

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
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
> 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
>
> > > 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
