You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@river.apache.org by Rupert Smith <ru...@googlemail.com> on 2010/12/02 17:50:28 UTC

How do I subscribe to know about changes to services?

Hi,

I have successfully registered a JMX RMI Connector with in a registry in an
app process, looked it up by service type, and queried it for available
MBeans in a management process. I have many app instances starting/stopping,
and a single management instance that needs to know when the applications
come up or down, and to obtain access to their MBeans when they do.

To get started, I have run an example lookup on the management process. Now
instead of a pull interface (client driven poll), I want, if possible a
registry driven push interface, registry will tell the management process as
service become available/unavailable.

First of all, I'd like to know, am I taking the right approach? Is the
ServiceRegistrar.notify(...) method capable of doing what I want it to do
wrt a push driven interface between the registry and the management process?
There's not much documentation around so its hard to know. I was expecting a
remote call-back from the registry every time a matching service changes its
registration.

If I can't get it to work, I'll just fall back to a periodic polling
mechansim.

See below for the gruesome details, and many thanks for any help you are
able to give me.

Rupert

=====================================

Here's some code:

public class MBeanJiniListener extends StartStopLifecycleBase implements
RemoteEventListener, Serializable
{
...
    private void startListeningForJMXConnectors() throws IOException,
ClassNotFoundException
    {
        ServiceRegistrar registrar =
JiniUtils.getRegistrar(jiniRegistryURL);

        log.fine("registrar is: " + registrar);

        jmxConnections = new HashMap<JMXConnector, MBeanServerConnection>();

        Class[] classes = new Class[] { JMXConnector.class };
        Entry[] serviceAttrs =
            new Entry[] { new
com.sun.jini.lookup.entry.BasicServiceType(JMX_CONNECTOR_SERVICE_NAME) };

        ServiceTemplate template = new ServiceTemplate(null, classes,
serviceAttrs);

        eventRegistration =
            registrar.notify(template,
ServiceRegistrar.TRANSITION_MATCH_NOMATCH, this, null,
                Long.MAX_VALUE);
    }
}

This fails with a ClassNotFoundException on this line:

        eventRegistration =
            registrar.notify(template,
ServiceRegistrar.TRANSITION_MATCH_NOMATCH, this, null,
                Long.MAX_VALUE)

...
Caused by: java.lang.ClassNotFoundException:
com.rapidaddition.fix.management.jini.MBeanJiniListener
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
at
net.jini.loader.pref.PreferredClassLoader.loadClass(PreferredClassLoader.java:922)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:334)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at
net.jini.loader.pref.PreferredClassProvider.loadClass(PreferredClassProvider.java:613)
at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:264)
at
sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:214)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1592)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1513)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1749)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:368)
at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:324)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:307)
... 9 more

I am using 'httpd.sh' and 'jrmp-reggie.sh' scripts from the hello example,
bundled with Apache River 2.1.1. Both have been modified to include all my
project .jars. That is:

'config/start-reggie.config'

...
    private static codebase =
        ConfigUtil.concat(
                          new Object[] {
                              "http://", ConfigUtil.getHostName(),
":8080/reggie-dl.jar",
                              " ",
                              "http://", ConfigUtil.getHostName(),
":8080/jsk-dl.jar",
                              " ",
                              "http://", ConfigUtil.getHostName(),
":8080/genzero-mgt-1.2-beta2-SNAPSHOT.jar",
                              " ",
                              "http://", ConfigUtil.getHostName(),
":8080/genzero-1.2-beta2-SNAPSHOT.jar",
                              " ",
                              "http://", ConfigUtil.getHostName(),
":8080/genzero-api-1.2-beta2-SNAPSHOT.jar",
                              " ",
                              "http://", ConfigUtil.getHostName(),
":8080/samples-1.2-beta2-SNAPSHOT.jar"
                          } );
...

and 'scripts/httpd.sh'

...
java -jar ../../../../../../../lib/classserver.jar -port 8080 -dir
lib:../../../../../../../lib-dl:/home/rupert/rapid/genzero/genzero-trunk/genzero-api/target:/home/rupert/rapid/genzero/genzero-trunk/genzero/target:/home/rupert/rapid/genzero/genzero-trunk/samples/target:/home/rupert/rapid/genzero/genzero-trunk/genzero-mgt/target
$*

Re: How do I subscribe to know about changes to services?

