主要要看JNDI的名字是什么。他根据JNDI取。
解决方案 »
- Spring的Ioc依赖注入原理
- hibernate注解配置集合映射list
- jquery 插件 tablesort 对表格排序问题
- JBOSS诡异的问题,急求高手帮帮忙
- 关于struts 2 中datetimepicker startDate到使用问题
- Axis1.2 还是Nullpointer的问题
- struts 上传文件问题
- 問一個關於Struts的問題
- 关于WAP乱码转换问题
- com.atomikos.icatch.HeurHazardException: Heuristic Exception
- 关于EJB中使用事务支持的疑问,请高手指教~~~
- 本人初学Java,想学习J2EE(EJB、JSP),但是发现要学习的东西太多,想请问一下那些什么图形设计(AWT、SWING)需要学习吗?好象在J2EE没
InitialContext ic = new InitialContext();
Object objRef = ic.lookup("java:comp/env/ejb/TheConverter");
的方法来取的,就是不明白为什么要在"ejb/TheConverter"前加"java:comp/env",望大虾们为我解困啊。
传统的写法是lookup("java:comp/env/ejb/TheConverter"),
InitialContext ic = new InitialContext();
Object objRef = ic.lookup("java:comp/env/ejb/TheConverter");
或
InitialContext ic = new InitialContext(); //step 1
Context rootCtx = (Context) ic.lookup("java:comp/env"); //step 2
Object objRef = rootCtx.lookup("ejb/TheConverter"); //step3你lookup("ejb/TheConverter")也能取得到,可能是服务器帮你直接取到了step2 (猜测而已)水平有限啊. 汗~
是sun的ejb标准中的写法
要看appserver的实现了,在大部分服务器中用jndiname就可以取得,比如weblogic,webshpere
但是在iplanet(sun的appserver)中就必须用这种写法: java:comp/env/jndiname
而且配置文件中必须加入ejbref
Context rootCtx = (Context) ic.lookup("java:comp/env");这种写法不存在
TraderBean.java : /**
* This method corresponds to the create method in the home interface
* "TraderHome.java".
* The parameter sets of the two methods are identical. When the client calls
* <code>TraderHome.create()</code>, the container allocates an instance of
* the EJBean and calls <code>ejbCreate()</code>.
*
* @exception javax.ejb.CreateException
* if there is a problem creating the bean
* @see examples.ejb20.basic.statefulSession.Trader
*/
public void ejbCreate() throws CreateException {
log("ejbCreate called");
try {
InitialContext ic = new InitialContext();
environment = (Context) ic.lookup("java:comp/env");
} catch (NamingException ne) {
throw new CreateException("Could not look up context");
}
this.tradingBalance = 0.0;
}
在sun自带的j2ee的环境中两个都有。我在j2ee服务器中的测试端和ejb都是在一个ear文件中,按理说 应该是ejb和测试端都在一个application中了,但是 在j2ee服务器的环境时,用简名的时候 是不能得到Home接口的 :(
Object objRef = ic.lookup("java:comp/env/ejb/TheConverter");
是一个ref引用
而 lookup(“ejb/TheConverter”)则直接是一个jndi的使用。...汗,偶一直没搞清楚什么意思...
而java:comp/env是相对于当前应用的一个环境,
如果是web应用则在web.xml的ejb-ref中定义ejb/TheConverter这个逻辑名,实际上就指向一定义的ejb/TheCjonverter
查询时使用java:comp/env/ejb/TheConverter是使用的逻辑名。如果是ejb模块,则在ejb-jar.xml中ejb-ref中定义。
这样做的目的应该是去掉硬编码的ejb查询。
有一篇到pdf文章的链接,偶这里ftp出不去,不知道这篇文章会不会提到.
另,这一篇应该很有帮助...
http://www-900.ibm.com/developerWorks/cn/wsdd/library/bestpractices/increase_app_portability.shtml
大家一起研究
那个Converter ejb绑定到jndi是 MyConverter,作了一个ref名为ejb/TheConverter,
<ejb-ref>
<ejb-ref-name>ejb/TheConverter</ejb-ref-name>
<jndi-name>MyConverter</jndi-name>
</ejb-ref> <ejb>
<ejb-name>ConverterEJB</ejb-name>
<jndi-name>MyConverter</jndi-name>
<ior-security-config>
<transport-config>
<integrity>supported</integrity>
<confidentiality>supported</confidentiality>
<establish-trust-in-target>supported</establish-trust-in-target>
<establish-trust-in-client>supported</establish-trust-in-client>
</transport-config>
<as-context>
<auth-method>username_password</auth-method>
<realm>default</realm>
<required>false</required>
</as-context>
<sas-context>
<caller-propagation>supported</caller-propagation>
</sas-context>
</ior-security-config>
<gen-classes>
<remote-home-impl>bbq.ejb.test.ConverterBean_RemoteHomeImpl</remote-home-impl>
<remote-impl>bbq.ejb.test.ConverterBean_EJBObjectImpl</remote-impl>
</gen-classes>
</ejb> 这个是我把xml考出来的,不知道为什么sun自己的工具写了好多看不懂的东西,不过反正
jndi是 MyConverter,ref名为ejb/TheConverter
写了几个jsp测试 ==========================================================
InitialContext ic = new InitialContext();
Object objRef = ic.lookup("java:comp/env/ejb/TheConverter");
ConverterHome home =(ConverterHome)PortableRemoteObject.narrow(
objRef, ConverterHome.class);
converter = home.create();
这个写法是正确的
=====================================================
InitialContext ic = new InitialContext();
Object objRef = ic.lookup("TheConverter");
ConverterHome home =(ConverterHome)PortableRemoteObject.narrow(
objRef, ConverterHome.class);
converter = home.create();
这种写法错误,提示no binding
=====================================================
InitialContext ic = new InitialContext();
Object objRef = ic.lookup("java:comp/env/ejb/MyConverter");
ConverterHome home =(ConverterHome)PortableRemoteObject.narrow(
objRef, ConverterHome.class);
converter = home.create();
也出错
========================================================
InitialContext ic = new InitialContext();
Object objRef = ic.lookup("MyConverter");
ConverterHome home =(ConverterHome)PortableRemoteObject.narrow(
objRef, ConverterHome.class);
converter = home.create();
这个是成功的
===============================================
楼主也可以打开配置看一看,
我直接用lookup("TheConverter") 查找时是在J2EE的目录下:
\j2sdkee1.3.1\repository\用户名\applications\test.jar中你可以查找你的jar所在的目录,估计是和sun的例子不一样的位置。
1。 检查文件j2ee\conf\ejb.properties 中的
repository.directory=repository
applications.directory=applications
是否正确
2。 检查你的客户端程序与服务端程序是否在同一个根jar文件(同一应用)中,如果是,
那么应该可以用相对路径解析“ejb\TheConverter”, 否则要用绝对路径("java:comp/env/ejb/MyConverter")解析.
Object objRef = ic.lookup("java:comp/env/ejb/ejbName");
来调用业务逻辑,当然在特定的应用服务器上还需要做一些名字的映射(假设在weblogic上)
如果
Object objRef = ic.lookup("ejb/ejbName");
那么就跟具体的应用服务器就紧密耦合在一块了,如果什么时候想把整个程序移植到另外一个应用
服务器上,那么整个lookup的名字就要修改。但是采用第一种方式,只需要修改相应应用服务器的
相关部署文件就可以了。不过第一种方式有个弱点就是当引用的ejb多了,比如说10个ejb相互引用
那么部署文件就会非常大,这是一个m*n的数量级
在ejb-jar.xml中
<ejb-ref>
<ejb-ref-name>ejb/TheConverter</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>..</home>
<remote>..</remote>
</ejb-ref>然后在weblogic-ejb-jar.xml中
<ejb-reference-description>
<ejb-ref-name>ejb/TheConverter</ejb-ref-name>
<jndi-name>ejb/TheConverter</jndi-name>
</ejb-reference-description>那么我们在程序中,
Object objRef = ic.lookup("java:comp/env/ejb/ejbName");
Object objRef = ic.lookup("ejb/ejbName");
结果一样的
和
Object objRef = ic.lookup("jndi-name");
效果是一样!
察看一下你的ejb-jar中的配置,偶觉得你的jndi名应该是'ejb/TheConverter',所以你直接取jndi就取到了正确的对象。
但是当你用deploy的jsp或者servlet访问容器中的ejb的时候,通常RI的deploytool会让你为其指定ejb-ref,你可以察看war里的配置文件,找到这个字串,这时候你就可以用上面的方法取得相应的对象了。
Caught an Exception: Unable to resolve 'java:comp.env/ejb/SavingsAccountHome' Resolved: '' Unresolved:'java:comp'
felic (fenglc) :
你的问题可能与具体的应用服务器有关,你在发布到什么服务器下? 能否把你的ejb-jar.xml和 另一个与服务器有关的xml(如JBoss的jboss.xml) 写出来看看?
EJB可以用2种方法来取得
1.Context rootCtx = (Context) ic.lookup("java:comp/env/ejb-ref");
2.Object objRef = ic.lookup("jndi-name");
如果用第一种的话,ejb-jar.xml中设置<ejb-ref></ejb-ref>属性.....,用这种方法可以提高代码的移植性,可以消除对某个特定naming系统和jvm的依赖(就是说不管是使用websphere还是weblogic作应用服务器,还是所引用的ejb是否在一个jvm里);
如果没有设置<ejb-ref></ejb-ref>那么就需要设置<jndi-name></jndi-name>,就是用第二种方法来取得。(用这种方法不易于移植)。
我也觉得caishixia的正确说的是正确的,我正在调试中:)
http://free.dlmovie.net/movie/freemovie.asp?userid=zscsichen
<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
</web-app>ejb-jar.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
<enterprise-beans>
<session>
<display-name>HelloBean</display-name>
<ejb-name>HelloBean</ejb-name>
<home>mastingejb.HelloHome</home>
<remote>mastingejb.Hello</remote>
<ejb-class>mastingejb.HelloBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Bean</transaction-type>
<ejb-ref>
<description>ejb/HelloBean</description>
<ejb-ref-name>ejb/HelloBean</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>mastingejb.HelloHome</home>
<remote>mastingejb.Hello</remote>
</ejb-ref>
</session>
</enterprise-beans>
<assembly-descriptor/>
</ejb-jar>weblogic-ejb-jar.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE weblogic-ejb-jar PUBLIC '-//BEA Systems, Inc.//DTD WebLogic 7.0.0 EJB//EN' 'http://www.bea.com/servers/wls700/dtd/weblogic-ejb-jar.dtd'>
<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>HelloBean</ejb-name>
<reference-descriptor>
<ejb-reference-description>
<ejb-ref-name>ejb/HelloBean</ejb-ref-name>
<jndi-name>ejb/HelloBean</jndi-name>
</ejb-reference-description>
</reference-descriptor>
<jndi-name>HelloBean</jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>在这种情况下还是只能用lookup("HelloBean");
还是不能使用lookup("java:comp/env/ejb/HelloBean");
客户端只能使用JNDI名称,我还测了一个数据源的使用,“java:/MSSQLDS"在EJB中可以使用,但在Client程序中不能。 这样说来,关于可移植性的描述应该就不正确了:
--》 用("java:comp/env/ejb-name")可以提高代码的移植性,可以消除对某个特定naming系统和jvm的依赖 --《 我觉得应该是使用JNDI名称更具可移植性:
. 在java:comp/env/ejb-name中用的是EJB的名称,一般不会随发布改变;
. ejb/ejb-ref用的是JNDI名称,发布是可以修改web.xml等文件改变,这样的好处是: 可以避免在引用名使用上的不方便,实际使用的客户可以按其意愿重新配置改名称。
大家以为呢?
。。
<ejb-ref>
<description>ejb/HelloBean</description>
<ejb-ref-name>ejb/HelloBean</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>mastingejb.HelloHome</home>
<remote>mastingejb.Hello</remote>
</ejb-ref>
。。
这一段是什么意思? 是表示HelloBean又调用了另一个EJB——ejb/HelloBean吗?
如果不是的话,这段应该是多余的。
同理,weblogic-ejb-jar.xml中的”<ejb-ref-name>ejb/HelloBean</ejb-ref-name>“可能也是多余的(我没用过weblogic, 说说而已)
2。web.xml是空的,web端如果有使用EJB的话,应该有应用说明:
<ejb-ref>
<ejb-ref-name>ejb/HelloBean</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>mastingejb.HelloHome</home>
<remote>mastingejb.Hello</remote>
</ejb-ref>
这里的<ejb-ref-name>ejb/HelloBean</ejb-ref-name>应为JNDI名称(web-app_2_3.dtd文件中的有关描述似乎与实际使用不符?请高手指点!!!)。
不知道你有没有看过sun 的 j2eetutorial中的例子?
里面的所有例子都是通过lookup("java:comp/env/ejb/ejbname")来取得的。
在他给的例子中
EJB jar 文件中的ejb-jar:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN' 'http://java.sun.com/dtd/ejb-jar_2_0.dtd'><ejb-jar>
<display-name>ConverterJAR</display-name>
<enterprise-beans>
<session>
<display-name>ConverterBean</display-name>
<ejb-name>ConverterBean</ejb-name>
<home>ConverterHome</home>
<remote>Converter</remote>
<ejb-class>ConverterBean</ejb-class>
<session-type>Stateful</session-type>
<transaction-type>Bean</transaction-type>
<security-identity>
<description></description>
<use-caller-identity></use-caller-identity>
</security-identity>
</session>
</enterprise-beans>
</ejb-jar>war文件中的web.xml:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE web-app PUBLIC '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN' 'http://java.sun.com/dtd/web-app_2_3.dtd'><web-app>
<display-name>ConverterWAR</display-name>
<servlet>
<servlet-name>index</servlet-name>
<display-name>index</display-name>
<jsp-file>/index.jsp</jsp-file>
</servlet>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<ejb-ref>
<ejb-ref-name>ejb/TheConverter</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>ConverterHome</home>
<remote>Converter</remote>
</ejb-ref>
</web-app>客户端jar文件的sun-j2ee-ri.xml:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE j2ee-ri-specific-information PUBLIC '-//Sun Microsystems Inc.//DTD J2EE Reference Implementation 1.3//EN' 'http://localhost:8000/sun-j2ee-ri_1_3.dtd'><j2ee-ri-specific-information>
<app-client>
<ejb-ref>
<ejb-ref-name>ejb/SimpleConverter</ejb-ref-name>
<jndi-name>MyConverter</jndi-name>
</ejb-ref>
</app-client>
</j2ee-ri-specific-information>客户端jar文件的application-client.xml:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE application-client PUBLIC '-//Sun Microsystems, Inc.//DTD J2EE Application Client 1.3//EN' 'http://java.sun.com/dtd/application-client_1_3.dtd'><application-client>
<display-name>ConverterClient</display-name>
<ejb-ref>
<ejb-ref-name>ejb/SimpleConverter</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>ConverterHome</home>
<remote>Converter</remote>
</ejb-ref>
</application-client>而在客户端掉用的方法分别为:
jsp中的调用方法:
InitialContext ic = new InitialContext();
Object objRef = ic.lookup("java:comp/env/ejb/TheConverter");
ConverterHome home = (ConverterHome)PortableRemoteObject.narrow(objRef, ConverterHome.class);
converter = home.create();java class client 端中调用方法:
Context initial = new InitialContext();
Context myEnv = (Context)initial.lookup("java:comp/env");
Object objref = myEnv .lookup("ejb/SimpleConverter");
以上是在sun自带的服务器中运行的。
而我自己在weblogic中设置为楼上的楼上的楼上所示.
只能用lookup("ejb/SimpleConverter");不能lookup("java:comp/env/ejb/TheConverter"); !!!!共同进步!!!!