On Feb 2, 2005, at 8:04 AM, Mark wrote:
> To all, most likely Alan,
>
> A little confusion on my end. I was trying to use the
> ReferenceCollectionListern to handle adding and removing of
> EJBContainers. Originally I was thinking of uisng the ContainerIndex
> like the EJBServer does. I have a GBean with the following:
>
> 1. I suppose the kernel creates a collection of containers during
> server startup and passes them to my gbean.
correct.
> 2. During runtime as ejbs are deployed (started) the kernel will end
> up calling memberAdded. (Likewise with the stop/undeploy an ejb with
> memberRemoved)
well, its the ReferenceContainer rather than the kernel directly, but
the effect is the same :-)
>
> public static final GBeanInfo GBEAN_INFO;
>
> static {
> GBeanInfoBuilder infoFactory = new
> GBeanInfoBuilder(RmiIiopServerGBean.class);
>
> infoFactory.addInterface(SocketService.class);
>
> infoFactory.addAttribute("classLoader", ClassLoader.class,
> false);
> infoFactory.addAttribute("args", ArrayList.class, true);
> infoFactory.addAttribute("props", Properties.class, true);
> infoFactory.addAttribute("ip", String.class, true);
> infoFactory.addAttribute("port", int.class, true);
> infoFactory.addReference("AdapterManager",
> AdapterManager.class);
> infoFactory.addReference("Containers", EJBContainer.class); //
> Use this?
you will get notified when a container is added or removed
> infoFactory.addReference("ContainerIndex",
> ContainerIndex.class); // or Use this?
you will have to ask the ContainerIndex for information when you need
it.
>
> infoFactory.setConstructor(new String[]{"classLoader",
> "AdapterManager", "ContainerIndex"});
I would definitely include Containers as a constructor arg
>
> GBEAN_INFO = infoFactory.getBeanInfo();
> }
>
> public static GBeanInfo getGBeanInfo() {
> return GBEAN_INFO;
> }
>
> public void memberAdded(ReferenceCollectionEvent event) {
> EJBContainer container = (EJBContainer) event.getMember();
>
> // TODO: How does this method differ from setContainers()???
setContainers gives you the ReferenceCollection that you can register
this listener with. Members can get added and removed from the
collection at any time
>
> log.debug( "RmiIiopServerGBean.memberAdded(): container = " +
> container );
> log.debug( "RmiIiopServerGBean.memberAdded(): containerID = " +
> container.getContainerID() );
>
> ............
> }
>
> public void memberRemoved(ReferenceCollectionEvent event) {
> EJBContainer container = (EJBContainer) event.getMember();
>
> log.debug( "RmiIiopServerGBean.memberRemoved(): container = " +
> container );
> log.debug( "RmiIiopServerGBean.memberRemoved(): containerID = "
> + container.getContainerID() );
>
> ...........
> }
>
> public void setContainers(Collection containers) {
> log.debug( "RmiIiopServerGBean.setContainers(): containers = "
> + containers );
> ReferenceCollection ref = (ReferenceCollection) containers;
> ref.addReferenceCollectionListener(this);
>
> this.containers = containers;
If you want to do something when EJBContainers are added to the
container, you need to iterate through the current contents of the
container right here and process each one, e.g. by calling memberAdded
yourself. My favorite example is in the TransactionManager gbean's
collection of ResourceManagers for recovery.
> }
>
>
> In my plan, I have:
>
> 1. In the reference for Contains, I have a name pattern for EJBs.
> However, I don't seem to be able to add a wildcard to represent
> any/all containers. I have tried various settings all result in
> either a Malformed exception or other.
what happens if you use the same pattern as ContainerIndex uses?
> 2. I suspect that I shouldn't use ContainerIndex, but rather
> Containers.
Depends on what you are trying to do. If you need to be notified when
a container comes or goes, you need to have your own reference
collection. If periodically you need to do something with all the
containers that happen to exist right then, you can either have your
own collection (you won't need the listener in this case) or use
ContainerIndex.
> 3. I have also observed that when using ContainerIndex, the kernel is
> able to start my GBean since there is a valid object reference for
> ContainerIndex. I have seen messages on the console that indicate
> that the kernel is awaiting an object reference for ContainerIndex.
> This is probably due to the fact that I don't currently have an ejb
> deployed.
Are there any "not"s left out of this sentence :-)? Are you sure the
names in your patterns are actually those used by the gbeans? Having
to supply an entire object name or quite a bit of the pattern is a
serious weakness of our current reference configuration system.
Anyway, both ContainerIndex and your gbean should start whether or not
there are any ejbs currently running. ContainerIndex is a
single-valued reference which should be present, and Containers is a
multivalued reference which should let your gbean start whether or not
it is empty.
>
> class="org.apache.geronimo.interop.adapter.AdapterManagerGBean"/>
>
> class="org.openejb.server.StandardServiceStackGBean">
> RMIIIOP
> 9000
> 127.0.0.1
> 127.0.0.1
> 5
> 20
> name="logOnSuccess">HOST,NAME,THREADID,USERID
> HOST,NAME
> name="Server">interop:type=Server,name=RMIIIOP
>
>
> class="org.apache.geronimo.interop.rmi.iiop.server.RmiIiopServerGBean">
> name="ContainerIndex">openejb:type=ContainerIndex
> name="Containers">openejb.server:EJBModule=ejbhw,*
Do you really mean to be looking for ejbs from exactly one ejb module?
If so, you should include the name of the module in this gbean's name.
> name="AdapterManager">interop:
> type=AdapterManager,name=AdapterManager
>
>
I recommend that you move to the more-automatic gbean naming system
where you specify the j2eeType in the GBeanInfoFactory constructor and
only the namePart in the xml config. If you'd like me to modify your
gbeans for this I'd be happy to.
Also, the names here imply that you are running in openejb rather than
full geronimo. Is this correct?
many thanks,
david jencks