Posted by Rupert Smith <ru...@googlemail.com>.
Yes, I see it is the case. Reggie outputs:

INFO: started Reggie: 2b200cb6-00c5-490d-b565-8f4478d8d1e5, [
nonsecure.hello.example.jini.sun.com], jini://badger2.thesett.com/
Got RemoteEvent:
com.sun.jini.reggie.RegistrarEvent[serviceID=61e5715d-fd9b-4f1c-8d75-4e217fda5ab1,
transition=TRANSITION_MATCH_NOMATCH,
source=com.sun.jini.reggie.RegistrarProxy[registrar=2b200cb6-00c5-490d-b565-8f4478d8d1e5
RegistrarImpl_Stub[UnicastRef2 [liveRef:
[endpoint:[127.0.1.1:50713](local),objID:[589eac25:12cabe249ee:-7fff,
804964581163571509]]]]], eventID=0, seqNum=1, handback=null]

I implemented a very simple RemoteEventListener, that just prints out the
event. I see that it does indeed get sent to the registry, and invoked
there. So that's not really what I'm after, I want the management process
that makes the call to be notified, the one that is notified. So I'll start
looking at ServiceDiscoveryManager and LookupCache.

Rupert

On 3 December 2010 10:56, Rupert Smith <ru...@googlemail.com> wrote:

> Hi I added:
>
> -Djava.rmi.server.codebase="
> http://localhost:8080/genzero-mgt-1.2-beta2-SNAPSHOT.jar
> http://localhost:8080/genzero-api-1.2-beta2-SNAPSHOT.jar"
>
> to the command line, which helped, but now I get another error about the
> serializability of MBeanJiniListener.
> Caused by: java.lang.RuntimeException:
> java.security.AccessControlException: access denied
> (java.lang.RuntimePermission accessDeclaredMembers)
>  at
> java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl.<init>(AtomicReferenceFieldUpdater.java:217)
> at
> java.util.concurrent.atomic.AtomicReferenceFieldUpdater.newUpdater(AtomicReferenceFieldUpdater.java:93)
>  at
> com.rapidaddition.util.concurrent.StartStopLifecycleBase.<clinit>(StartStopLifecycleBase.java:34)
>
> The offending line is:
>
> private static final AtomicReferenceFieldUpdater<StartStopLifecycleBase,
> RunState> RUN_STATE_UPDATER =
>
>  AtomicReferenceFieldUpdater.newUpdater(StartStopLifecycleBase.class,
> RunState.class, "runState");
>
> Maybe, I just need to make the runState field transient.
>
> However, it seems a bit strange to me that MBeanJiniListener needs to be
> serialised at all. The call:
>
> eventRegistration =
>             serviceRegistrar.notify(template,
> ServiceRegistrar.TRANSITION_MATCH_NOMATCH, this, null, Long.MAX_VALUE);
>
> needs to call back on a RemoteEventListener, and I would have thought that
> the registry would just need that interface, in order to call it, and not
> the whole implementation serialized. Or is it that the RemoteEventListener
> implementations gets send to the registry, and actually invoked on that
> process, and not the original calling process?
> On 2 December 2010 18:49, Dennis Reedy <de...@gmail.com> wrote:
>
>>
>> On Dec 2, 2010, at 122PM, Rupert Smith wrote:
>>
>> > On 2 December 2010 18:05, Dennis Reedy <de...@gmail.com> wrote:
>> >
>> >> I assume the com.rapidaddition.fix.management.jini.MBeanJiniListener
>> class
>> >> is in genzero-api-1.2-beta2-SNAPSHOT.jar right?
>> >>
>> >
>> > Its acutally in genzero-mgt-1.2-beta2-SNAPSHOT.jar, but I made all my
>> jars
>> > available just in case there were other things it needed in there too.
>> >
>> >> Are you setting the codebase to your service when you start it? Can we
>> see
>> > the command line when you start your service?
>> >
>> > I haven't set up a 'codebase' for the service. I didn't know I needed
>> to, so
>> > maybe thats where I'm going wrong.
>>
>> Yes, I think it may be. When you start your service try setting the
>> -Djava.rmi.server.codebase=<codeserver:port>/genzero-mgt-1.2-beta2-SNAPSHOT.jar
>>
>> This will allow services (like reggie) that do not have the classes they
>> need in their classpath (like
>> com.rapidaddition.fix.management.jini.MBeanJiniListener) to dynamically load
>> them. If you can, try setting that system property and report back what
>> happens.
>>
>> Additonally, Tom's recommendation to use the ServiceDiscoveryManager and
>> LookupCache are right on.
>>
>> HTH
>>
>> Dennis
>
>
>

