转自http://theopentutorials.com/examples/java-ee/ejb3/how-to-create-ejb3-mdb-project-in-eclipse-jboss-7-1/
Environment Used
- JDK 6 (Java SE 6)
- JMS Sender/Client – Servlet 2.5 API
- JMS Consumer – EJB 3.0 Message Driven Bean (MDB)
- Eclipse Indigo IDE for Java EE Developers (3.7.1)
- JBoss Tools – Core 3.3.0 M5 for Eclipse Indigo (3.7.1)
- JBoss Application Server (AS) 7.1.0 Final
Setting up development environment:
Read this page for installing and setting up the environment for developing and deploying EJB 3.0 Session bean on JBoss application server.
Project Description
- We are going to create a simple EJB 3 Message Driven Bean and a Web client (Servlet) which sends messages to the Queue destination.
- This example explains how to develop, deploy and run EJB3 MDB as a message consumer in JBoss application server.
- For testing this MDB listener we write a Web client (a servlet) as a message producer which sends a simple text message and an object message.
- The message driven bean (message consumer) and the Servlet (message producer) are deployed on the same server instance (JBoss AS).
Creating New EJB Project
- Open Eclipse IDE and create a new EJB project which can be done in three ways,
- Right click on Project Explorer -> New -> EJB Project
- File menu -> New -> EJB Project
- Click on the down arrow on New icon on toolbar -> EJB Project
- Enter the project name as “FirstMDBProject” and make sure the JBoss 7.1 Runtime has been selected with the EJB 3.0 Module version.
- This project uses Java 1.6 version. The default Java version in Eclipse Indigo is 1.7 so to change the “Configuration” click on “Modify…” button to make changes.
- Click Next -> Next -> and Finish.
- You will see an EJB project in the Project Explorer view.
Creating object message class
- Right click on ejbModule -> New -> Class
- Enter the Java package name as com.theopentutorials.mdb.to
- Enter the Class name as Employee
- Click “Finish“
Copy the following code:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
package
com.theopentutorials.mdb.to;
import
java.io.Serializable;
public
class
Employee
implements
Serializable {
private
int
id;
private
String name;
private
String designation;
private
double
salary;
public
Employee() { }
public
Employee(
int
id, String name, String designation,
double
salary)
{
this
.id = id;
this
.name = name;
this
.designation = designation;
this
.salary = salary;
}
public
int
getId() {
return
id;
}
public
void
setId(
int
id) {
this
.id = id;
}
public
String getName() {
return
name;
}
public
void
setName(String name) {
this
.name = name;
}
public
String getDesignation() {
return
designation;
}
public
void
setDesignation(String designation) {
this
.designation = designation;
}
public
double
getSalary() {
return
salary;
}
public
void
setSalary(
double
salary) {
this
.salary = salary;
}
@Override
public
String toString() {
return
"Employee [id="
+ id +
", name="
+ name +
", designation="
+ designation +
", salary="
+ salary +
"]"
;
}
}
|
Creating Message Driven Bean Consumer
- Right click on ejbModule -> New -> Message-Driven Bean (EJB 3.x)
- Enter the Java package name as com.theopentutorials.mdb
- Enter the Class name as QueueListenerMDB
- Select the Destination type as Queue
- Click “Finish“
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
package
com.theopentutorials.mdb;
import
java.util.Date;
import
javax.ejb.ActivationConfigProperty;
import
javax.ejb.MessageDriven;
import
javax.jms.JMSException;
import
javax.jms.Message;
import
javax.jms.MessageListener;
import
javax.jms.ObjectMessage;
import
javax.jms.TextMessage;
import
com.theopentutorials.mdb.to.Employee;
@MessageDriven
(activationConfig = {
@ActivationConfigProperty
(
propertyName =
"destinationType"
, propertyValue =
"javax.jms.Queue"
),
@ActivationConfigProperty
(
propertyName =
"destination"
, propertyValue =
"queue/MyQueue"
) })
public
class
QueueListenerMDB
implements
MessageListener {
public
QueueListenerMDB() {
}
public
void
onMessage(Message message) {
try
{
if
(message
instanceof
TextMessage) {
System.out.println(
"Queue: I received a TextMessage at "
+
new
Date());
TextMessage msg = (TextMessage) message;
System.out.println(
"Message is : "
+ msg.getText());
}
else
if
(message
instanceof
ObjectMessage) {
System.out.println(
"Queue: I received an ObjectMessage at "
+
new
Date());
ObjectMessage msg = (ObjectMessage) message;
Employee employee = (Employee) msg.getObject();
System.out.println(
"Employee Details: "
);
System.out.println(employee.getId());
System.out.println(employee.getName());
System.out.println(employee.getDesignation());
System.out.println(employee.getSalary());
}
else
{
System.out.println(
"Not a valid message for this Queue MDB"
);
}
}
catch
(JMSException e) {
e.printStackTrace();
}
}
}
|
- The activationConfig property of @MessageDriven is an array of ActivationConfigProperty and it should specify the destinationType (Queue or Topic) and destination (Queue/Topic’s JNDI name).
- In the onMessage() we are receiving two types of message, TextMessage and ObjectMessage.
Configuring messaging services on JBoss AS 7
In the previous version of JBoss AS we had an option to configure the messaging destinations (Queue or Topic) in META-INF/*-service.xml with element. In JBoss AS 7, it is configured in main application server configuration file (standalone.xml) which is found in JBossAS_Home/standalone/configuration.
- Open standalone.xml and follow the steps below to configure messaging services.
Add entension element
Add
1
|
<
extension
module
=
"org.jboss.as.messaging"
/>
|
in the <extensions> element.
Add subsystem element
Add the following <subsystem> inside <profile> element.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
<
subsystem
xmlns
=
"urn:jboss:domain:messaging:1.1"
>
<
hornetq-server
>
<
persistence-enabled
>true</
persistence-enabled
>
<
journal-file-size
>102400</
journal-file-size
>
<
journal-min-files
>2</
journal-min-files
>
<
connectors
>
<
netty-connector
name
=
"netty"
socket-binding
=
"messaging"
/>
<
netty-connector
name
=
"netty-throughput"
socket-binding
=
"messaging-throughput"
>
<
param
key
=
"batch-delay"
value
=
"50"
/>
</
netty-connector
>
<
in-vm-connector
name
=
"in-vm"
server-id
=
"0"
/>
</
connectors
>
<
acceptors
>
<
netty-acceptor
name
=
"netty"
socket-binding
=
"messaging"
/>
<
netty-acceptor
name
=
"netty-throughput"
socket-binding
=
"messaging-throughput"
>
<
param
key
=
"batch-delay"
value
=
"50"
/>
<
param
key
=
"direct-deliver"
value
=
"false"
/>
</
netty-acceptor
>
<
in-vm-acceptor
name
=
"in-vm"
server-id
=
"0"
/>
</
acceptors
>
<
security-settings
>
<
security-setting
match
=
"#"
>
<
permission
type
=
"send"
roles
=
"guest"
/>
<
permission
type
=
"consume"
roles
=
"guest"
/>
<
permission
type
=
"createNonDurableQueue"
roles
=
"guest"
/>
<
permission
type
=
"deleteNonDurableQueue"
roles
=
"guest"
/>
</
security-setting
>
</
security-settings
>
<
address-settings
>
<
address-setting
match
=
"#"
>
<
dead-letter-address
>jms.queue.DLQ</
dead-letter-address
>
<
expiry-address
>jms.queue.ExpiryQueue</
expiry-address
>
<
redelivery-delay
>0</
redelivery-delay
>
<
max-size-bytes
>10485760</
max-size-bytes
>
<
address-full-policy
>BLOCK</
address-full-policy
>
<
message-counter-history-day-limit
>10</
message-counter-history-day-limit
>
</
address-setting
>
</
address-settings
>
<
jms-connection-factories
>
<
connection-factory
name
=
"InVmConnectionFactory"
>
<
connectors
>
<
connector-ref
connector-name
=
"in-vm"
/>
</
connectors
>
<
entries
>
<
entry
name
=
"java:/ConnectionFactory"
/>
</
entries
>
</
connection-factory
>
<
connection-factory
name
=
"RemoteConnectionFactory"
>
<
connectors
>
<
connector-ref
connector-name
=
"netty"
/>
</
connectors
>
<
entries
>
<
entry
name
=
"RemoteConnectionFactory"
/>
<
entry
name
=
"java:jboss/exported/jms/RemoteConnectionFactory"
/>
</
entries
>
</
connection-factory
>
<
pooled-connection-factory
name
=
"hornetq-ra"
>
<
transaction
mode
=
"xa"
/>
<
connectors
>
<
connector-ref
connector-name
=
"in-vm"
/>
</
connectors
>
<
entries
>
<
entry
name
=
"java:/JmsXA"
/>
</
entries
>
</
pooled-connection-factory
>
</
jms-connection-factories
>
<
jms-destinations
>
<
jms-queue
name
=
"testQueue"
>
<
entry
name
=
"queue/MyQueue"
/>
</
jms-queue
>
<
jms-topic
name
=
"testTopic"
>
<
entry
name
=
"topic/MyTopic"
/>
</
jms-topic
>
</
jms-destinations
>
</
hornetq-server
>
</
subsystem
>
|
The entry name for jms-queue should match the destination activation config property in @MessageDriven.
Add messaging port
In <socket-binding-group> add these two elements
1
2
|
<
socket-binding
name
=
"messaging"
port
=
"5445"
/>
<
socket-binding
name
=
"messaging-throughput"
port
=
"5455"
/>
|
Add MDB Resource Adapter Reference
Under <subsystem xmlns=”urn:jboss:domain:ejb3:1.2″> add this <mdb> element
1
2
3
4
|
<
mdb
>
<
resource-adapter-ref
resource-adapter-name
=
"hornetq-ra"
/>
<
bean-instance-pool-ref
pool-name
=
"mdb-strict-max-pool"
/>
</
mdb
>
|
Deploying EJB project
- Now we need to deploy the EJB project “FirstMDBProject” on server..
- Deploying the project can be done in two ways,
- Right click on the EJB project -> Run As -> Run On Server. Select the existing “JBoss 7.1 Runtime Server” and click Finish.
- Right click on “JBoss 7.1 Runtime Server” available in Servers view -> Add and Remove… -> Select the EJB JAR file from the left pane and click Add-> and then Finish.
Start/Restart the Server
Right click on “JBoss 7.1 Runtime Server” from Servers view and click on Start if it has not yet been started.
If the project is deployed properly with global JNDI mapping then you will see the following message in the console.
Bound messaging object to jndi name java:/queue/MyQueue
Started message driven bean ‘QueueListenerMDB’ with ‘hornetq-ra’ resource adapter
Deployed “FirstMDBProject.jar”
Creating JMS client (Dynamic Web Project)
- The next step is to write a Web Client (a Servlet) which produces the message and sends to the Queue.
- The servlet uses JNDI to lookup ConnectionFactory and the Queue.
- Creating a new ‘Dynamic Web project’ can be done in three ways,
- Right click on Project Explorer -> New -> Dynamic Web Project
- File menu -> New -> Dynamic Web Project
- Click on the down arrow on New icon on toolbar -> Dynamic Web Project
- Enter the project name as “MDBWebClient” and make sure the JBoss 7.1 Runtime has been selected with the Dynamic web module version as 2.5.
- This project uses Java 1.6 version. The default Java version in Eclipse Indigo is 1.7 so to change the “Configuration” click on “Modify…” button to make changes.
- Click “Next” -> “Next” -> and “Finish”.
- You will see the Dynamic web project in the “Project Explorer” view.
To send object message servlet needs Employee class which we have created in FirstMDBProject.
Creating JAR file
- Right click on Employee.java file in FirstMDBProject -> Export.
- Expand Java folder and select “JAR file” and click Next.
- Click on Browse… and enter the file name and Finish.
Now copy the created JAR file and paste it in MDBWebClient/WebContent/WEB-INF/lib folder.
Creating Servlet class
- Right click on src or Project -> New -> Servlet
- Enter the Java package name as com.theopentutorials.servlets
- Enter the Class name as ServletMessageProducer
- Click “Finish“
In the doGet() method copy the following code.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
package
com.theopentutorials.servlets;
import
java.io.IOException;
import
java.io.PrintWriter;
import
javax.jms.ObjectMessage;
import
javax.jms.Queue;
import
javax.jms.QueueConnection;
import
javax.jms.QueueConnectionFactory;
import
javax.jms.QueueSender;
import
javax.jms.QueueSession;
import
javax.jms.TextMessage;
import
javax.naming.Context;
import
javax.naming.InitialContext;
import
javax.servlet.ServletException;
import
javax.servlet.http.HttpServlet;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
com.theopentutorials.mdb.to.Employee;
public
class
ServletMessageProducer
extends
HttpServlet {
private
static
final
long
serialVersionUID = 1L;
public
ServletMessageProducer() {
super
();
}
protected
void
doGet(HttpServletRequest request,
HttpServletResponse response)
throws
ServletException, IOException {
final
String QUEUE_LOOKUP =
"queue/MyQueue"
;
final
String CONNECTION_FACTORY =
"ConnectionFactory"
;
PrintWriter out = response.getWriter();
try
{
Context context =
new
InitialContext();
QueueConnectionFactory factory =
(QueueConnectionFactory)context.lookup(CONNECTION_FACTORY);
QueueConnection connection = factory.createQueueConnection();
QueueSession session =
connection.createQueueSession(
false
,
QueueSession.AUTO_ACKNOWLEDGE);
Queue queue = (Queue)context.lookup(QUEUE_LOOKUP);
QueueSender sender = session.createSender(queue);
//1. Sending TextMessage to the Queue
TextMessage message = session.createTextMessage();
message.setText(
"Hello EJB3 MDB Queue!!!"
);
sender.send(message);
out.println(
"1. Sent TextMessage to the Queue"
);
//2. Sending ObjectMessage to the Queue
ObjectMessage objMsg = session.createObjectMessage();
Employee employee =
new
Employee();
employee.setId(
2163
);
employee.setName(
"Kumar"
);
employee.setDesignation(
"CTO"
);
employee.setSalary(
100000
);
objMsg.setObject(employee);
sender.send(objMsg);
out.println(
"2. Sent ObjectMessage to the Queue"
);
session.close();
}
catch
(Exception e){e.printStackTrace();}
}
}
|
Deploying Dynamic Web Project
- Now we need to deploy the servlet’s project “MDBWebClient” on server.
- Deploying the project can be done in two ways,
- Right click on the “MDBWebClient” Dynamic Web project -> Run As -> Run On Server. Select the existing “JBoss 7.1 Runtime Server” and click Finish.
- Right click on “JBoss 7.1 Runtime Server” available in Servers view -> Add and Remove… -> Select the WAR file from the left pane and click Add-> and then Finish.
Start/Restart the Server
- Right click on “JBoss 7.1 Runtime Server” from Servers view and click on Start if it has not yet been started.
- If the projects are deployed properly then you will see the following message in the console.
Deployed “MDBWebClient.war”
Deployed “FirstMDBProject.jar”
Folder Structure
The figure below shows the final directory structure of EJB project “FirstMDBProject”.
The figure below shows the final directory structure of Dynamic Web project “MDBWebClient”
Run the Servlet
- Use Ctrl + F11 to run the Servlet and select the existing JBoss Runtime Server and Finish.
- The URL for requesting Servlet ishttp://localhost:8080/MDBWebClient/ServletMessageProducer
Eclipse Internal Web Browser will display the following output
JBoss Runtime Server Console will display the following output.
[stdout] Queue: I received a TextMessage at Fri Feb 17 18:03:41 IST 2012
[stdout] Message is : Hello EJB3 MDB Queue!!!
[stdout] Queue: I received an ObjectMessage at Fri Feb 17 18:03:41 IST 2012
[stdout] Employee Details:
[stdout] 2163
[stdout] Kumar
[stdout] CTO
[stdout] 100000.0