Hi,

Jay SenSharma

Jay SenSharma

Why We Need to generate EJB Client Jar (Stubs) for Client side Usages?

Many times we see various issues in the absence of client Jar at client side like NoSuchMethodError, CORBA errors,the following Kind of Stack Trace at client end, while invoking the EJB methods:

java.lang.AssertionError: java.lang.ClassNotFoundException: com.abc.bcd.GetCredit
at weblogic.ejb.container.internal.RemoteBusinessIntfGenerator.generateRemoteInterface (RemoteBusinessIntfGenerator.java:57)
at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.readObject (RemoteBusinessIntfProxy.java:205)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)

Example: http://forums.oracle.com/forums/thread.jspa?threadID=839694&tstart=0

Here In this Demonstration we will see following 3-Things…

PART-A). How to Develope a Simple EJB3 Stateless Application.

PART-B). How to Generate the EJB3 Deployment Descriptors using APPC utility from EJB Jar Application.

PART-3). Then How to Edit this EJB3 Deployment Descriptors to Generate ClientJars & Assign Custom JNDI Name to our EJB.

We will see some other options as well to explore the “weblogic.Appc” utility in this sample.

…………….. =========================================

******** Begin Of PART-A Below *********

…………….. =========================================
Step1). So we begin by creating a Simple Directory somewhere inside our file system: Example create a Directory inside : “C:CustomJNDIName”

Step2). Create “src” directory inside “C:CustomJNDIName” location.

Step3). Provide the “ReplicableSFSRemoteIntf.java” program inside “C:CustomJNDINamesrc”

package sfsb3;
import javax.ejb.*;
@Remote
public interface ReplicableSFSRemoteIntf {
public void removeWithRetain()throws Exception;
public void removeWithoutRetain() throws Exception;
public String printBean ();
public int testIncrement() throws Exception;
public int testDecrement() throws Exception;
public int getCount() throws Exception;
}

Step4). Provide the “ReplicableSFSLocalIntf.java” program inside “C:CustomJNDINamesrc”

package sfsb3;
import javax.ejb.*;
@Local
public interface ReplicableSFSLocalIntf {
public void removeWithRetain() throws Exception;
public void removeWithoutRetain() throws Exception;
public String printBean ();
public int testIncrement() throws Exception;
public int testDecrement() throws Exception;
public int getCount() throws Exception;
}

Step5). Now provide The Bean Implementation class “ReplicableSFSBean.java” program inside “C:CustomJNDINamesrc”

package sfsb3;
import javax.ejb.*;
@Stateful
public class ReplicableSFSBean implements ReplicableSFSRemoteIntf, ReplicableSFSLocalIntf
{
int count = 0;
public ReplicableSFSBean() {
System.out.println("nt ReplicableSFSBean--> ReplicableSFSBean() invoked");
}
@Init("create")
public void initMethod() throws CreateException {
System.out.println("nt ReplicableSFSBean--> public void initMethod() invoked");
}

@Remove(retainIfException=true)
public void removeWithRetain() throws Exception{
System.out.println("nt ReplicableSFSBean--> removeWithRetain() invoked");
}

@Remove
public void removeWithoutRetain() throws Exception{
System.out.println("nt ReplicableSFSBean--> removeWithoutRetain() invoked");
}

public String printRemoteIntf () {
System.out.println("nt ReplicableSFSBean ---> public String printRemoteIntf () invoked");
return "ReplicableSFSRemoteObjectIntf";
}

public String printLocalIntf () {
System.out.println("nt ReplicableSFSBean ---> public String printLocalIntf () invoked");
return "ReplicableSFSLocalObjectIntf";
}

public String printBean () {
System.out.println("nt ReplicableSFSBean ---> public String printBean () invoked");
return "ReplicableSFSBean";
}

public int testIncrement() throws Exception
{
System.out.println("nt ReplicableSFSBean ---> public int testIncrement() invoked");
count=count+5;
return count;
}

public int testDecrement() throws Exception
{
System.out.println("nt ReplicableSFSBean ---> public int testDecrement() invoked");
count=count-2;
return count;
}

public int getCount() throws Exception
{
System.out.println("nt ReplicableSFSBean ---> public int getCount() invoked");
return count;
}
}

Step6). Now develop the ANT Build file “build.xml” inside “C:CustomJNDIName” as following:

<project name="Test-Client_Jar_EJB3" default="deploy" basedir=".">

<property name="wl.home.lib" value="C:bea103wlserver_10.3serverlib" />
<property name="wls.username" value="weblogic" />
<property name="wls.password" value="weblogic" />
<property name="wls.hostname" value="localhost" />
<property name="wls.port" value="7001" />
<property name="admin.server.name" value="AdminServer" />
<property name="deploy.target" value="AdminServer" />