Re: How do I subscribe to know about changes to services?

Posted by Rupert Smith <ru...@googlemail.com>.
Hi I added:

-Djava.rmi.server.codebase="
http://localhost:8080/genzero-mgt-1.2-beta2-SNAPSHOT.jar
http://localhost:8080/genzero-api-1.2-beta2-SNAPSHOT.jar"

to the command line, which helped, but now I get another error about the
serializability of MBeanJiniListener.
Caused by: java.lang.RuntimeException: java.security.AccessControlException:
access denied (java.lang.RuntimePermission accessDeclaredMembers)
at
java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl.<init>(AtomicReferenceFieldUpdater.java:217)
at
java.util.concurrent.atomic.AtomicReferenceFieldUpdater.newUpdater(AtomicReferenceFieldUpdater.java:93)
at
com.rapidaddition.util.concurrent.StartStopLifecycleBase.<clinit>(StartStopLifecycleBase.java:34)

The offending line is:

private static final AtomicReferenceFieldUpdater<StartStopLifecycleBase,
RunState> RUN_STATE_UPDATER =
        AtomicReferenceFieldUpdater.newUpdater(StartStopLifecycleBase.class,
RunState.class, "runState");

Maybe, I just need to make the runState field transient.

However, it seems a bit strange to me that MBeanJiniListener needs to be
serialised at all. The call:

eventRegistration =
            serviceRegistrar.notify(template,
ServiceRegistrar.TRANSITION_MATCH_NOMATCH, this, null, Long.MAX_VALUE);

needs to call back on a RemoteEventListener, and I would have thought that
the registry would just need that interface, in order to call it, and not
the whole implementation serialized. Or is it that the RemoteEventListener
implementations gets send to the registry, and actually invoked on that
process, and not the original calling process?
On 2 December 2010 18:49, Dennis Reedy <de...@gmail.com> wrote:

>
> On Dec 2, 2010, at 122PM, Rupert Smith wrote:
>
> > On 2 December 2010 18:05, Dennis Reedy <de...@gmail.com> wrote:
> >
> >> I assume the com.rapidaddition.fix.management.jini.MBeanJiniListener
> class
> >> is in genzero-api-1.2-beta2-SNAPSHOT.jar right?
> >>
> >
> > Its acutally in genzero-mgt-1.2-beta2-SNAPSHOT.jar, but I made all my
> jars
> > available just in case there were other things it needed in there too.
> >
> >> Are you setting the codebase to your service when you start it? Can we
> see
> > the command line when you start your service?
> >
> > I haven't set up a 'codebase' for the service. I didn't know I needed to,
> so
> > maybe thats where I'm going wrong.
>
> Yes, I think it may be. When you start your service try setting the
> -Djava.rmi.server.codebase=<codeserver:port>/genzero-mgt-1.2-beta2-SNAPSHOT.jar
>
> This will allow services (like reggie) that do not have the classes they
> need in their classpath (like
> com.rapidaddition.fix.management.jini.MBeanJiniListener) to dynamically load
> them. If you can, try setting that system property and report back what
> happens.
>
> Additonally, Tom's recommendation to use the ServiceDiscoveryManager and
> LookupCache are right on.
>
> HTH
>
> Dennis

Re: How do I subscribe to know about changes to services?

Posted by Dennis Reedy <de...@gmail.com>.
On Dec 2, 2010, at 122PM, Rupert Smith wrote:

> On 2 December 2010 18:05, Dennis Reedy <de...@gmail.com> wrote:
> 
>> I assume the com.rapidaddition.fix.management.jini.MBeanJiniListener class
>> is in genzero-api-1.2-beta2-SNAPSHOT.jar right?
>> 
> 
> Its acutally in genzero-mgt-1.2-beta2-SNAPSHOT.jar, but I made all my jars
> available just in case there were other things it needed in there too.
> 
>> Are you setting the codebase to your service when you start it? Can we see
> the command line when you start your service?
> 
> I haven't set up a 'codebase' for the service. I didn't know I needed to, so
> maybe thats where I'm going wrong.

