Saturday, 22 August 2009

How to create Custom Java Packages Using Net Beans

By Ali Riza SARAL

This document will explain how to create custom packages with NetBeans. You can create your own java packages and put them in jar files so that you can call or use java objects from them.

This document is based on the example Geometry.java example from Wrox - Beginning Java 2 JDK5 Edition -2005 by Ivor HORTON which can be found on the internet.

The solution is given in stages, so please be patient and try to understand each stage as quick as possible:

1. STAGE:

There is only one package and that is the main program’s package named PackageEx.

----------------------------------------------------
SOURCE of packageex.java
----------------------------------------------------
package packageex;

class Line {
Point start; // Start point of line
Point end; // End point of line

// Create a line from two points
Line(final Point start, final Point end) {
this.start = new Point(start);
this.end = new Point(end);
}

// Create a line from two coordinate pairs
Line(double xStart, double yStart, double xEnd, double yEnd) {
start = new Point(xStart, yStart); // Create the start point
end = new Point(xEnd, yEnd); // Create the end point
}

// Calculate the length of a line
double length() {
return start.distance(end); // Use the method from the Point class
}

// Convert a line to a string
public String toString() {
return "(" + start+ "):(" + end + ")"; // As "(start):(end)"
} // that is, "(x1, y1):(x2, y2)"

// Return a point as the intersection of two lines -- called from a Line object
Point intersects(final Line line1) {
Point localPoint = new Point(0, 0);

double num =
(this.end.y - this.start.y)*(this.start.x - line1.start.x) -
(this.end.x - this.start.x)*(this.start.y - line1.start.y);

double denom =
(this.end.y - this.start.y)*(line1.end.x - line1.start.x) -
(this.end.x - this.start.x)*(line1.end.y - line1.start.y);

localPoint.x = line1.start.x + (line1.end.x - line1.start.x)*num/denom;
localPoint.y = line1.start.y + (line1.end.y - line1.start.y)*num/denom;

return localPoint;
}
}
----------------------------------------------------------
SOURCE of point.java
-----------------------------------------------------------
package packageex;

class Point {
// Coordinates of the point
double x;
double y;

// Create a point from coordinates
Point(double xVal, double yVal) {
x = xVal;
y = yVal;
}

// Create a point from another Point object
Point(final Point oldPoint) {
x = oldPoint.x; // Copy x coordinate
y = oldPoint.y; // Copy y coordinate
}

// Move a point
void move(double xDelta, double yDelta) {
// Parameter values are increments to the current coordinates
x += xDelta;
y += yDelta;
}

// Calculate the distance to another point
double distance(final Point aPoint) {
return Math.sqrt(
(x - aPoint.x)*(x - aPoint.x) + (y - aPoint.y)*(y - aPoint.y) );
}

// Convert a point to a string
public String toString() {
return Double.toString(x) + ", " + y; // As "x, y"
}
}
-----------------------------------------------------
SOURCE of TryGeometry.java
-----------------------------------------------------
package packageex;

public class TryGeometry {
public static void main(String[] args) {
// Create two points and display them
Point start = new Point(0.0, 1.0);
Point end = new Point(5.0, 6.0);
System.out.println("Points created are " + start + " and " + end);


// Create two lines and display them
Line line1 = new Line(start, end);
Line line2 = new Line(0.0, 3.0, 3.0, 0.0);
System.out.println("Lines created are " + line1 + " and " + line2);

// Display the intersection
System.out.println("Intersection is " + line2.intersects(line1));

// Now move the end point of line1 and show the new intersection
end.move(1.0, -5.0);
System.out.println("Intersection is " + line1.intersects(line2));
}
}
-----------------------------------------------------------
2. STAGE:

There is an additional package named com.ars.geometry besides the packageex2 which belongs to the main program. Please be aware of the differences in the package statements at the top of each program.
TryGeometry has a import statement also…


-----------------------------------------
SOURCE of Line.java
-----------------------------------------
package com.ars.geometry;

public class Line {
Point start; // Start point of line
Point end; // End point of line

// Create a line from two points
public Line(final Point start, final Point end) {
this.start = new Point(start);
this.end = new Point(end);
}

// Create a line from two coordinate pairs
public Line(double xStart, double yStart, double xEnd, double yEnd) {
start = new Point(xStart, yStart); // Create the start point
end = new Point(xEnd, yEnd); // Create the end point
}

// Calculate the length of a line
public double length() {
return start.distance(end); // Use the method from the Point class
}

// Convert a line to a string
public String toString() {
return "(" + start+ "):(" + end + ")"; // As "(start):(end)"
} // that is, "(x1, y1):(x2, y2)"

// Return a point as the intersection of two lines -- called from a Line object
public Point intersects(final Line line1) {
Point localPoint = new Point(0, 0);

double num =
(this.end.y - this.start.y)*(this.start.x - line1.start.x) -
(this.end.x - this.start.x)*(this.start.y - line1.start.y);

double denom =
(this.end.y - this.start.y)*(line1.end.x - line1.start.x) -
(this.end.x - this.start.x)*(line1.end.y - line1.start.y);

localPoint.x = line1.start.x + (line1.end.x - line1.start.x)*num/denom;
localPoint.y = line1.start.y + (line1.end.y - line1.start.y)*num/denom;

return localPoint;
}
}
---------------------------------------------------------------------
SOURCE of Point.java
---------------------------------------------------------------------
package com.ars.geometry;

