EJB在weblogic下的部署与运行问题

03-07-06 trainking
我尽量把这个问题说清楚,但我知道要把这个问题从头到尾看一遍很麻烦,但我还是恳请大家能耐下心看一下我到底问题出在哪里,帮帮我,谢谢大家!

环境变量设置:

classpath:c:\JBuilder6\jdk1.3.1\lib\tools.jar;c:\JBuilder6\jdk1.3.1\lib\dt.jar;c:\j2sdkee1.3.1\lib\j2ee.jar;c:\bea\wlserver6.1\lib\weblogic_sp.jar;c:\bea\wlserver6.1\lib\weblogic.jar;e:\javatest;

path:%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;c:\JBuilder6\jdk1.3.1\bin;c:\j2sdkee1.3.1\bin;c:\bea\wlserver6.1\bin;

J2EE_HOME,JAVA_HOME,WL_HOME我也都设好了

1。我编写了一个EJB:3个java文件分别是――HelloWorld.java,HelloWorldHome.java,HelloWorldBean.java,

(其中package ejbweblogic.ejb;)

(我在环境变量的classpath中设了我存放包的路径:e:\javatest;)

2。3个java文件编译通过后,均存放在e:\javatest\ejbweblogic\ejb目录下

3。编写了ejb-jar.xml和weblogic-ejb-jar.xml文件,存放在e:\javatest\META-INF目录下

(weblogic-ejb-jar.xml中jndi-name为HelloWorldEJB)

4。使用jar命令将META-INF和ejbweblogic一起打成一个包

e:\javatest>jar cvf HelloWorld.jar ejbweblogic META-INF

5。我把HelloWorld.jar文件拷贝到c:\bea\wlserver6.1\config\mydomain\applications目录下

6。在weblogic控制台中将HelloWorld.jar upload进来

7。编写一个HelloWorldClient.java,存放在e:\javatest\ejbweblogic\ejb目录下;程序中lookup("HelloWorldEJB")

8。编译通过后我执行:

e:\javatest>java ejbweblogic.ejb.HelloWorldClient "t3://localhost:7001"

但执行后出现错误:Caught an unexcepton exception!(这是HelloWorldClient中主程序抛出的异常。)

请大家帮我看看我到底哪里做错了?谢谢!

附:HelloWorldClient程序

package ejbweblogic.ejb;

import javax.naming.Context;

import javax.naming.InitialContext;

import javax.rmi.PortableRemoteObject;

public class HelloWorldClient

{public static void main(String[] args)

{try{Context initial=new InitialContext();

Object objref=initial.lookup("HelloWorldEJB");

HelloWorldHome home=(HelloWorldHome)PortableRemoteObject.narrow(objref,HelloWorldHome.class);

HelloWorld helloBean=home.create();

String msg=helloBean.sayHello();

System.out.println(msg);}

catch(Exception ex)

{System.err.println("Caught an unexception exception!");

}

}

}

ysxu
2003-07-07 09:55

System.err.println("Caught an unexception exception!");

之后,增加一行

ex.printStackTrace();

重新执行后,看错误信息,在来解决你的问题

robbin
2003-07-07 11:06
你有好几个地方都错了。

1、在你第4步之后,不能直接部署,需要用ejbc对jar包进行处理,生成EJB极其接口的weblogic的实现类以及一些Weblogic运行时读的配置文件。

jar cvf pre_HelloWorld.jar ejbweblogic META-INF

java weblogic.ejbc pre_HelloWorld.jar HelloWorld.jar

2、如果你的Weblogic在Development mode下,不需要在控制台upload,拷贝到applications目录下,已经自动部署好了。

3、客户端程序和EJB不在一个JVM里面运行,需要定位JNDI服务

定位JNDI方法很多,比较好的办法是在JNDI配置文件jndi.properties里面写上JNDI工厂和地址,自己创建一个jndi.properties文件,放在CLASSPATH路径下,内容如下:

java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory

java.naming.provider.url=t3://fankai:7001/

birdy.chen
2003-07-07 17:01
String url = "t3://localhost:7001";

String user = "system";

String password = "11111111";

Properties properties = null;

properties = new Properties();

properties.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");

properties.put(Context.PROVIDER_URL, url);

if (user != null) {

properties.put(Context.SECURITY_PRINCIPAL, user);

properties.put(Context.SECURITY_CREDENTIALS, password == null ? "" : password);

}

Context ic = new InitialContext(properties);

trainking
2003-07-07 17:09
我遵照ysxu和robbin的建议,将原先错误的地方改正了。但有一点我还不是很清楚,就是关于JNDI服务的定位问题。“客户端程序和EJB不在一个JVM里面运行”是什么意思?如何做到让他们在一个JVM中运行?我自己写jndi.properties,存放在e:\javatest下,那么在classpath中是否添加一个路径为:e:\javatest\jndi.properties

可能就是因为这个问题还没解决吧,我运行客户端程序后出现错误如下:

Caught an unexception exception!

javax.naming.CommunicationException: Can't find SerialContextProvider