Yes, I think it may be. When you start your service try setting the -Djava.rmi.server.codebase=<codeserver:port>/genzero-mgt-1.2-beta2-SNAPSHOT.jar

This will allow services (like reggie) that do not have the classes they need in their classpath (like com.rapidaddition.fix.management.jini.MBeanJiniListener) to dynamically load them. If you can, try setting that system property and report back what happens.

Additonally, Tom's recommendation to use the ServiceDiscoveryManager and LookupCache are right on. 

HTH

Dennis

Re: How do I subscribe to know about changes to services?

Posted by Rupert Smith <ru...@googlemail.com>.
On 2 December 2010 18:05, Dennis Reedy <de...@gmail.com> wrote:

> I assume the com.rapidaddition.fix.management.jini.MBeanJiniListener class
> is in genzero-api-1.2-beta2-SNAPSHOT.jar right?
>

Its acutally in genzero-mgt-1.2-beta2-SNAPSHOT.jar, but I made all my jars
available just in case there were other things it needed in there too.

> Are you setting the codebase to your service when you start it? Can we see
the command line when you start your service?

I haven't set up a 'codebase' for the service. I didn't know I needed to, so
maybe thats where I'm going wrong.

I'm not sure if this is what your after, but here is the code that places
the JMX Connector in the registry as a service:

    private static final String JMX_CONNECTOR_SERVICE_NAME = "JMXConnector";

    private ServiceRegistration registerRMIConnector(JMXConnectorServer
rmiConnector, Map<String, String> params,
        String jiniRegistryURL) throws IOException, ClassNotFoundException
    {
        JMXConnector proxy = rmiConnector.toJMXConnector(params);
        ServiceRegistrar registrar =
JiniUtils.getRegistrar(jiniRegistryURL);

        Entry[] serviceAttrs =
            new Entry[] { new
com.sun.jini.lookup.entry.BasicServiceType(JMX_CONNECTOR_SERVICE_NAME) };

        log.fine("Registering proxy: ServiceType = " +
JMX_CONNECTOR_SERVICE_NAME + ", proxy = " + proxy);

        ServiceItem srvcItem = new ServiceItem(null, proxy, serviceAttrs);

        rmiConnectorRegistration = registrar.register(srvcItem, Lease.ANY);
        log.fine("Registered ServiceID: " +
rmiConnectorRegistration.getServiceID().toString());

        return rmiConnectorRegistration;
    }

Re: How do I subscribe to know about changes to services?

Posted by Dennis Reedy <de...@gmail.com>.
On Dec 2, 2010, at 1150AM, Rupert Smith wrote:

> Hi,
> 
> I have successfully registered a JMX RMI Connector with in a registry in an
> app process, looked it up by service type, and queried it for available
> MBeans in a management process. I have many app instances starting/stopping,
> and a single management instance that needs to know when the applications
> come up or down, and to obtain access to their MBeans when they do.
> 
> To get started, I have run an example lookup on the management process. Now
> instead of a pull interface (client driven poll), I want, if possible a
> registry driven push interface, registry will tell the management process as
> service become available/unavailable.

My guess is that from the stacktrace thats what seems to be attempted. 

Since reggie does not have the com.rapidaddition.fix.management.jini.MBeanJiniListener in it's classpath, it needs to load it from somewhere.  Reggie is looking to load that class based on the codebase for your service. Are you setting the codebase to your service when you start it? Can we see the command line when you start your service?

I assume the com.rapidaddition.fix.management.jini.MBeanJiniListener class is in genzero-api-1.2-beta2-SNAPSHOT.jar right?



Re: How do I subscribe to know about changes to services?

Posted by Rupert Smith <ru...@googlemail.com>.
When each application start, its finds the registry and places a JMX
Connector in it, when it shuts down it (usually) deregisters the JMX
Connector cleanly. Got this bit working.

There is one management application (still being put together). I have
written an quick test example for it, that finds the registry, gets any
available JMX Connectors, and then queries them about the MBeans on the
applications. The MBeans themselves don't ever get put in the registry, this
last step, the JMX conversation between the management application and the
managed applications uses JMX over RMI. My example lookup works just fine.

Then I saw that ServiceRegistrar has a notify(...) method on it. I though
maybe that will let me register my query about services, and be called back
as matching services are registered/deregistered, but I'm not really sure if
its the right way to go about doing that.