public class Point {
// Coordinates of the point
public double x;
public double y;

// Create a point from coordinates
public Point(double xVal, double yVal) {
x = xVal;
y = yVal;
}

// Create a point from another Point object
public Point(final Point oldPoint) {
x = oldPoint.x; // Copy x coordinate
y = oldPoint.y; // Copy y coordinate
}

// Move a point
public void move(double xDelta, double yDelta) {
// Parameter values are increments to the current coordinates
x += xDelta;
y += yDelta;
}

// Calculate the distance to another point
public double distance(final Point aPoint) {
return Math.sqrt(
(x - aPoint.x)*(x - aPoint.x) + (y - aPoint.y)*(y - aPoint.y) );
}

// Convert a point to a string
public String toString() {
return Double.toString(x) + ", " + y; // As "x, y"
}
}
----------------------------------------------------------
SOURCE of TryGeometry.java
----------------------------------------------------------
package packageex2;

import com.ars.geometry.*;

public class TryGeometry {
public static void main(String[] args) {
// Create two points and display them
Point start = new Point(0.0, 1.0);
Point end = new Point(5.0, 6.0);
System.out.println("Points created are " + start + " and " + end);


// Create two lines and display them
Line line1 = new Line(start, end);
Line line2 = new Line(0.0, 3.0, 3.0, 0.0);
System.out.println("Lines created are " + line1 + " and " + line2);

// Display the intersection
System.out.println("Intersection is " + line2.intersects(line1));

// Now move the end point of line1 and show the new intersection
end.move(1.0, -5.0);
System.out.println("Intersection is " + line1.intersects(line2));
}
}
--------------------------------------------------------------
3. STAGE
Right click on PackageEx3 in the projects window. Select Properties. Select Libraries. Select Compile to add compile time libraries. You can add JAR or folder with this utility. We will add the source directories that we have created in the second stage, namely ../PackageEx2/src . Here it is critically important that you add one higher level of directory in order to include the dir you need. You must also add the same library to the run timr libraries by selecting the run tab.

---------------------------------------------------------------
SOURCE of TryGeometry.java
---------------------------------------------------------------
package packageex3;

import com.ars.geometry.Line;
import com.ars.geometry.Point;

public class TryGeometry {
public static void main(String[] args) {

// Create two points and display them
Point start = new Point(0.0, 1.0);
Point end = new Point(5.0, 6.0);
System.out.println("Points created are " + start + " and " + end);


// Create two lines and display them
Line line1 = new Line(start, end);
Line line2 = new Line(0.0, 3.0, 3.0, 0.0);
System.out.println("Lines created are " + line1 + " and " + line2);

// Display the intersection
System.out.println("Intersection is " + line2.intersects(line1));

// Now move the end point of line1 and show the new intersection
end.move(1.0, -5.0);
System.out.println("Intersection is " + line1.intersects(line2));
}
}
---------------------------------------------------------------
4. STAGE
We create a JAR file from the material that resides in the com.ars.geometry directory.

C:\Documents and Settings\Ali Riza SARAL\Desktop>jar
Usage: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...
Options:
-c create new archive
-t list table of contents for archive
-x extract named (or all) files from archive
-u update existing archive
-v generate verbose output on standard output
-f specify archive file name
-m include manifest information from specified manifest file
-e specify application entry point for stand-alone application
bundled into an executable jar file
-0 store only; use no ZIP compression
-M do not create a manifest file for the entries
-i generate index information for the specified jar files
-C change to the specified directory and include the following file
If any file is a directory then it is processed recursively.


Example 1: to archive two class files into an archive called classes.jar:
jar cvf classes.jar Foo.class Bar.class
Example 2: use an existing manifest file 'mymanifest' and archive all the
files in the foo/ directory into 'classes.jar':
jar cvfm classes.jar mymanifest -C foo/ .



C:\Documents and Settings\Ali Riza SARAL\Desktop>pwd
/cygdrive/c/Documents and Settings/Ali Riza SARAL/Desktop

C:\Documents and Settings\Ali Riza SARAL\Desktop>cd geometry

C:\Documents and Settings\Ali Riza SARAL\Desktop\geometry>jar cvf geometry.jar -C . .


C:\Documents and Settings\Ali Riza SARAL\Desktop\geometry dizini
08/06/2009 09:52 PM DIR .
08/06/2009 09:52 PM DIR ..
08/06/2009 09:05 PM DIR com
08/06/2009 09:52 PM 3,569 geometry.jar

Adding the geometry jar for run time libraries option is NOT ENOUGH. You must also specify a package lib for the compile time libraries. I added the packageex2 libraries and saw that netbeans required the compile time libraries reference when using a package.

--------------------------------------------------
5. STAGE
I took out the compile time libraries reference to the packageex2 directory and referenced the geometry.jar for both the compile and run time libraries references. Be aware that this requires that your JAR file must have both the source and the class files of your package.

References:
1- Wrox - Beginning Java 2 JDK5 Edition -2005 by Ivor HORTON
2- Java Package Tutorial by Patrick Bouklee
3- Q&A How do I create a _JAR file – google search keywords.

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
/////
}