<property name="src.dir" value="src"/>
<property name="build.dir" value="build"/>
<property name="classes.dir" value="${build.dir}/classes"/>
<property name="jar.dir" value="${build.dir}"/>
<property name="jar.file.name" value="SFSB_EJB3"/>
<property name="deploy.name" value="SFSB_EJB3" />
<property name="deploy.source" value="SFSB_EJB3.jar" />

<path id="custom.classpath">
<fileset dir="${wl.home.lib}">
<include name="*.jar"/>
</fileset>
</path>

<taskdef name="wldeploy" classname="weblogic.ant.taskdefs.management.WLDeploy"/>

<target name="init" depends="clean">
<mkdir dir="${build.dir}"/>
</target>

<target name="clean" >
<delete dir="build"/>
</target>

<target name="compile" depends="init">
<mkdir dir="${classes.dir}"/>
<javac srcdir="${src.dir}" destdir="${classes.dir}" />
</target>

<target name="jar" depends="compile">
<mkdir dir="${jar.dir}"/>
<jar destfile="${jar.dir}/${jar.file.name}.jar" basedir="${classes.dir}"/>
</target>
</project>

Step 7). Now Open a Command Window ….then run “setWLSEnv.sh” or “setWLSEnv.cmd” then run the above Ant script to Build the EJB jar file.

OUTPUT:

C:CustomJNDIName>ant  jar
Buildfile: build.xml

clean:
[delete] Deleting directory C:CustomJNDINamebuild

init:
[mkdir] Created dir: C:CustomJNDINamebuild

compile:
[mkdir] Created dir: C:CustomJNDINamebuildclasses
[javac] Compiling 3 source files to C:CustomJNDINamebuildclasses

jar:
[jar] Building jar: C:CustomJNDINamebuildSFSB_EJB3.jar

BUILD SUCCESSFUL
Total time: 1 second

…………….. =========================================

******** Begin Of PART-B Below *********

…………….. =========================================
Step 8). Just Observer the Generated Jar “SFSB_EJB3.jar” inside “C:CustomJNDINamebuild”. It doesnt have any Deployment descriptors.

Step9). To generate the Deployment descriptors from the Jar “SFSB_EJB3.jar” we can use the following “weblogic.appc” Attribute:


C:CustomJNDINamebuild>   <strong>java weblogic.appc -source 1.5 -output OUTPUT -writeInferredDescriptors SFSB_EJB3.jar</strong>

—————-

Step10). Now open the OUTPUT directory which is created inside “C:CustomJNDINamebuild” directory and then observe that the Default EJB3 Descriptors are Created inside “META-INF” directory like following:

“ejb-jar.xml”

<?xml version='1.0' encoding='UTF-8'?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" metadata-complete="true">

<enterprise-beans>
<session>
<ejb-name>ReplicableSFSBean</ejb-name>
<business-local>sfsb3.ReplicableSFSLocalIntf</business-local>
<business-remote>sfsb3.ReplicableSFSRemoteIntf</business-remote>
<ejb-class>sfsb3.ReplicableSFSBean</ejb-class>
<session-type>Stateful</session-type>
<remove-method>
<bean-method>
<method-name>removeWithRetain</method-name>
<method-params></method-params>
</bean-method>
<retain-if-exception>true</retain-if-exception>
</remove-method>
<remove-method>
<bean-method>
<method-name>removeWithoutRetain</method-name>
<method-params></method-params>
</bean-method>
<retain-if-exception>false</retain-if-exception>
</remove-method>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>

<assembly-descriptor></assembly-descriptor>
</ejb-jar>

Default “weblogic-ejb-jar.xml” as following:

<weblogic-ejb-jar xmlns="http://www.bea.com/ns/weblogic/weblogic-ejb-jar" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-ejb-jar http://www.bea.com/ns/weblogic/weblogic-ejb-jar/1.0/weblogic-ejb-jar.xsd">

</weblogic-ejb-jar>


…………….. =========================================

******** Begin Of PART-C Below *********

…………….. =========================================
Step 11). Now Edit the “ejb-jar.xml” file …by adding the <ejb-clientjar>My_Ejb3_Client.jar</ejb-clientjar> Tag inside it. Like following:

<?xml version='1.0' encoding='UTF-8'?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" metadata-complete="true">
<enterprise-beans>
<session>
<ejb-name>ReplicableSFSBean</ejb-name>
<business-local>sfsb3.ReplicableSFSLocalIntf</business-local>
<business-remote>sfsb3.ReplicableSFSRemoteIntf</business-remote>
<ejb-class>sfsb3.ReplicableSFSBean</ejb-class>
<session-type>Stateful</session-type>
<remove-method>
<bean-method>
<method-name>removeWithRetain</method-name>
<method-params></method-params>
</bean-method>
<retain-if-exception>true</retain-if-exception>
</remove-method>
<remove-method>
<bean-method>
<method-name>removeWithoutRetain</method-name>
<method-params></method-params>
</bean-method>
<retain-if-exception>false</retain-if-exception>
</remove-method>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
<assembly-descriptor></assembly-descriptor>