So yes, what I am trying to do is to create some sort of subscription that
will be notified each time a new JMX Connector service is made available, or
becomes unavailable (if an app crashes leaving its connector in the
registry, no matter, I will soon find out it doesn't work when I try to
connect to it over RMI, and can forget about it then).

Thanks for your input, I'll take a look at ServiceDiscoveryManager and
LookupCache.

The reason I'm trying to do the above, is that if I just to JMX over RMI,
each application on each server would need to run rmiregistry. The central
management application would need to know the addresses of all the
rmiregistrys. I'm happy if each app knows the location of the central
management application, but its going to be much better if the management
app can dynamically learn about new managed applications appearing and
dissapearing. Searching around has led me to looking into Jini to accomplish
this, but I am a Jini beginner so my questions might seem a bit awkward, and
not quite in line with what Jini is designed to do. So far so good, just
need to get it working in a push driven way, instead of polling with a
lookup on the registry.

Thanks,

Rupert

On 2 December 2010 17:52, Tom Hobbs <tv...@googlemail.com> wrote:

> Hi Rupert,
>
> I'm not entirely sure I understand what it is you're trying to
> achieve.  Are you saying you have many services which come and go
> (which you describe as "applications") and you want notifications of
> when they dis/appear so you can then get access to their MBeans?
>
> If that's right, a possible approach would be to use a
> ServiceDiscoveryManager to create a LookupCache.  The LookupCache
> would always know what services are around.  As a side-effect, when
> you create the LookupCache
> (ServiceDiscoveryManager.createLookupCache(ServiceTemplate,
> ServiceItemFilter, ServiceDiscoveryListener)) your implementation of
> ServiceDiscoveryListener can handle your accessing the MBeans when
> things appear and dropping them when they go.
>
> Does that help?  If not, can you clarify a bit more what you're trying
> to do and I'll see if I can help.
>
> Cheers,
>
> Tom
>
>
>
> On Thu, Dec 2, 2010 at 4:50 PM, Rupert Smith
> <ru...@googlemail.com> wrote:
> > Hi,
> >
> > I have successfully registered a JMX RMI Connector with in a registry in
> an
> > app process, looked it up by service type, and queried it for available
> > MBeans in a management process. I have many app instances
> starting/stopping,
> > and a single management instance that needs to know when the applications
> > come up or down, and to obtain access to their MBeans when they do.
> >
> > To get started, I have run an example lookup on the management process.
> Now
> > instead of a pull interface (client driven poll), I want, if possible a
> > registry driven push interface, registry will tell the management process
> as
> > service become available/unavailable.
> >
> > First of all, I'd like to know, am I taking the right approach? Is the
> > ServiceRegistrar.notify(...) method capable of doing what I want it to do
> > wrt a push driven interface between the registry and the management
> process?
> > There's not much documentation around so its hard to know. I was
> expecting a
> > remote call-back from the registry every time a matching service changes
> its
> > registration.
> >
> > If I can't get it to work, I'll just fall back to a periodic polling
> > mechansim.
> >
> > See below for the gruesome details, and many thanks for any help you are
> > able to give me.
> >
> > Rupert
> >
> > =====================================
> >
> > Here's some code:
> >
> > public class MBeanJiniListener extends StartStopLifecycleBase implements
> > RemoteEventListener, Serializable
> > {
> > ...
> >    private void startListeningForJMXConnectors() throws IOException,
> > ClassNotFoundException
> >    {
> >        ServiceRegistrar registrar =
> > JiniUtils.getRegistrar(jiniRegistryURL);
> >
> >        log.fine("registrar is: " + registrar);
> >
> >        jmxConnections = new HashMap<JMXConnector,
> MBeanServerConnection>();
> >
> >        Class[] classes = new Class[] { JMXConnector.class };
> >        Entry[] serviceAttrs =
> >            new Entry[] { new
> > com.sun.jini.lookup.entry.BasicServiceType(JMX_CONNECTOR_SERVICE_NAME) };
> >
> >        ServiceTemplate template = new ServiceTemplate(null, classes,
> > serviceAttrs);
> >
> >        eventRegistration =
> >            registrar.notify(template,
> > ServiceRegistrar.TRANSITION_MATCH_NOMATCH, this, null,
> >                Long.MAX_VALUE);
> >    }
> > }
> >
> > This fails with a ClassNotFoundException on this line:
> >
> >        eventRegistration =
> >            registrar.notify(template,
> > ServiceRegistrar.TRANSITION_MATCH_NOMATCH, this, null,
> >                Long.MAX_VALUE)
> >
> > ...
> > Caused by: java.lang.ClassNotFoundException:
> > com.rapidaddition.fix.management.jini.MBeanJiniListener
> > at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
> > at java.security.AccessController.doPrivileged(Native Method)
> > at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
> > at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
> > at
> >
> net.jini.loader.pref.PreferredClassLoader.loadClass(PreferredClassLoader.java:922)
> > at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
> > at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:334)
> > at java.lang.Class.forName0(Native Method)
> > at java.lang.Class.forName(Class.java:264)
> > at
> >
> net.jini.loader.pref.PreferredClassProvider.loadClass(PreferredClassProvider.java:613)
> > at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:264)
> > at
> >
> sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:214)
> > at
> java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1592)
> > at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1513)
> > at
> java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1749)
> > at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346)
> > at java.io.ObjectInputStream.readObject(ObjectInputStream.java:368)
> > at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:324)
> > at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:307)
> > ... 9 more
> >
> > I am using 'httpd.sh' and 'jrmp-reggie.sh' scripts from the hello
> example,
> > bundled with Apache River 2.1.1. Both have been modified to include all
> my
> > project .jars. That is:
> >
> > 'config/start-reggie.config'
> >
> > ...
> >    private static codebase =
> >        ConfigUtil.concat(
> >                          new Object[] {
> >                              "http://", ConfigUtil.getHostName(),
> > ":8080/reggie-dl.jar",
> >                              " ",
> >                              "http://", ConfigUtil.getHostName(),
> > ":8080/jsk-dl.jar",
> >                              " ",
> >                              "http://", ConfigUtil.getHostName(),
> > ":8080/genzero-mgt-1.2-beta2-SNAPSHOT.jar",
> >                              " ",
> >                              "http://", ConfigUtil.getHostName(),
> > ":8080/genzero-1.2-beta2-SNAPSHOT.jar",
> >                              " ",
> >                              "http://", ConfigUtil.getHostName(),
> > ":8080/genzero-api-1.2-beta2-SNAPSHOT.jar",
> >                              " ",
> >                              "http://", ConfigUtil.getHostName(),
> > ":8080/samples-1.2-beta2-SNAPSHOT.jar"
> >                          } );
> > ...
> >
> > and 'scripts/httpd.sh'
> >
> > ...
> > java -jar ../../../../../../../lib/classserver.jar -port 8080 -dir
> >
> lib:../../../../../../../lib-dl:/home/rupert/rapid/genzero/genzero-trunk/genzero-api/target:/home/rupert/rapid/genzero/genzero-trunk/genzero/target:/home/rupert/rapid/genzero/genzero-trunk/samples/target:/home/rupert/rapid/genzero/genzero-trunk/genzero-mgt/target
> > $*
> >
>

