Thursday, 2 July 2009

Three Tier Web Service Tutorial

This tutorial describes how you can use NetBeans IDE 6.5.1 to create a mobile client application that consumes a web service that you have already created before. The mechanics of this tutorial are taken from the
End-to-End Web Service Tutorial: Mobile Dilbert Application
http://www.netbeans.org/kb/60/mobility/mobile-dilbert.html
but the canvas and graphics related elements are excluded. Instead of using the Gilbert web service I used CalcARSWS which I produced changing the addition operation to maultiplication at the standard Net Beans example named Calculator.

1. Step: Create a web application, and then create a web service in it according to the below info:
package ars;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

/**
*
* @author Ali Riza SARAL
*/
@WebService()
public class CalcARSWS {
/**
* Web service operation
*/
@WebMethod(operationName = "multiply")
public int multiply(@WebParam(name = "i") int i, @WebParam(name = "j") int j) {
return i * j;
}
}

2. Step: Create a Web Service Client named ThreeTierARS App according to the info you may find at Dilbert example: You simply run the app in the first step, CalcARSApp and find the absolute URL. You enter this WSDL URL into the related location at the second step.

3. Step: You create a simple mobile application ThreeTierARSClient which has ThreeTierARSMIDlet.java in it. You also create a Mobile Client To Webapplicaiton similar to the Dilbert application. Different to the Dilbert application this ThreeTierARSApp calls multiply(2,2) method of the CalcARSWS web service that resides in the CalcARSApp… To achieve this you make the follwing changes in the ThreeTiersARSMIDlet.java file.
public SimpleCancellableTask getTask() {
if (task == null) {
// write pre-init user code here
task = new SimpleCancellableTask();
task.setExecutable(new org.netbeans.microedition.util.Executable() {
public void execute() throws Exception {
// write task-execution user code here

ThreeTierARSClient client = new ThreeTierARSClient();
try{
int multiply_returnValue = client.multiply(2,2);
textField.setString(String.valueOf(multiply_returnValue));
}
catch(java.io.IOException e){
System.out.println(e.toString());
}
}
});
// write post-init user code here
}


And;

public void startMIDlet() {
// write pre-action user code here
switchDisplayable(null, getSplashScreen());
// write post-action user code here
textField=getTextField();
}

At one point somewhere here it gave the error message:
…Wrapper class ars.MultiplyResponse is not found. Have you run APT to generate them?

I clicked on the ThreeTierARSClient.wsclient and did ‘Generate’…
It still did not work. I shut down the netbeans and restarted it. I deployed
CalcARSApp and then ThreeTierARSApp and ran the ThreeTierARSClient.
It worked. If you are interested to see the source files they are available on demand
from arsaral( at ) yahoo.com.

Kind regards.
Note: Do not forget to deploy the apps that include the webservices you use before trying to make any references to them.

Friday, 29 May 2009

4-How to setup a JMS queue with also JTA processing

WEBLOGIC JMS queue setup

1- I build the EJB outside the Jdev environment, at C:\JTAdistrib with build.xml
The output goes to C:\ JTAdistrib\ deploy\ JTAdis. jar

2- Then I deployed the EJB with WebLogic Console
Deployments->lock-edit->install
Path: C:\ JTAdistrib\ deploy\ JTAdis. Jar

3- Services->Messaging->JMSservers -> Lock-Edit -> new
Name: RegistrarQ
Targets: DefaultServer

4- Services->Messaging->JMSmodules -> Lock-Edit -> new
Name: jms/QCF

Summary of resources

Name………….…
Type…………………..JNDI Name ……….Subdeployment…………………..Targets
jms/QCF…………Connection Factory…ConnectionFactory…Default Targetting……………….DefaultServer
jms/RegistrarQ..Queue………………RegistrarQ……….jms/RegistrarQsubDeploy…..RegistrarQ



Name: jms/RegistrarQ
Subdeployment: jms/RegistrarQsubdeploy
Destination: RegistrarQ
Monitoring: jms/QCF!jms/RegistrarQ (This is only an output field – I put it here for for checking)
Control: jms/QCF!jms/RegistrarQ (This is only an output field – I put it here for for checking)

Name: jms/QCF
JNDI name: ConnectionFactory
Target: DefaultServer

Do not play with the WebLogic – console parameters. If you need you may change the logging parameters to see more info. But TINTPB’s this example works almost fine specially with the ejb-jar xml files, you just have to make the jms setup work. Please note the sequence of the definitions made with weblogic console. Be carefull about the JNDI names also. Avoid giving the same name to different things, give a unique name to every different thing.

javax.naming.NameNotFoundException: While trying to lookup 'javax.jms.Queue.class' didn't find subcontext 'Queue'.

This error is given when the queue destination has not been made. It looks as if it is a JNDI error but actually the object that the JNDI is supposed to point at does not exist. It gives the same error message to both.

The output to the program is below:

<May 28, 2009 10:45:54 PM EEST> <Notice> <Stdout> <BEA-000000> <Connecting to JDBC data store...>
<May 28, 2009 10:45:54 PM EEST> <Notice> <Stdout> <BEA-000000> <Begin JTA distributed transaction. . .>
<May 28, 2009 10:45:54 PM EEST> <Notice> <Stdout> <BEA-000000> <Trying to drop table StudentCourse...>
<May 28, 2009 10:45:54 PM EEST> <Notice> <Stdout> <BEA-000000> <Table StudentCourse dropped successfully...>
<May 28, 2009 10:45:54 PM EEST> <Notice> <Stdout> <BEA-000000> <Created new StudentCourse table.>
<May 28, 2009 10:45:54 PM EEST> <Notice> <Stdout> <BEA-000000> <A new record is inserted into table StudentCourse. . .>
<May 28, 2009 10:45:54 PM EEST> <Notice> <Stdout> <BEA-000000> <Connecting to JMS destination...>
<May 28, 2009 10:45:54 PM EEST> <Notice> <Stdout> <BEA-000000> <Notify registration...>
<May 28, 2009 10:45:56 PM EEST> <Notice> <Stdout> <BEA-000000> <Message sent: Student id=1 is enrolled in course=CS310>
<May 28, 2009 10:45:57 PM EEST> <Notice> <Stdout> <BEA-000000> <Committing the transaction. . .>
<May 28, 2009 10:46:09 PM EEST> <Warning> <JMSPool> <BEA-169817> <The JMS connection factory resource ConnectionFactory declared in the EJB "RegistrarMDB" as part of application "JTAdis" does not support XA. It cannot be used inside a transaction context.>

Please note that in order to see this output you must have set up the sensitivity of the defaultserver’s logging to the notice level.

With this example I have completed tinptB ‘s Blog: EJB in 21 Days: which includes almost all aspects of EJB programming. My gratitude goes to him/her. I would be happy if I could contribute just a bit by providing the solutions to all of his open end questions by the way.

Cheers.

Ali R+ SARAL

3-How to setup a JMS queue with also JTA processing

FILE: Client.java
import javax.naming.*;
import javax.rmi.PortableRemoteObject;

import jtadistrib.UserManager;
import jtadistrib.UserManagerHome;

public class Client {
public static void main(String argv[]) {
// A simple client deligates the UserManager session bean
// to perform a JTA transaction. The JTA transaction will
// be started in one method, then the context will be
// propagated to other methods of the bean. Multiple resources:
// a JDBC and a JMS resource manager are invloved in the
// same distributed transaction.
System.out.print("Demonstration the use of JTA \n");
try {
InitialContext ctx = new InitialContext();
Object obj = ctx.lookup("jtadistrib/UserManagerHome");
UserManagerHome userHome = (UserManagerHome)
PortableRemoteObject.narrow(obj, UserManagerHome.class);
UserManager user = userHome.create();
// Delegate a UserManager to start a JTA transaction
System.out.println("\nStart global transaction...");
user.connectUserManager();
// Connect to a JDBC DataSource and add the enrolled course
System.out.println("Adding courses to database...");
user.addCourse(1, "CS310");
// Connect to a JMS destination and send a message
System.out.println("Notifying registrar queue...");
user.notifyRegistrar(1, "CS310");
// Commit the JTA transaction and release resources
Thread.sleep(1000);
System.out.println("Committing transaction...");
user.disconnectUserManager();
} catch(Exception e) {
System.err.println(e.toString());
}
}
}

FILE: jndi.properties
java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
java.naming.factory.url.pkgs=weblogic.jndi.factories:weblogic.corba.j2ee.naming.url:weblogic.corba.client.naming
java.naming.provider.url=t3://localhost:7101
java.naming.security.principal=weblogic
java.naming.security.credentials=weblogic

FILE: build.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<project name="EJB3 Tutorial" basedir="." default="deploy">

<property name="deploy.dir" value="C:/JTAdistrib/deploy" />
<property name="sourcedir" value="${basedir}/src"/>
<property name="targetdir" value="${basedir}/build"/>
<property name="librarydir" value="${basedir}/lib"/>

<path id="libraries">
<fileset dir="${librarydir}">
<include name="*.jar"/>
</fileset>
</path>

<target name="clean">
<delete dir="${targetdir}"/>
<mkdir dir="${targetdir}"/>
</target>

<target name="compile" depends="copy-resources">
<javac srcdir="${sourcedir}"
destdir="${targetdir}"
classpathref="libraries"
debug="on">
<compilerarg value="-Xlint"/>
</javac>
</target>
<target name="copy-resources">
<copy todir="${targetdir}">
<fileset dir="${sourcedir}">
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>

<target name="deploy" description="JARs the Task" depends="clean,copy-resources,compile">
<jar destfile="${deploy.dir}/JTAdis.jar">
<metainf dir="${sourcedir}/META-INF" />
<fileset dir="${targetdir}">
<include name="**/*.class" />
</fileset>
</jar>
</target>

<target name="undeploy" description="Undeploy jar from server">
<delete file="${deploy.dir}/JTAdis.jar" />
</target>

<target name="run" depends="compile">
<java classname="Client" classpathref="libraries">
<classpath path="${targetdir}"/>
<jvmarg value="-Djava.library.path=./lib"/>
</java>
</target>
</project>

2- How to setup a JMS queue with also JTA processing

FILE: ejb-jar.xml
<?xml version="1.0"?>

<!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>
<ejb-name>UserManager</ejb-name>
<home>jtadistrib.UserManagerHome</home>
<remote>jtadistrib.UserManager</remote>
<ejb-class>jtadistrib.UserManagerBean</ejb-class>
<session-type>Stateful</session-type>
<transaction-type>Bean</transaction-type>
<resource-env-ref>
<resource-env-ref-name>styejbDB</resource-env-ref-name>
<resource-env-ref-type>javax.sql.DataSource</resource-env-ref-type>
</resource-env-ref>
<resource-env-ref>
<resource-env-ref-name>jms/RegistrarQ</resource-env-ref-name>
<resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
</resource-env-ref>
</session>
<message-driven>
<ejb-name>RegistrarMDB</ejb-name>
<ejb-class>jtadistrib.RegistrarMDB</ejb-class>
<transaction-type>Container</transaction-type>
<message-driven-destination>
<destination-type>javax.jms.Queue</destination-type>
</message-driven-destination>
<resource-ref>
<res-ref-name>jms/QCF</res-ref-name>
<res-type>javax.jms.QueueConnectionFactory</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</message-driven>
</enterprise-beans>
</ejb-jar>

FILE: weblogic-ejb-jar.xml
<?xml version="1.0"?>
<!DOCTYPE weblogic-ejb-jar PUBLIC
'-//BEA Systems, Inc.//DTD WebLogic 6.0.0 EJB//EN'
'http://www.bea.com/servers/wls600/dtd/weblogic-ejb-jar.dtd'>

<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>UserManager</ejb-name>
<reference-descriptor>
<resource-env-description>
<res-env-ref-name>styejbDB</res-env-ref-name>
<jndi-name>styejbDB</jndi-name>
</resource-env-description>
<resource-env-description>
<res-env-ref-name>jms/RegistrarQ</res-env-ref-name>
<jndi-name>RegistrarQ</jndi-name>
</resource-env-description>
</reference-descriptor>
<jndi-name>jtadistrib/UserManagerHome</jndi-name>
</weblogic-enterprise-bean>
<weblogic-enterprise-bean>
<ejb-name>RegistrarMDB</ejb-name>
<message-driven-descriptor>
<pool>
<max-beans-in-free-pool>5</max-beans-in-free-pool>
<initial-beans-in-free-pool>1</initial-beans-in-free-pool>
</pool>
<destination-jndi-name>RegistrarQ</destination-jndi-name>
</message-driven-descriptor>
<reference-descriptor>
<resource-description>
<res-ref-name>jms/QCF</res-ref-name>
<jndi-name>ConnectionFactory</jndi-name>
</resource-description>
</reference-descriptor>
<jndi-name>RegistrarQ</jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>

1- How to setup a JMS queue with also JTA processing

This note is about setting up a JMS queue… It is based on Understanding J2EE Transactions example of tinptB ‘s Blog: EJB in 21 Days: http://ejbvn.wordpress.com/ I appreciate her excellent English, which makes a soothing effect while trying to break through difficulties.

TINPTB’s work for the 16th Day includes all files that is necessary for this example but misses tha JMS setup part naturally, because it changes according to the application server you use. In addition to his work I added the home and interface files to his RegistrarMDB. You can find the JMS setup at the bottom.

Without any further aloboration, follows my solution below full and completely working with: Jdeveloper 11g(only the client not the deployment), WebLogic10.3, wlfullclient5, apache-ant-1.7.1 and mysql-essential-5.1.30-win32, mysql-connector-java-5.0.8 and Toad for MySQL 4.1 Freeware.

FILE: RegistrarHome.java
package jtadistrib;

import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;

public interface RegistrarHome extends EJBHome{
Registrar create() throws CreateException, RemoteException;
}

FILE: Registrar.java
package jtadistrib;

import java.rmi.RemoteException;

public interface Registrar extends javax.ejb.EJBObject{
}

FILE: RegistrarMDB.java
package jtadistrib;

import javax.ejb.MessageDrivenBean;
import javax.ejb.MessageDrivenContext;
import javax.ejb.EJBException;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
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.InitialContext;
import javax.naming.NamingException;
public class RegistrarMDB implements MessageDrivenBean, MessageListener{
private MessageDrivenContext mctx =null;
public void setMessageDrivenContext(MessageDrivenContext ctx) {mctx = ctx;}
public void ejbCreate() {
System.out.println("Instance of RegistrarMDB is created...");
}
public void ejbRemove() {}

public void onMessage(Message message) {
System.out.println("RegistrarMDB.onMessage: started..");
try {
TextMessage msg = (TextMessage)message;
System.out.println("RegistrarMDB: Registrar received message: " +
msg.getText());
} catch(JMSException e) {
e.printStackTrace();
}
}
}

Thursday, 21 May 2009

6-How to Develop Message-Driven Beans

Weblogic JMS setup follows:

For deploying EJB:
You first run ANT in the MDBentity directory – namely you run the build.xml
You have the output in the C:\MDBentity\deploy directory.
You select Deployments in the Domain Structure section on the left…
You select install and it goes on from there….
If you can not do this, please refere to my WLST script tha you can find in the other EJB entries
in this blog.

To define the JMS:
Select Services in the Domain Structure Section on the left…
Select messaging
Select JMS Servers
Select new Name:styejbJMS target:DefaultServer


DO NOT PLAY WITH THE PARAMETERS – Use MINIMUM CHANGES.

To define the Topic:
Select Services in the Domain Structure Section on the left…
Select messaging
Select JMS Modules
Select new
Name:OrderVerifierARS
Summary of Resources: Name:OrderVerifierTopic JNDIName:OrderVerifierTopic
SubDeployment: styejbJMS

WARNING: 1- I had some problems in running the example. It seemed as if onMessage did not work… Also, as if, I must start the MDB manually just after the DefaultServer startup??? But at the end it worked without really being aware of how it happened really. I also changed to
String connectionFactoryJndiName = "weblogic.jms.ConnectionFactory"; from the older
javax.jms.TopicConnectionFactory…

2- Playing with the console setups related to logging can be helpful in seeing more information in the logs.
The System.out.println commands in the EJBs are printed into the Running - server log which you can switch to from the Running - application log simply at the bottom right section of the Jdev.

3- There is also the monitoring options at the top of the DefaultDomain – Deployments window.
You can select your EJB and select monitoring and see its status – very useful.

The outputs of the logs follows:
Default Server LOG

<May 21, 2009 2:59:50 PM EEST> <Notice> <Stdout> <BEA-000000> <setEntityContext called>
<May 21, 2009 2:59:50 PM EEST> <Notice> <Stdout> <BEA-000000> <ejbPostCreate() called.>
<May 21, 2009 2:59:50 PM EEST> <Notice> <Stdout> <BEA-000000> <ejbCreate() called.>
<May 21, 2009 2:59:50 PM EEST> <Notice> <Stdout> <BEA-000000> <ejbStore() called.>
<May 21, 2009 2:59:51 PM EEST> <Notice> <Stdout> <BEA-000000> <ejbLoad() called.>
<May 21, 2009 2:59:51 PM EEST> <Notice> <Stdout> <BEA-000000> <ejbStore() called.>
<May 21, 2009 2:59:51 PM EEST> <Notice> <Stdout> <BEA-000000> <************ Order Information ************>
<May 21, 2009 2:59:51 PM EEST> <Notice> <Stdout> <BEA-000000> <****ARSSSSSSSSSSssssssss Order Id is : 1242907190421>
<May 21, 2009 2:59:51 PM EEST> <Notice> <Stdout> <BEA-000000> <************ Order Information Ends ************>
<May 21, 2009 2:59:56 PM EEST> <Notice> <Stdout> <BEA-000000> <ejbLoad() called.>
<May 21, 2009 2:59:56 PM EEST> <Notice> <Stdout> <BEA-000000> <ejbStore() called.>
<May 21, 2009 3:00:56 PM EEST> <Error> <JDBC> <BEA-001112> <Test "select count(*) from SYSTABLES" set up for pool "myJDBCDataSource" failed with exception: "com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'testars.systables' doesn't exist".>
<May 21, 2009 3:00:56 PM EEST> <Info> <JDBC> <BEA-001128> <Connection for pool "myJDBCDataSource" closed.>
<May 21, 2009 3:00:57 PM EEST> <Info> <JDBC> <BEA-001067> <Connection for pool "myJDBCDataSource" refreshed.>


Running mdbex.jpr log
C:\Oracle\Middleware\jdk160_05\bin\javaw.exe -client -classpath C:\JDeveloper\mywork\EJB3\MDBex\classes;C:\JDeveloper\mywork\EJB3\lib\wlfullclient5.jar Client
Starting Client . . .
Looking up the JMS destination(Topic) via JNDI.
Locating connection factory.
Creating a connection and establishing a session.
Creating an order with status:Submitted
Order id 1242908873140 is created
Creating a text message with order id and publishing it.
Sleeping for 5 sec.
Now the order status is:Verified
Process exited with exit code 0.

5-How to Develop Message-Driven Beans

Files located in the src directory
FILE: Client.java
import javax.jms.*;

import javax.naming.*;

import javax.ejb.*;

import java.util.*;

import mdbex.OrderARSHome;
import mdbex.OrderARS;
import weblogic.jms.*;

public class Client {
public static void main(String[] args) {
print("Starting Client . . .");
try {
String orderVerifierJndiName = "OrderVerifierTopic"; //args[0]; mdbex/OrderVerifier
String connectionFactoryJndiName = "weblogic.jms.ConnectionFactory";
// javax.jms.TopicConnectionFactory
// javax.jms.QueueConnectionFactory
// ?weblogic.jms.ConnectionFactory
// ?weblogic.jms.XAConnectionFactory

print("Looking up the JMS destination(Topic) via JNDI.");
Context context = new InitialContext();
Topic topic = (Topic)context.lookup(orderVerifierJndiName);

print("Locating connection factory.");
TopicConnectionFactory connectionFactory =
(TopicConnectionFactory)context.lookup(connectionFactoryJndiName);
print("Creating a connection and establishing a session.");
TopicConnection connection =
connectionFactory.createTopicConnection();
TopicSession session =
connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
TopicPublisher publisher = session.createPublisher(topic);

print("Creating an order with status:Submitted");
Context initialContext = new InitialContext();
Object object = initialContext.lookup("mdbex/OrderARS");
OrderARSHome orderHome =
(OrderARSHome)javax.rmi.PortableRemoteObject.narrow(object,
OrderARSHome.class);
OrderARS order = (OrderARS)orderHome.create("1", "Submitted", 100);
String orderId = order.getOrderId();
print("Order id " + orderId + " is created");
print("Creating a text message with order id and publishing it.");
TextMessage tm = session.createTextMessage();
tm.setText(orderId);
publisher.publish(tm);

print("Sleeping for 5 sec.");
Thread.sleep(5000);
print("Now the order status is:" + order.getStatus());
} catch (Exception ex) {
System.err.println(ex);
ex.printStackTrace();
}
}

static void print(String s) {
System.out.println(s);
}

}

FILE: jndi.properties
java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
java.naming.factory.url.pkgs=weblogic.jndi.factories:weblogic.corba.j2ee.naming.url:weblogic.corba.client.naming
java.naming.provider.url=t3://localhost:7101
java.naming.security.principal=weblogic
java.naming.security.credentials=weblogic

Located in the MDBentity library( ../src)
FILE: build.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<project name="EJB3 Tutorial" basedir="." default="deploy">

<property name="deploy.dir" value="C:/MDBentity/deploy" />
<property name="sourcedir" value="${basedir}/src"/>
<property name="targetdir" value="${basedir}/build"/>
<property name="librarydir" value="${basedir}/lib"/>

<path id="libraries">
<fileset dir="${librarydir}">
<include name="*.jar"/>
</fileset>
</path>

<target name="clean">
<delete dir="${targetdir}"/>
<mkdir dir="${targetdir}"/>
</target>

<target name="compile" depends="copy-resources">
<javac srcdir="${sourcedir}"
destdir="${targetdir}"
classpathref="libraries"
debug="on">
<compilerarg value="-Xlint"/>
</javac>
</target>
<target name="copy-resources">
<copy todir="${targetdir}">
<fileset dir="${sourcedir}">
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>

<target name="deploy" description="JARs the Task" depends="clean,copy-resources,compile">
<jar destfile="${deploy.dir}/MDBent.jar">
<metainf dir="${sourcedir}/META-INF" />
<fileset dir="${targetdir}">
<include name="**/*.class" />
</fileset>
</jar>
</target>

<target name="undeploy" description="Undeploy jar from server">
<delete file="${deploy.dir}/MDBent.jar" />
</target>

<target name="run" depends="compile">
<java classname="Client" classpathref="libraries">
<classpath path="${targetdir}"/>
<jvmarg value="-Djava.library.path=./lib"/>
</java>
</target>
</project>


4-How to Develop Message-Driven Beans

XML files locates in the src/META-INF directory;
FILE: ejb-jar.xml

<!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>
<entity>
<ejb-name>OrderARSEJB</ejb-name>
<home>mdbex.OrderARSHome</home>
<remote>mdbex.OrderARS</remote>
<ejb-class>mdbex.OrderARSEJB</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>java.lang.String</prim-key-class>
<reentrant>False</reentrant>
<cmp-version>2.x</cmp-version>
<abstract-schema-name>OrderARS</abstract-schema-name>
<cmp-field>
<field-name>orderId</field-name>
</cmp-field>
<cmp-field>
<field-name>studentId</field-name>
</cmp-field>
<cmp-field>
<field-name>orderDate</field-name>
</cmp-field>
<cmp-field>
<field-name>status</field-name>
</cmp-field>
<cmp-field>
<field-name>amount</field-name>
</cmp-field>
<primkey-field>orderId</primkey-field>
<query>
<query-method>
<method-name>findByStatus</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</query-method>
<ejb-ql>
<![CDATA[SELECT OBJECT(o) FROM OrderARS AS o
WHERE o.status = ?1]]>
</ejb-ql>
</query>
<query>
<query-method>
<method-name>ejbSelectAllOrderAmounts</method-name>
<method-params>
</method-params>
</query-method>
<ejb-ql>
<![CDATA[SELECT o.amount FROM OrderARS AS o
WHERE o.orderId IS NOT NULL]]>
</ejb-ql>
</query>
</entity>
<message-driven>
<ejb-name>OrderVerifierMDB</ejb-name>
<ejb-class>mdbex.OrderVerifierMDB</ejb-class>
<transaction-type>Container</transaction-type>
<message-driven-destination>
<destination-type>javax.jms.Topic</destination-type>
<subscription-durability>NonDurable</subscription-durability>
</message-driven-destination>
</message-driven>
</enterprise-beans>
</ejb-jar>

FILE: weblogic-ejb-jar.xml
<?xml version="1.0"?>
<!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>OrderARSEJB</ejb-name>
<entity-descriptor>

<persistence>
<persistence-use>
<type-identifier>WebLogic_CMP_RDBMS</type-identifier>
<type-version>6.0</type-version>
<type-storage>META-INF/weblogic-cmp-rdbms-jar.xml</type-storage>
</persistence-use>
</persistence>

</entity-descriptor>
<jndi-name>mdbex/OrderARS</jndi-name>
</weblogic-enterprise-bean>
<weblogic-enterprise-bean>
<ejb-name>OrderVerifierMDB</ejb-name>
<message-driven-descriptor>
<pool>
<max-beans-in-free-pool>20</max-beans-in-free-pool>
<initial-beans-in-free-pool>5</initial-beans-in-free-pool>
</pool>
<destination-jndi-name>OrderVerifierTopic</destination-jndi-name>
</message-driven-descriptor>
<jndi-name>mdbex/OrderVerifier</jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>

FILE: weblogic-rdbms-jar.xml
<!DOCTYPE weblogic-rdbms-jar PUBLIC
'-//BEA Systems, Inc.//DTD WebLogic 7.0.0 EJB RDBMS Persistence//EN'
'http://www.bea.com/servers/wls700/dtd/weblogic-rdbms20-persistence-700.dtd'>
<weblogic-rdbms-jar>
<weblogic-rdbms-bean>
<ejb-name>OrderARSEJB</ejb-name>
<data-source-name>styejbDB</data-source-name>
<table-map>
<table-name>orders</table-name>
<field-map>
<cmp-field>orderId</cmp-field>
<dbms-column>order_id</dbms-column>
</field-map>
<field-map>
<cmp-field>studentId</cmp-field>
<dbms-column>student_id</dbms-column>
</field-map>
<field-map>
<cmp-field>orderDate</cmp-field>
<dbms-column>order_date</dbms-column>
</field-map>
<field-map>
<cmp-field>status</cmp-field>
<dbms-column>status</dbms-column>
</field-map>
<field-map>
<cmp-field>amount</cmp-field>
<dbms-column>amount</dbms-column>
</field-map>
</table-map>
</weblogic-rdbms-bean>
</weblogic-rdbms-jar>

3-How to Develop Message-Driven Beans

Files located in the package src/mdbex;
FILE : OrderVerifierHome.java
package mdbex;

import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;

public interface OrderVerifierHome extends EJBHome{
OrderVerifier create() throws CreateException, RemoteException;
}

FILE: OrderVerifier.java
package mdbex;

import java.rmi.RemoteException;

public interface OrderVerifier extends javax.ejb.EJBObject{
}

FILE: OrderVerifierMDB.java
package mdbex;

import java.util.*;
import java.io.*;
import java.rmi.*;
import javax.naming.*;
import javax.ejb.*;

import javax.jms.MessageListener;

import javax.ejb.CreateException;
import javax.ejb.MessageDrivenBean;
import javax.ejb.MessageDrivenContext;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

import javax.naming.InitialContext;
import javax.naming.NamingException;

public class OrderVerifierMDB implements MessageDrivenBean, MessageListener
{

private MessageDrivenContext mdbContext;

/**
* this method is invoked by the container. it gives the MDB instance a reference to its context.
* this can be empty also.
* @param ctx MessageDrivenContext for this instance
*/
public void setMessageDrivenContext(MessageDrivenContext ctx) {
mdbContext = ctx;
}

/**
* @exception javax.ejb.CreateException if there is
* a communications or systems failure
*/
public void ejbCreate () throws CreateException {
System.out.println("****ARSSSSSSSSSSssssssss********");
}

/**
*/
public void ejbRemove() {
mdbContext = null;
}

// Implementation of MessageListener
/**
*@param msg The Message from the JMS-Server
*/
public void onMessage(Message msg) {
TextMessage orderMessage = (TextMessage) msg;
try {
String orderId = orderMessage.getText();

System.out.println("************ Order Information ************");
System.out.println("****ARSSSSSSSSSSssssssss Order Id is : "+orderId);
System.out.println("************ Order Information Ends ************");
System.out.println();

try {
System.out.println("Creating an order with status:Submitted");
Context initialContext = new InitialContext();
Object object = initialContext.lookup("mdbex/OrderARS");
OrderARSHome orderHome =
(OrderARSHome)javax.rmi.PortableRemoteObject.narrow(object,
OrderARSHome.class);
// OrderARS order = (OrderARS)orderHome.create("1", "Submitted", 100);
OrderARS order = orderHome.findByPrimaryKey(orderId);
order.setStatus("Verified");

} catch (Exception ex) {
System.err.println(ex);
ex.printStackTrace();
}
}
catch(JMSException ex) {
ex.printStackTrace();
}
}

//
// Implementation of MessageListener
/////
}

2-How to Develop Message-Driven Beans

Files located in the package src/mdbex:
FILE : OrderARSHome.java
package mdbex;

import java.util.*;
import java.rmi.*;
import javax.ejb.*;

public interface OrderARSHome extends EJBHome {
/* Create methods */
public OrderARS create(String studentId,
String status, double amount) throws CreateException, RemoteException;
/* Finder methods */
public OrderARS findByPrimaryKey(String key)
throws FinderException, RemoteException;
public Collection findByStatus(String status)
throws FinderException, RemoteException;
/* Home methods */
public double getTotalAmountOfAllOrders()
throws FinderException, RemoteException;
}

FILE: OrderARS.java
package mdbex;

import java.rmi.*;
import javax.ejb.*;

public interface OrderARS extends EJBObject {
public String getOrderId()
throws RemoteException;
public String getStudentId()
throws RemoteException;
public void setStudentId(String studentId)
throws RemoteException;
public double getAmount()
throws RemoteException;
public void setAmount(double amount)
throws RemoteException;
public java.sql.Timestamp getOrderDate()
throws RemoteException;
public void setOrderDate(java.sql.Timestamp date)
throws RemoteException;
public String getStatus()
throws RemoteException;
public void setStatus(String status)
throws RemoteException;
}

FILE: OrderARSEJB.java
package mdbex;

import java.util.*;
import java.io.*;
import java.rmi.*;
import javax.naming.*;
import javax.ejb.*;

public abstract class OrderARSEJB implements EntityBean
{
protected EntityContext ctx;
public abstract String getOrderId();
public abstract void setOrderId(String orderId);
public abstract String getStudentId();
public abstract void setStudentId(String studentid);
public abstract java.sql.Timestamp getOrderDate();
public abstract void setOrderDate(java.sql.Timestamp timestamp);
public abstract String getStatus();
public abstract void setStatus(String status);
public abstract double getAmount();
public abstract void setAmount(double amount);
/* Callback methods */
public void setEntityContext(EntityContext ctx) {
print("setEntityContext called");
this.ctx = ctx;
}
public void unsetEntityContext() {
print("unsetEntityContext called.\n");
this.ctx = null;
}
public void ejbActivate() {
print("ejbActivate() called.\n");
}
public void ejbPassivate() {
print("ejbPassivate() called.\n");
}
public void ejbStore() {
print("ejbStore() called.\n");
}
public void ejbLoad() {
print("ejbLoad() called.\n");
}
public void ejbRemove() throws RemoveException {
print("ejbRemove() called.\n");
}
public String ejbCreate( String studentId,
String status, double amount) throws CreateException {
print("ejbCreate() called.\n");
String orderId = getUniqueId();
setOrderId(orderId);
setStudentId(studentId);
setStatus(status);
setAmount(amount);
setOrderDate(new java.sql.Timestamp(System.currentTimeMillis()));
return null;
}
public void ejbPostCreate(String studentId,
String courseId, double amount) throws CreateException {
print("ejbPostCreate() called.\n");
}
/* Home methods */
public double ejbHomeGetTotalAmountOfAllOrders()
throws FinderException {
double totalAmount = 0.0;
Collection col = ejbSelectAllOrderAmounts();
Enumeration amounts=Collections.enumeration(col);
while( amounts.hasMoreElements() ) {
Double amount= (Double)amounts.nextElement();
totalAmount += amount.doubleValue();
}
return totalAmount;
}
/* select methods. */
public abstract Collection ejbSelectAllOrderAmounts()
throws FinderException ;

void print(String s) {
System.out.println(s);
}
String getUniqueId(){
return new Long(System.currentTimeMillis()).toString();
}
}