Need help understanding JNDI and a particular Clas

2019-07-03 18:20发布

问题:

I have an enterprise application A and B deployed (in WLS 10.0). A is the "framework", B is a client app. The client issues the following calls:

Object o = ctx.lookup(jndiName); // line 1
cf = (ConnectionFactory) o; // line 2

ConnectionFactory is an interface, defined as:

public interface ConnectionFactory 
    extends java.io.Serializable, javax.resource.Referenceable {
    ...
}

What happens is:

  1. If the jar containing the interface class is on the system classpath, line 2 is executed fine
  2. If the interface class is not on the system classpath, but packaged with the applications separately, line 2 throws a ClassCastException (which has the informative text that the o is a ConnectionFactoryImpl)

Why is this possible? I assume that the JNDI lookup returns only a stub to the remote object (am I right in this point?), then why does it matter if the classloader of the interface class are different?

The kind of answer I expect:

  1. Yes, it should happen the way you experience it, because ...
  2. No, it should not happen this way, because if ... then ..., so there is something fishy in your setup
  3. The situation you described is very strange, are you sure you don't miss some point somewhere?
  4. ... :)

It would also be nice if someone could clarify how the JNDI and stubs work, where does the casting happen (on the client side on the stub? or on the original object on the remote side?), etc.

Thanks for your help!

回答1:

The answer, sadly, is (1).

JNDI does not dictate a mechanism for how the object is stored on the tree, or how it is delivered to clients. It's just an API to use for performing the operations.

If both applications are in the same JVM, as they are here, then Weblogic is very likely just handing the object directly to the client application. There is no stub, and "remote side". Since the types implemented by that object are not visible to the client application (remember, a type identity is defined by the class name, and also the classloader it was loaded from).

You might think this is a weird thing to happen, but bear in mind that applications talking amongst themselves like this is not the norm in JavaEE development - the apps are supposed to be isolated from one another, sharing only system-level resources.