Re: How do I subscribe to know about changes to services?

Posted by Tom Hobbs <tv...@googlemail.com>.
Hi Rupert,

I'm not entirely sure I understand what it is you're trying to
achieve.  Are you saying you have many services which come and go
(which you describe as "applications") and you want notifications of
when they dis/appear so you can then get access to their MBeans?

If that's right, a possible approach would be to use a
ServiceDiscoveryManager to create a LookupCache.  The LookupCache
would always know what services are around.  As a side-effect, when
you create the LookupCache
(ServiceDiscoveryManager.createLookupCache(ServiceTemplate,
ServiceItemFilter, ServiceDiscoveryListener)) your implementation of
ServiceDiscoveryListener can handle your accessing the MBeans when
things appear and dropping them when they go.

Does that help?  If not, can you clarify a bit more what you're trying
to do and I'll see if I can help.

Cheers,

Tom



On Thu, Dec 2, 2010 at 4:50 PM, Rupert Smith
<ru...@googlemail.com> wrote:
> Hi,
>
> I have successfully registered a JMX RMI Connector with in a registry in an
> app process, looked it up by service type, and queried it for available
> MBeans in a management process. I have many app instances starting/stopping,
> and a single management instance that needs to know when the applications
> come up or down, and to obtain access to their MBeans when they do.
>
> To get started, I have run an example lookup on the management process. Now
> instead of a pull interface (client driven poll), I want, if possible a
> registry driven push interface, registry will tell the management process as
> service become available/unavailable.
>
> First of all, I'd like to know, am I taking the right approach? Is the
> ServiceRegistrar.notify(...) method capable of doing what I want it to do
> wrt a push driven interface between the registry and the management process?
> There's not much documentation around so its hard to know. I was expecting a
> remote call-back from the registry every time a matching service changes its
> registration.
>
> If I can't get it to work, I'll just fall back to a periodic polling
> mechansim.
>
> See below for the gruesome details, and many thanks for any help you are
> able to give me.
>
> Rupert
>
> =====================================
>
> Here's some code:
>
> public class MBeanJiniListener extends StartStopLifecycleBase implements
> RemoteEventListener, Serializable
> {
> ...
>    private void startListeningForJMXConnectors() throws IOException,
> ClassNotFoundException
>    {
>        ServiceRegistrar registrar =
> JiniUtils.getRegistrar(jiniRegistryURL);
>
>        log.fine("registrar is: " + registrar);
>
>        jmxConnections = new HashMap<JMXConnector, MBeanServerConnection>();
>
>        Class[] classes = new Class[] { JMXConnector.class };
>        Entry[] serviceAttrs =
>            new Entry[] { new
> com.sun.jini.lookup.entry.BasicServiceType(JMX_CONNECTOR_SERVICE_NAME) };
>
>        ServiceTemplate template = new ServiceTemplate(null, classes,
> serviceAttrs);
>
>        eventRegistration =
>            registrar.notify(template,
> ServiceRegistrar.TRANSITION_MATCH_NOMATCH, this, null,
>                Long.MAX_VALUE);
>    }
> }
>
> This fails with a ClassNotFoundException on this line:
>
>        eventRegistration =
>            registrar.notify(template,
> ServiceRegistrar.TRANSITION_MATCH_NOMATCH, this, null,
>                Long.MAX_VALUE)
>
> ...
> Caused by: java.lang.ClassNotFoundException:
> com.rapidaddition.fix.management.jini.MBeanJiniListener
> at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
> at java.security.AccessController.doPrivileged(Native Method)
> at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
> at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
> at
> net.jini.loader.pref.PreferredClassLoader.loadClass(PreferredClassLoader.java:922)
> at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
> at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:334)
> at java.lang.Class.forName0(Native Method)
> at java.lang.Class.forName(Class.java:264)
> at
> net.jini.loader.pref.PreferredClassProvider.loadClass(PreferredClassProvider.java:613)
> at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:264)
> at
> sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:214)
> at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1592)
> at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1513)
> at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1749)
> at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346)
> at java.io.ObjectInputStream.readObject(ObjectInputStream.java:368)
> at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:324)
> at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:307)
> ... 9 more
>
> I am using 'httpd.sh' and 'jrmp-reggie.sh' scripts from the hello example,
> bundled with Apache River 2.1.1. Both have been modified to include all my
> project .jars. That is:
>
> 'config/start-reggie.config'
>
> ...
>    private static codebase =
>        ConfigUtil.concat(
>                          new Object[] {
>                              "http://", ConfigUtil.getHostName(),
> ":8080/reggie-dl.jar",
>                              " ",
>                              "http://", ConfigUtil.getHostName(),
> ":8080/jsk-dl.jar",
>                              " ",
>                              "http://", ConfigUtil.getHostName(),
> ":8080/genzero-mgt-1.2-beta2-SNAPSHOT.jar",
>                              " ",
>                              "http://", ConfigUtil.getHostName(),
> ":8080/genzero-1.2-beta2-SNAPSHOT.jar",
>                              " ",
>                              "http://", ConfigUtil.getHostName(),
> ":8080/genzero-api-1.2-beta2-SNAPSHOT.jar",
>                              " ",
>                              "http://", ConfigUtil.getHostName(),
> ":8080/samples-1.2-beta2-SNAPSHOT.jar"
>                          } );
> ...
>
> and 'scripts/httpd.sh'
>
> ...
> java -jar ../../../../../../../lib/classserver.jar -port 8080 -dir
> lib:../../../../../../../lib-dl:/home/rupert/rapid/genzero/genzero-trunk/genzero-api/target:/home/rupert/rapid/genzero/genzero-trunk/genzero/target:/home/rupert/rapid/genzero/genzero-trunk/samples/target:/home/rupert/rapid/genzero/genzero-trunk/genzero-mgt/target
> $*
>