<ejb-client-jar>My_Ejb3_Client.jar</ejb-client-jar>

</ejb-jar>

Step 12). Now edit the “weblogic-ejb-jar.xml” file to assign a Simple Custom JNDI name to Our EJB …like following:

<weblogic-ejb-jar xmlns="http://www.bea.com/ns/weblogic/90" xmlns:j2ee="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bea.com/ns/weblogic/90 http://www.bea.com/ns/weblogic/90/weblogic-ejb-jar.xsd">

<weblogic-enterprise-bean>
<ejb-name>ReplicableSFSB</ejb-name>
<stateful-session-descriptor>
<business-interface-jndi-name-map>
<business-remote>sfsb3.ReplicableSFSRemoteIntf </business-remote>
<jndi-name>ReplicableSFSB</jndi-name>
</business-interface-jndi-name-map>
</stateful-session-descriptor>
</weblogic-enterprise-bean>

</weblogic-ejb-jar>

Step13). Now You can assemble your Edited EJB in the following location: “C:CustomJNDINamebuildOUTPUT”. In the command prompt move inside this directory and Just Build the EJB jar again….

C:CustomJNDINamebuildOUTPUT> jar cvf Edited_SFSB_EJB3.jar .

or

C:CustomJNDINamebuildOUTPUT> jar cvf Edited_SFSB_EJB3.jar META-INF sfsb3

or

C:CustomJNDINamebuildOUTPUT> jar cvf Edited_SFSB_EJB3.jar META-INF sfsb3 _WL_GENERATED

————–

Step14). Now Your “Edited_SFSB_EJB3.jar” is ready for deployment ….But we want to generate the client artifacts before deploying the Edited EJB…So for that we are going to use a New “buildClientJar.xml” inside “C:CustomJNDINamebuildOUTPUT” Location like following:

<project name="Test-Client_Jar_EJB3" default="deploy" basedir=".">
<property name="wl.home.lib" value="C:bea103wlserver_10.3serverlib" />
<property name="wls.username" value="weblogic" />
<property name="wls.password" value="weblogic" />
<property name="wls.hostname" value="localhost" />
<property name="wls.port" value="7001" />
<property name="admin.server.name" value="AdminServer" />
<property name="deploy.target" value="AdminServer" />

<property name="src.dir" value="src"/>
<property name="build.dir" value="build"/>
<property name="classes.dir" value="${build.dir}/classes"/>
<property name="jar.dir" value="${build.dir}"/>
<property name="jar.file.name" value="Edited_SFSB_EJB3"/>
<property name="deploy.name" value="Edited_SFSB_EJB3" />
<property name="deploy.source" value="Edited_SFSB_EJB3.jar" />

<path id="custom.classpath">
<fileset dir="${wl.home.lib}">
<include name="*.jar"/>
</fileset>
</path>

<taskdef name="weblogicAppc" classpathref="custom.classpath" classname="weblogic.ant.taskdefs.j2ee.Appc"/>
<taskdef name="wldeploy" classname="weblogic.ant.taskdefs.management.WLDeploy"/>

<target name="appc">
<weblogicAppc source="${jar.file.name}.jar" keepgenerated="true"
verbose="true" output="." clientJarOutputDir="." />
</target>

<target name="deploy" depends="appc">
<wldeploy action="deploy" name="${deploy.name}" source="${deploy.source}" user="${wls.username}" nostage="true"
password="${wls.password}" verbose="true" adminurl="t3://${wls.hostname}:${wls.port}" targets="${deploy.target}" />
</target>

<target name="redeploy">
<wldeploy action="redeploy" name="${deploy.name}" user="${wls.username}" nostage="true" source="${deploy.source}"
password="${wls.password}" verbose="true" adminurl="t3://${wls.hostname}:${wls.port}" targets="${deploy.target}" />
</target>

<target name="undeploy">
<wldeploy action="undeploy" name="${deploy.name}" failonerror="false" user="${wls.username}"
password="${wls.password}" verbose="true" adminurl="t3://${wls.hostname}:${wls.port}" targets="${deploy.target}" />
</target>
</project>

Step15). Now as soon as you run the above Ant Script you will find that “My_Ejb3_Client.jar” Client Jar file is generated inside the Current Directory and The EJB is deployed on the Server….

C:CustomJNDINamebuildOUTPUT> ant -buildfile buildClientJar.xml

.

.

Thanks

Jay SenSharma