Staless Session Bean – EJB3
PDF version here
SESSIONBEAN – EJB3
Author: Võ Văn Hải
https://vovanhai.wordpress.com
I. Giới thiệu
Các bài viết giới thiệu về ejb3 thì google trên web sẽ cho kết quả đọc 100 năm không hết, ở đây tôi chỉ cho bạn từng bước thật cụ thể để cài đặt một ứng dụng.
Tất nhiên, việc thiết lập classpath của bạn là đầy đủ đến các thư viện jar của ejb3. Ở đây tôi thiết lập các tham số sau cho classpath:
%JBOSS_HOME%client\jboss-j2ee.jar;%JBOSS_HOME%client\jnp-client.jar; %JBOSS_HOME%client\jboss-common-client.jar; %JBOSS_HOME%client\concurrent.jar;%JBOSS_HOME%client\jboss-client.jar; %JBOSS_HOME%client\jboss-serialization.jar; %JBOSS_HOME%client\jboss-remoting.jar; %JBOSS_HOME%client\jbosssx-client.jar; %JBOSS_HOME%client\jboss-transaction-client.jar;% JBOSS_HOME%client\jbossall-client.jar; C:\javaSoft\javamail-1.4.1\mail.jar; %JBOSS_HOME%\client\jboss-ejb3x.jar;
II. Cài đặt
1. Tạo thư mục ConvertCurrency_EJB3. Tất cả bài demo được lưu ở đây.
2. Tạo file ConvertRemote.java có nội dung sau
package convert;
import javax.ejb.Remote;
@Remote public interface ConvertRemote { public double USD2VND(double usd); public double VND2USD(double vnd); } |
3. Tạo file ConvertBean.java có nội dung sau
package convert;
import javax.ejb.Stateless;
@Stateless public class ConvertBean implements ConvertRemote {
public double USD2VND(double usd) { return usd*16530; }
public double VND2USD(double vnd) { return vnd/16530; } } |
4. Tạo thư mục META-INF, sau đó tạo file jboss.xml trong thư mục này có nội dung như sau :
<?xml version=“1.0“ encoding=“UTF-8“?> <!DOCTYPE jboss PUBLIC “-//JBoss//DTD JBOSS 4.0//EN“ “http://www.jboss.org/j2ee/dtd/jboss_4_0.dtd“>
<jboss> <enterprise-beans> <session> <ejb-name>ConvertBean</ejb-name> <jndi-name>ConvertBeanEJB3</jndi-name> </session> </enterprise-beans> </jboss> |
III. Đóng gói và Triển Khai
1. Tạo file compile.bat có nội dung sau
javac -d . *.java pause |
Đảm bảo việc compile không có lỗi.
2. Tạo file createJAR.bat để tạo file jar có nội dung sau:
jar cvf ConvertEJB3.jar convert/*.class META-INF/*.xml pause |
3. Triển khai
Copy file ConvertEJB3.jar vào thư mục %JBOSS_HOME%\ C:\javaSoft\jboss-4.2.2.GA\server\default\deploy\
Kết quả ta có như sau :
… 20:21:48,784 INFO [JmxKernelAbstraction] creating wrapper delegate for: org.jbo ss.ejb3.stateless.StatelessContainer 20:21:48,784 INFO [JmxKernelAbstraction] installing MBean: jboss.j2ee:jar=ConvertEJB3.jar,name=ConvertBean,service=EJB3 with dependencies: 20:21:48,784 INFO [EJBContainer] STARTED EJB: convert.ConvertBean ejbName: ConvertBean 20:21:48,816 INFO [EJB3Deployer] Deployed: file:/C:/javaSoft/jboss-4.2.2.GA/ser ver/default/deploy/ConvertEJB3.jar … |
IV. Client application
1. Tạo thư mục client sau đó copy thư mục convert vào đấy
2. Tạo tập tin Client.java có nội dung sau
package client;
import javax.naming.Context; import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject;
import convert.ConvertRemote;
public class Client {
public static void main(String[] args) { try { System.setProperty( “java.naming.factory.initial”, “org.jnp.interfaces.NamingContextFactory” ); System.setProperty( “java.naming.provider.url”, “localhost:1099” ); System.setProperty( “java.naming.factory.url.pkgs”, “org.jboss.naming” );
Context ctx = new InitialContext(); Object obj = ctx.lookup(“ConvertBeanEJB3”);
ConvertRemote calc = (ConvertRemote) PortableRemoteObject.narrow(obj, ConvertRemote.class); double a = calc.USD2VND(2000); System.out.println(“=====================================”); System.out.println(“So tien chuyen doi:” + a); System.out.println(“=====================================”); } catch (Exception ex) { ex.printStackTrace(); } } } |
3. Tạo file compile.bat có nội dung sau
javac -d . *.java pause |
Chạy file này và đảm bảo không có lỗi nào
4. Tạo file run.bat có nội dung sau
java Client pause |
5. Thực thi file run.bat, kết quả ta được như sau
D:\Bai giang Aptech\Aptech – Semester 4\EJB 3\CalclatorSessionBeanEJB3\client>java Client ======================================== so tien chuyen doi:3.306E7 ========================================
D:\Bai giang Aptech\Aptech – Semester 4\EJB 3\CalclatorSessionBeanEJB3\client>pause Press any key to continue . . . |
V. Kết luận
Vậy, ta thấy EJB làm cho việc viết code trở nên hết sức dễ dàng, tất cả các phần mà trước đây trên ejb2x lập trình viên phải làm đã được chuyển cho container.
CHÚC CÁC BẠN THÀNH CÔNG!
truongat said
Chào anh, cho em hỏi, làm thế nào lookup() EJB3.0(JBoss 4.2) từ Struts 2 chạy trên tomcat. em làm hoài nhưng nó cứ báo lổi :
javax.servlet.ServletException: java.lang.RuntimeException: javax.naming.NoInitialContextException: Cannot instantiate class: org.jnp.interfaces.NamingContextFactory [Root exception is java.lang.ClassNotFoundException: org.jnp.interfaces.NamingContextFactory]
vovanhai said
Do bạn thiếu thư viện đến đối tượng NamingContextFactory. Nó ở trong gói %JBOSS_HOME%\client\jnp-client.jar. Bạn thêm nó vào classpath nhé!
Kaka said
Chào anh, hình như trong thư mục META-INF, còn thiếu 1 file Deployment Descriptor ejb-jar.xml (giống như trong EJB 2.0) thì phải, bởi vì khi em ko có file đó thì nó báo lỗi, còn khi em thêm file đó thì run tốt.
P/S: em đang dùng JBOSS 4.2.3
Anh check lại và confirm giùm em, thanks
Kaka said
Àh, với lại thực tế khi em làm cái ví dụ này, trong cái đống thư viện anh nêu ra đầu bài, thì khi compile chỉ cần gói jboss-ejb3x.jar và khi run phía Client thì cần thêm gói jbossall-client.jar là đủ rùi.
P/S: em ko dùng tool gì cả, làm bằng manual hoàn toàn, coding bằng notepad, đóng gói và run bằng console, copy bằng Ctrl_C + Ctrl_V, … 😀
Mong anh check lại và confirm giùm em, thanks.
vovanhai said
Không cần file ejb-jar.xml đâu. EJB3 mà!
vovanhai said
Thực tế với ví dụ đơn giản của tôi thì số lượng thư viện cần thiết không nhiều vậy. Nếu muốn chắc chắn vừa đủ cho ứng dụng của mình, bạn hãy xem gói jar kỹ là OK. Ý tôi là trong 1 vài trường hợp khác.
Kaka said
Ah, em hiểu vấn đề rùi, tại vì trong trường hợp của em thì tên lớp Bean (ConvertBean) ko giống như giá trị của thẻ trong file jboss.xml –> em chỉ cần sửa lại Annotations @Stateless(name=”xxx”), với xxx giống với giá trị của thẻ là ko cần sử dụng đến file ejb-jar.xml như anh đã nói, hihi.
Cám ơn anh đã giải đáp
P/S: anh có thể cho em nick chat YM để thuận tiện cho việc trao đổi hơn được ko a? Thanks
Kaka said
Ah, em hiểu vấn đề rùi, tại vì trong trường hợp của em thì tên lớp Bean (ConvertBean) ko giống như giá trị của thẻ tag ejb-name trong file jboss.xml –> em chỉ cần sửa lại Annotations @Stateless(name=”xxx”), với xxx giống với giá trị của thẻ tag ejb-name là ko cần sử dụng đến file ejb-jar.xml như anh đã nói, hihi.
Cám ơn anh đã giải đáp
P/S: anh có thể cho em nick chat YM để thuận tiện cho việc trao đổi hơn được ko a? Thanks
Thuck44b said
Chào anh Hải,
Anh ơi, khi em dùng servlet/jsp để triệu gọi EJB3 thì em gặp lỗi như sau :
“javax.naming.CommunicationException [Root exception is java.lang.ClassNotFoundException: agribank.ISessionBeanRemote (no security manager: RMI class loader disabled)]”
trong đó agribank là pakage,ISessionBeanRemote là interface, SessionBeanRemote là class thực thi các method của ISessionBeanRemote và em dùng JBoss 4.0 for EJB 3.0
Khi gọi EJB thì em gọi như sau:
Properties env = new Properties();
env.setProperty(“java.naming.factory.initial”, “org.jnp.interfaces.NamingContextFactory”);
env.setProperty(“java.naming.provider.url”, “localhost:1099”);
env.setProperty(“java.naming.factory.url.pkgs”, “org.jboss.naming”);
Context context = new InitialContext(env);
//==========
// context=new InitialContext();
//InitialContext context=new InitialContext();
String name=”SessionBean/remote”;
Với SessionBean là ejb name khi em srtart JBoss.
ISessionBeanRemote sessionBean=(ISessionBeanRemote)context.lookup(name);
Anh làm ơn giải đáp giúp em nhé, em làm mất mấy tuần rồi mà vẫn chưa làm được, thanhks anh nhiều!
Em ThucHP
vovanhai said
gửi nguyên bài của bạn cho tôi vào mail vovanhaiqn@gmail.com, tui xem sao!
Thuyit said
anh Hải ơi, em làm như ví dụ trên của anh nhưng bị lỗi như thế này:
javax.naming.CommunicationException: Receive timed out [Root exception is java.net.SocketTimeoutException: Receive timed out]
at org.jnp.interfaces.NamingContext.discoverServer(NamingContext.java:1465)
at org.jnp.interfaces.NamingContext.checkRef(NamingContext.java:1594)
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:634)
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:627)
at javax.naming.InitialContext.lookup(Unknown Source)
at client.Client.main(Client.java:23)
Caused by: java.net.SocketTimeoutException: Receive timed out
at java.net.PlainDatagramSocketImpl.receive0(Native Method)
at java.net.PlainDatagramSocketImpl.receive(Unknown Source)
at java.net.DatagramSocket.receive(Unknown Source)
at org.jnp.interfaces.NamingContext.discoverServer(NamingContext.java:1435)
… 5 more
anh làm ơn giải đáp giúp em, em làm mấy hôm mà chưa được
vovanhai said
Lỗi nó báo là hết thời gian. Lỗi tại dòng 23 của client: Object obj = ctx.lookup(“ConvertBeanEJB3″) là do nó lookup không thấy cái bean của em. Em xem xét lại việc triển khai của em sao. Em chú ý file jboss.xml chỗ thẻ: ConvertBeanEJB3. Nếu em bỏ luôn file jboss.xml này thì tên bean lookup bay giờ phải là :Object obj = ctx.lookup(“ConvertBeanEJB3/remote″). Chúc vui!
hoangthuy said
Cho em hoi cach tao file .bat la nhu the nao vay a?
Em cam on nhieu!!!
vovanhai said
Mở notepad ra mà gõ
duy khanh said
em chào anh!
ở ví dụ trên anh dùng jboss, nhưng em lại dùng glassfish
vậy em phải sửa chỗ này như thế nào?
System.setProperty(“java.naming.factory.initial”,”org.jnp.interfaces.NamingContextFactory”);
System.setProperty( “java.naming.provider.url”,”localhost:1099″);
System.setProperty(“java.naming.factory.url.pkgs”,”org.jboss.naming”);
Và dùng thêm thư viện nào nữa ah.
thank anh nhiều.
Võ Văn Hải said
Dùng GlassFish thì bạn dùng annotaion @EJB, khỏi cần thêm gì nữa.
duy khanh said
em làm được roài, thank anh nhiều
van cao said
Dear anh Hai
Em chưa hiểu lắm cái annotaion @EJB dùng để làm gì. Anh giải thích giúp em với ạ. Có phải chỉ dùng GlassFish thì mới dùng được cái này thôi không. Nếu dùng cái này rồi thì em deploy server và client trên 2 máy khác nhau kiểu gì vì có thấy mô tả server với port nằm ở đâu đâu ạ.
Regards
หนังxxx said
I was suggested this web site by my cousin. I’m not
sure whether or not this submit is written by means of him as no one else recognize such precise approximately my problem.
You’re amazing! Thanks!