3
votes

I have two JBoss servers, JbossA and JbossB. Each has its own JNDI. Now I have a JMS on JbossA with the name jms/Client and a JMS on JbossB with the name jms/Server.

Now I want an application on JbossA to be able to access jms/Server using its own JNDI. Also I'd like an application on JbossB to acces jms/Client using the jndi-name jms/Client1 using its own JNDI.

In Short:

JbossA/
       JNDI/
            jms/Client
            jms/Server  -> JbossB/JNDI/jms/Server


JbossB/
       JNDI/
            jms/Server
            jms/Client1  -> JBossA/JNDI/jms/Client
  • AppA on JbossA accesses jms/Client and jms/Server using JbossA/JNDI
  • AppB on JbossB accesses jms/Server and jms/Client1 using JbossB/JNDI

Two questions:

  1. Is it possible?
  2. If so, how would I go about configuring this in JBoss EAP 6.0.1 (Jboss 7.1) ?
3
This is purely an application / jndi question. I'm removing the hornetq tagClebert Suconic
You're right. apologies...dstibbe

3 Answers

0
votes

First, I can't think of a good reason why you'd want to look up an MDB, those are supposed to be invoked by the container only (by the JMS implementation to be precise), but if you're trying to look up a JMS publisher or connection then what your asking for totally makes sense.

With that said, JBoss 7 introduced a nice new feature, the Remote Naming Project does exactly what you need, the problem is that, apparently, it is only able to bind remote EJBs, you could give it a try though. It is my personal opinion that the JBoss team (to whom I'm infinitely thankful for such a great work) is a little left behind in this (maybe they have a good reason for it?), other JEE containers have been able to do this for quite a while, in Weblogic it's called Foreign JNDI Binding, but anyway, if the above didn't work and you absolutely need to do this, I'm afraid the only solution left is to do it programmatically, in that case keep reading below.

The javax.naming API provides a way to bind references to objects outside your local naming context, simply use InitialContext.bind(String name, Object obj), but instead of binding the actual object bind an instance of javax.naming.Reference. As you can see from the javadocs, to create the Reference instance you need to provide an instance of an implementation of javax.naming.RefAddr containing the necessary info to locate the remote object and an implementation of javax.naming.spi.ObjectFactory which is the object that under the hood will do the actual look up to get your remote object. It'd look something like this:

InitialContext ctx = new InitialContext();
ForeignJNDIObjectRefAddr refAddr = getRemoteObjectJNDIInfo(...;
ctx.bind("jms/Server", new Reference("java.lang.Object",
                refAddr, ForeignJNDIObjectFactory.class.getName(), null));

in this case you would have implemented ForeignJNDIObjectRefAddr and ForeignJNDIObjectFactory, when it's time to do the look up, your ForeignJNDIObjectFactory.getObjectInstance method will get invoked with the ForeignJNDIObjectRefAddr instance as its first parameter, so that you have all the necessary info to do the look up and return your remote object. good luck!

0
votes

It's possible. It is easier if you can upgrade your EAP version though. If you have EAP subscription, I don't see a reason for keeping that old version in place. There are lot of bugs fixed since.

From EAP 6.2.0 release notes:

External JNDI Federation

A Naming subsystem configuration has been added to the JBoss EAP 6 configuration that enables an administrator to connect an external naming system to the JBoss EAP 6 JNDI. This capability replaces the ExternalContextMBean from JBoss EAP 5.

However, even with EAP 6.0.x you could use

<subsystem xmlns="urn:jboss:domain:naming:1.2">
    <bindings>
        <object-factory name="java:global/myExtContext" module="my.custom.module" class="my.example.class.ExternalContextObjectFactory"/>
    </bindings>
    <remote-naming/>
</subsystem>

And implement ExternalContextObjectFactory in my.custom.module module like

public class ExternalContextObjectFactory implements ObjectFactory {
    @Override
    public Object getObjectInstance(final Object obj, final Name name, final Context nameCtx, final Hashtable<?, ?> environment) throws Exception {
      Hashtable env = new Hashtable();
      if(environment != null)
        env.putAll(environment);
      env.set( /* all the properties you will need for your target context */ );
      return new InitialContext(environment);
    }
} 

So your target context would be bound to java:global/myExtContext.

0
votes

This is feasible using External JNDI Federation included in EAP 6.x. You need to define a global bound properties. Rest is for you to explore :)

Shishir