本地接口问题!各方高手请赐教

我把local类型的EJB配置在weblogic中的EJB Module中,但是为什么配置在web Application中的Servlet访问不到它,报JNDI找不到,但是remote的EJB就找得到,而且在EJB Module中的同一个EJB.jar中的EJB访问得到,但是不同的EJB.jar中的就访问的到。后来我把EJB、Servlet都打包成一个ear结构,部署在Application中就都能访问到了,请斑竹帮忙解答一下,万分感谢!

是因为weblogic的classloader的缘故

weblogic为每一个应用ear准备一个application classloader,它的父classloader是jdk的System classloader。

因为你的ejb module是单独部署的,也就是是不同的应用。所以你的web应用中的servlet用ejb的local接口,是不能找到的,因为local接口的调用直接用的classloader功能,又web 应用和ejb module使用不同的classloader,所以web应用的classloader是不能够找到ejb module的classloader所导进来的local接口。所以知找不到的。

但是如果把web 和ejb module放在一块成一个ear包,那么它们的classloader是父子关系,即web的classloader的父亲是ejb 的classloader。孩子是可以找到父classloader所导进来的类,所以ejb的local接口,web中的servlet是可以调用的。

远程remote接口,不存在这个问题,是因为它的调用机制,不是通过classloader来完成的,而是通过远程过程调用来完成,因此,不会有这样的问题。

说了这么多,不知道说清楚了没有

还有个另外问题,我看了一些Sample发现例如用了会话bean调用实体bean那么,在ejb-jar.xml部署文件中会出现<ejb-local-ref>的描述,用来指定会话bean中到底调用了哪些实体bean,可是我没有设计<ejb-local-ref>的描述也用的好好的,那么加上<ejb-local-ref>的描述有什么用呢?
<enterprise-beans>
<session>
<display-name>Cart</display-name>
<ejb-name>Cart</ejb-name>
<home>com.borland.samples.esite.ejb20.CartHome</home>
<remote>com.borland.samples.esite.ejb20.Cart</remote>
<ejb-class>com.borland.samples.esite.ejb20.CartBean</ejb-class>
<session-type>Stateful</session-type>
<transaction-type>Container</transaction-type>
<ejb-local-ref>
<description />
<ejb-ref-name>ejb/Orderitem</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<local-home>com.borland.samples.esite.ejb20.OrderitemHome</local-home>
<local>com.borland.samples.esite.ejb20.Orderitem</local>
<ejb-link>Orderitem</ejb-link>
</ejb-local-ref>
<ejb-local-ref>
<description />
<ejb-ref-name>ejb/ShoppingCart</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<local-home>com.borland.samples.esite.ejb20.ShoppingCartHome</local-home>
<local>com.borland.samples.esite.ejb20.ShoppingCart</local>
<ejb-link>ShoppingCart</ejb-link>
</ejb-local-ref>
<ejb-local-ref>
<description />
<ejb-ref-name>ejb/ServerDataModule</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local-home>com.borland.samples.esite.ejb20.ServerDataModuleLocalHome</local-home>
<local>com.borland.samples.esite.ejb20.ServerDataModuleLocal</local>
<ejb-link>ServerDataModule</ejb-link>
</ejb-local-ref>
<ejb-local-ref>
<description />
<ejb-ref-name>ejb/User</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<local-home>com.borland.samples.esite.ejb20.UserHome</local-home>
<local>com.borland.samples.esite.ejb20.User</local>
<ejb-link>User</ejb-link>
</ejb-local-ref>
</session>

读不起,可能bang大哥的论坛字符忘了考虑html关键字符问题上面的帖子显示有点问题,我再重复一遍:
我看了一些Sample发现例如用了会话bean调用实体bean那么,在ejb-jar.xml部署文件中会出现的ejb-local-ref描述,用来指定会话bean中到底调用了哪些实体bean,可是我自己写的例子没有在部署文件中添加的ejb-local-ref描述也用的好好的,那么加上的ejb-local-ref描述有什么用呢?

这个问题要涉及到ejb的开发和部署,即开发人员和部署者之间的关系

试想你要调用一个ejb,你肯定会通过jndi来lookup这个ejb,是不是?
那么这段查找代码肯定有一个ejb的jndi name是不是?

现在分开来看,ejb的开发人员是不知道部署人员对这个ejb用什么样的jndi name。如果部署人员改变ejb的jndi name,那么相应的调用ejb的查找代码也许要改动,这不符合j2ee规范,部署人员是不能,也不可能更改ejb提供者的代码。如果调用ejb的查找代码是通过ejb ref来做的话,就可以避免这个。那么在查找代码中用到的只是ejb ref name,所以不存在上面讲的这个问题

噢,原来如此,我发现这些例子中查询EJB时都是用context.lookup("java:comp/env/ejb-ref-name");而我自己写的都是ctx.lookup("JndiName");这样就是说部署人员任意改动JndiName,代码还是可以通过ejb-ref-name找到EJB,而我直接用JndiName就得改代码了,谢谢!

还有一个问题:我在Tomcat中配置的数据源JNDI需要这样来找到(DataSource) ctx.lookup("java:comp/env/JNDIName"),而在weblogic中(DataSource) ctx.lookup("JNDIName")就能找到,这是什么原因能,你们在项目中是如何解决的啊??谢谢您的不断回贴!