at com.sun.enterprise.naming.SerialContext.getProvider(SerialContext.java:63)

at com.sun.enterprise.naming.SerialContext.lookup(SerialContext.java:120)

at javax.naming.InitialContext.lookup(InitialContext.java:350)

at ejbweblogic.ejb.HelloWorldClient.main(HelloWorldClient.java:10)

看了ysxu和robbin的回复,我虽然还是没能完全解决问题,但收获的确不小,可能正在向成功迈进了,在这里先谢谢两位。但是由于我刚接触java和EJB,而且本人比较愚笨,所以还有一些问题没有搞清楚,恳请两位和更多高人能再次指点一二,万分感谢!

robbin
2003-07-07 19:29
建议:

1、购买BEA官方指定的那本书《J2EE应用和BEA Weblogic Server》,有中文版,虽然是按照Weblogic6.0讲解的,但是会对你的帮助巨大。

2、其实可以去BEA网站Free download 最新的Weblogic8.1,license是免费使用1年的,足够了,况且一年后,你还可以删除重新安装一次继续用。

JNDI的问题:

1、Weblogic目录服务原理

Weblogic内置了一个目录服务,是用纯Java实现的,Weblogic容器提供的各种资源,包括EJB,DataSource,JMS等等,都是通过该目录服务查找到的。该目录服务和Web Server默认情况下共用7001端口,但是Web Server使用HTTP协议,而目录服务使用t3协议(不是规范的IIOP协议,据说通讯效率高很多)

2、JNDI的原理

Weblogic的目录服务实现了JNDI SPI接口和JNDI接口,因此可以使用标准的JNDI接口代码来定位该目录服务。定位目录服务的方法有3种:

1)撰写配置文件jndi.properties,这种方法最好,可以在不修改代码的情况下,改变配置文件,就可以更改目录服务。

2)在代码里面写,通过一个Property对象传入

3)在java命令行通过-Dname=value传入

回答你的问题:

>客户端程序和EJB不在一个JVM里面运行”是什么意思?如何做到让他们在一个JVM中运行?

EJB是运行在Weblogic Server里面的,而Weblogic Server其实也就是一个java程序而已,你可以看看startWelogic.cmd脚本就知道了,其实就是一个java .... weblogic.Server 这样一个java程序。

而你写的客户端程序,你是另外使用java ...命令启动的,所以你启动的JVM和Weblogic启动的JVM分别是两个不同的进程,看看任务管理器就知道了。Java是不能够直接进行进程间通讯的。

如果让他们在一个JVM里面运行,就是你写一个Servlet/JSP,放在Weblogic的Web Application里面运行,这样你的Servlet/JSP和EJB分别是同一进程空间的两个不同的线程,能够读到同样的Weblogic Server的系统属性。

如果你是在Servlet/JSP(或者JNDI初始化写在Servlet/JSP引用到的Java class中)中,而不是在单独的客户端程序中定位Weblogic内置的目录服务的时候,那么就不需要声明JNDI服务的位置(也最好不要声明),Weblogic会自动使用默认的内置目录服务,并且在这样的情况下,JNDI速度比较快(因为不需要经过远程方法调用)。而如果你非要声明的话(使用jndi.properties,或者代码内声明),那么Weblogic就无法进行优化,即使在同一JVM内部,也必须进行远程方法调用。

>我自己写jndi.properties,存放在e:\javatest下,那么在classpath中是否添加一个路径为:e:\javatest\jndi.properties

不需要,你可以读读JNDI的Java源代码,配置文件是通过这样方式查找的(我进行简化了):

InputStream input = getClass().getClassLoader().getResourceAsStream("jndi.properties");

由于e:\javatest\已经在CLASSPATH里面,所以你放在e:\javatest\下面就可以了,不需要添加e:\javatest\jndi.properties,也不应该添加。(当然你也可以放在CLASSPATH定义的其他路径下)

>可能就是因为这个问题还没解决吧,我运行客户端程序后出现错误如下

我估计你的错误在于你不应该把j2sdkee的类库引入到CLASSPATH里面来,实际上j2ee只是一个接口规范而已,具体的实现由各个App Server厂商来实现,比如BEA Weblogic,IBM Websphere,Sun ONE 等等。而j2sdkee也有一个j2ee规范的实现,但是非常弱智,仅仅提供一个学习和实现的参考而已。由于你在CLASSPATH里面把j2sdkee的类库放到weblogic前面,而j2sdkee也有一个内置的弱弱的JNDI目录服务,所以你的客户端程序先找到了j2sdkee的JNDI实现类,而它企图去找j2sdkee的目录服务,而不是Weblogic的目录服务。

所以你把j2sdkee删掉就好了,顺便说一句,Weblogic里面j2ee该有的全有了,安装j2sdkee不但是多此一举,而且会导致类库使用的混乱。

trainking
2003-07-08 15:00
真的是非常非常感谢robbin耐心又详尽的解释,令我受益匪浅!同时也感谢ysxu和birdy.chen对我问题的热心回复!谢谢大家!

猜你喜欢