Tag: EJB

Calling EJB3 to EJB3 Locally using @EJB Annotation

Hi,

Jay SenSharma

Jay SenSharma

Here is a simple demo of calling an EJB3 Stateless bean through another EJB3 bean which is reside inside the same EAR file. To refer to a Local EJB using @EJB annotation we must use the  Tag <ejb-local-ref> inside our “ejb-jar.xml” as described in the following post.

Many times we get following kind of error at the time of Deploying the application while using @EJB annotation…

Caused By: javax.naming.NameNotFoundException: While trying to look up ejb-info

Which usually happens because our deployment descriptors  are not configured properly to lookup a Local Bean and when the WebLogic Container tries to inject the Local EJB in to another Bean/WebApplication it fails due. Example:

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

Step1). Create a directory somewhere in your file system like “C:demosrc”

Step2). Now place the following files inside “C:demosrc” directory:

“CalculatorLocal.java”

//CalculatorRemote.java
package calculator;
import javax.ejb.*;
@Local
public interface CalculatorLocal
{
  public int add(int x,int y);
}

“CalculatorBean.java”

package calculator;
import javax.ejb.*;

@Stateless(name="CalculatorBean")
public class CalculatorBean implements CalculatorLocal
 {
   public int add(int x,int y)
    {
	  System.out.println("nt[CalculatorBean]  add() invoked.");
      return (x+y);
    }
 }
 

“CallerRemote.java”

//CalculatorRemote.java
package caller;
import javax.ejb.*;
@Remote
public interface CallerRemote
{
     public String testMethod();
   	 public String callEJBOne(int a, int b);
}
 

“CallerBean.java”

//CalculatorBean.java
package caller;
import javax.ejb.*;
import javax.naming.*;
import java.util.*;

@Stateless(name = "CallerName", mappedName = "CallerMappedName")
public class CallerBean implements CallerRemote
 {
	 @EJB calculator.CalculatorLocal local;
     public String testMethod()
	    {
		   System.out.println("nnt Bean testMethod() called....");
		   return "DONE----returned";
	    }

	public String callEJBOne(int a, int b)
	    {
           int result=0;
		   try{
		   System.out.println("nnt Bean callEJBOne(a,b) called....");
           result=local.add(a,b);
		   }
		   catch(Exception e){ e.printStackTrace(); }
		   return "DONE----result = "+result;
	    }
 }
 

“ejb-jar.xml”

<ejb-jar version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">

<enterprise-beans>
	<session>
		<ejb-name>CallerBean</ejb-name>
		<business-remote>caller.CallerRemote</business-remote>
		<ejb-class>caller.CallerBean</ejb-class>
		<session-type>Stateless</session-type>
		<ejb-local-ref>
		        <ejb-ref-name>ejb/CalculatorLocal</ejb-ref-name>
				<local>calculator.CalculatorLocal</local>
		</ejb-local-ref>
	</session>
</enterprise-beans>
</ejb-jar>

“application.xml”

<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.4">
   <display-name>EJB3_to_EJB3_Local_Injection</display-name>

   <module>
	<ejb>ejbOne.jar</ejb>
    </module>

   <module>
	<ejb>ejbTwo.jar</ejb>
    </module>

</application>

“TestClientEjb3.java”

import caller.CallerRemote;
import javax.naming.*;
import java.util.*;
public class TestClientEjb3
{
	public static void main(String[] args)  throws Exception
	{
		  String  result="";
		System.out.println("nnt Hello ...");
		   try{
                 Properties pr=new Properties();
                 pr.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
	             pr.put(Context.PROVIDER_URL,"t3://localhost:7001");

		   InitialContext ic=new InitialContext(pr);
           CallerRemote remote=(CallerRemote)ic.lookup("CallerMappedName#caller.CallerRemote");
           result=remote.callEJBOne(1000,2000);
		   }
		   catch(Exception e){ e.printStackTrace(); }
		  System.out.println("ONE----result = "+result);
	    }
}

Step3). Now place the following “build.xml” file inside “C:demo” directory:

<project name="webservices-complex" default="deploy">

<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="wls.server.name" value="AdminServer" />
<property name="wl.home" value="C:/bea1033/wlserver_10.3" />

<property name="src.dir" value="src" />
<property name="deploy.stuff" value="deploy" />
<property name="build.dir" value="build" />
<property name="ear.name" value="EJB3LocalLookupEAR" />
<property name="ear.dir" value="${deploy.stuff}/${ear.name}" />
<property name="ejb.jar.name.1" value="ejbOne.jar" />
<property name="ejb.jar.name.2" value="ejbTwo.jar" />
<property name="client.jar.name" value="testClient.jar" />

<path id="wl.classpath">
        <fileset dir="${wl.home}/server/lib">
              <include name="*.jar"/>
        </fileset>
        <fileset dir="${ear.dir}">
              <include name="${ejb.jar.name.1}"/>
              <include name="${ejb.jar.name.2}"/>
        </fileset>
</path>

<path id="client.classpath">
        <fileset dir="${wl.home}/server/lib">
              <include name="weblogic.jar"/>
			  <exclude name="jrmp.jar"/>
        </fileset>
        <fileset dir="${build.dir}">
              <include name="${client.jar.name}"/>
        </fileset>
</path>

<target name="init">
	<mkdir dir="${build.dir}"/>
	<mkdir dir="${ear.dir}"/>
	<mkdir dir="${ear.dir}/META-INF"/>
	<mkdir dir="${deploy.stuff}" />
</target>

<target name="compile1" depends="init">
	<javac srcdir="${src.dir}" destdir="${build.dir}"  includes="CalculatorBean.java,CalculatorLocal.java"/>
	<jar destfile="${ear.dir}/${ejb.jar.name.1}" basedir="${build.dir}" />
    <delete dir="${build.dir}" />
</target>

<target name="compile2" depends="compile1">
	<mkdir dir="${build.dir}"/>
	<mkdir dir="${build.dir}/META-INF" />
	<javac srcdir="${src.dir}" destdir="${build.dir}"  includes="CallerBean.java,CallerRemote.java" classpathref="wl.classpath"/>
	<copy file="${src.dir}/ejb-jar.xml" tofile="${build.dir}/META-INF/ejb-jar.xml"/>
	<jar destfile="${ear.dir}/${ejb.jar.name.2}" basedir="${build.dir}" />
    <copy file="${src.dir}/application.xml" tofile=	"${ear.dir}/META-INF/application.xml" />
	<delete dir="${build.dir}"/>
</target>

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

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

<target name="compileClient">
	<delete dir="${build.dir}"/>
	<mkdir dir="${build.dir}"/>
	<javac srcdir="${src.dir}" destdir="${build.dir}"  includes="CallerRemote.java" classpathref="wl.classpath"/>
	<javac srcdir="${src.dir}" destdir="${build.dir}"  includes="TestClientEjb3.java" classpathref="wl.classpath"/>
	<jar destfile="${build.dir}/${client.jar.name}" basedir="${build.dir}" />
</target>

<target name="run" depends="compileClient">
    <java classname="TestClientEjb3" classpathref="client.classpath"/>
</target>

</project>

Step4). Now run the “. ./setWLSEnv.sh” to set the CLASSPATH and PATH then run the ANT script like following:

building_And_Deploying_Ejb3Local_App

building_And_Deploying_Ejb3Local_App

Step5). Now invoke the Client like following:

Running_The_Client

Running_The_Client

NOTE: Above instruction is for EJB to EJB lookup.

But if you are trying to inject an EJB  Bean inside your Servlet (WebApplication) then you must make sure that you are using the following link of “webxml”   which uses Servlet 2.5  XSD specification:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

</webapp>

.

.

Thanks

Jay SenSharma


WebLogic WorkManager with EJB3 And MaxThread Constraint

Hi,
Jay SenSharma

Jay SenSharma

WebLogic Provides us a feature to manage the WebLogic Threads per application using WorkManagers. In this demo we will see how we can instruct WebLogic to allocate only one thread to process the Clients request. We will develop a simple EJB3 application and we will assign a WorkManager with MaxThreadConstraint as 2. It means for Any number of Clients request to that EJB, the WebLogic will allocate only 1 Thread for request processing.
.
Step1). Please follow the instructions mentioned in the  link: http://middlewaremagic.com/weblogic/?p=2691 to create WebLogic WorkManager in seconds using WLST. Just make sure that you chose the following values for Max and Min Threads to see how this sample works. Later you can use your own values.
MaxThread=2
MinThread=2
.
Step2). Now create a Directory somewhere in your file system like:  “C:tempEJB3_With_WorkManager”
.
Step3). Now create a EJB remote Interface “CalculatorRemote.java” inside “C:tempEJB3_With_WorkManager” like following:
//CalculatorRemote.java
package calculator;
import javax.ejb.*;
@Remote
public interface CalculatorRemote
{
  public int add(int x,int y);
}
Step4). Now ssame way create a Stateless Session Bean “CalculatorBean.java” inside “C:tempEJB3_With_WorkManager” like following:
//CalculatorBean.java
package calculator;
import javax.ejb.*;
@Stateless
public class CalculatorBean implements CalculatorRemote
 {
   public int add(int x,int y)
    {
	  System.out.println("Current ThreadName Is: "+Thread.currentThread().getName());
      return (x+y);
    }
 }
Step5). Now create a directory with name “META-INF” inside “C:tempEJB3_With_WorkManager” and then create a file “weblogic-ejb-jar.xml”  inside “C:tempEJB3_With_WorkManagerMETA-INF”  directory like following so that we can assign the WebLogic WorkManager to the EJB using “dispatch-policy” tag:
<?xml version='1.0' encoding='UTF-8'?>
<weblogic-ejb-jar xmlns="http://www.bea.com/ns/weblogic/10.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <weblogic-enterprise-bean>
    <ejb-name>CalculatorBean</ejb-name>
    <stateless-session-descriptor>
      <pool></pool>
      <stateless-clustering>
        <home-is-clusterable>false</home-is-clusterable>
        <stateless-bean-is-clusterable>false</stateless-bean-is-clusterable>
      </stateless-clustering>
    </stateless-session-descriptor>
    <transaction-descriptor></transaction-descriptor>
    <jndi-name>X</jndi-name>
    <dispatch-policy>JackWorkManager</dispatch-policy>
    <remote-client-timeout>0</remote-client-timeout>
  </weblogic-enterprise-bean>
</weblogic-ejb-jar>
Step6). Now run the “setWLSEnv.cmd” in a command prompt to set the classpath then Compile and EJBs and then make a Jar of it like following:
compiling_Ejb3

compiling_Ejb3

Step7). Now deploy the above created EJB3 jar file “Ejb3.jar” in WebLogic Server.
.
Step8). Check the AdminConsole where you are able to see the WorkManager properly assigned to your EJB3 or Not?
 EJB3_Workmanager_Console_look

EJB3_Workmanager_Console_look

Step9). Now Create a Client somewhere in your file system and set the Classpath to Ejb3.jar which we created above…. Client program like following “Ejb3Client.java”.  This client is going to send 5000 fresh requests to the WebLogic Server.
package calculator;
import javax.naming.*;
import java.util.*;
public class  Ejb3Client
{
	public final static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
	private static String serverUrl ="t3://localhost:7001";
	public static void main(String[] ar)  throws Exception
	{
		for(int i=0;i<=5000;i++)
		 {
           InitialContext ic=null;
           try{
		        Hashtable env = new Hashtable();
		        env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
		        env.put(Context.PROVIDER_URL, serverUrl);
  		        ic = new InitialContext(env);
              }
            catch(Exception e)
             {
			    System.out.println("nt Didnot get InitialContext: "+e);
			 }
           try
             {

                Object obj=ic.lookup("calc#calculator.CalculatorRemote");
                CalculatorRemote remote=(CalculatorRemote)obj;
                System.out.println("nntRemote=>"+remote.getClass());

				System.out.println("nntClassLoading=>1");
                Class.forName("calculator.CalculatorRemote");
				System.out.println("nntClassLoading=>2");

                System.out.println("nnt SUM = "+remote.add(Integer.parseInt(ar[0]),Integer.parseInt(ar[1])));
             }
           catch(Exception e)
             {
                System.out.println("nnt jack Exception => "+e);
                e.printStackTrace();
             }
           System.out.println("nt Iteration ------------ "+i);
	    }
	}
}

Step10). Run the client and then check the Server STDOUT that all the 5000 request will be processed only by a Two Execute Thread….It means due to MaxThreadConstraint=2 the WebLogic will not allocate more than two thread to process clients request.
EJB3_Workmanager_Client_Console_Output

EJB3_Workmanager_Client_Console_Output

In the output (STDOUT) of the Server you will see that there are only 2 Threads which are processing all the 5000 Clients request…..

Current ThreadName Is: [ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'
Current ThreadName Is: [ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'
.
.
Thanks
Jay SenSharma

Tuning EJB3 Application using Plan.xml

Hi,

Jay SenSharma

Jay SenSharma

In response to comment posted regarding tunning of EJB3 app:   http://middlewaremagic.com/weblogic/?p=1696#comment-1356

Here is a Simple Demonstration of Changing the Tunable Parameters of an EJB3.0 application using “Plan.xml”. As we have many annotations available as part of EJB3.0 Specifications But we dont have the Annotations available for many Tunable parameters like “max-beans-in-free-pool”, “initial-beans-in-free-pool”…etc. If we want to change/add these values for our EJB3.0/EJB2.x Application then we have have to change provide our own “weblogic-ejb-jar.xml” file.

But In Most of the production scenarios The WebLogic Administrator doesnt have priviledge to change any thing inside the EJB jar module. So in that case A WebLogic AdminiStartor can use the “Plan.xml” file to change these Tunable Parameters Settings…

Step1). Create a Directory somewhere in your file system.
Example: C:EJB3_Plan_XML_Demo

Step2). Create a Directory “EJB3App” inside Directory “C:EJB3_Plan_XML_Demo”

Step3). Provide the EJB3 Business Interface “CalculatorRemote.java” inside “C:EJB3_Plan_XML_DemoEJB3App”

package calculator;
import javax.ejb.*;
@Remote
public interface CalculatorRemote
{
public int add(int x,int y);
public int sub(int x,int y);
public int mult(int x,int y);
public int div(int x,int y);
}

Step4). Provide the EJB3 Stateless Bean Implementation class “CalculatorBean.java” inside “C:EJB3_Plan_XML_DemoEJB3App”

package calculator;
import javax.ejb.*;
@Stateless
public class CalculatorBean implements CalculatorRemote
{
public int add(int x,int y)
{
return (x+y);
}
public int sub(int x,int y)
{
return(x-y);
}
public int mult(int x,int y)
{
return (x*y);
}
public int div(int x,int y)
{
return (x/y);
}
}

Step5). Now Create a directory “META-INF” inside “C:EJB3_Plan_XML_DemoEJB3App” and then provide an Empty “weblogic-ejb-jar.xml” file 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>

NOTE: Step5 is the Most important Step because if we want to override setting of any descriptor then at least that file must exist inside our application….doesn’t matter if it is Empty or having some contents inside it.

Step6). Now a command prompt and the run the “setWLSEnv.cmd” and then Compile the above two ejb stuffs.

Compiling_EJB3_App

Compiling_EJB3_Ap

Step7). Write the “build.xml” file to deploy your Application…inside “C:EJB3_Plan_XML_Demo” like following:

<project name="webservices-hello_world" default="deploy">
<!-- set global properties for this build -->
<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="wls.server.name" value="AdminServer" />

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

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

</project>

Step8). Now open a Command prompt and then run “setWLSEnv.cmd” then run the above ant “build.xml” file to deploy your application:

Deploying_EJB3_App_using_Ant

Deploying_EJB3_App_Using_Ant

Step9). Now Login to Admin Consoel to see how many initial beans have been created for our EJB3App.

Step10). Now Provide the “plan.xml” file inside “C:EJB3_Plan_XML_Demo” location as following to change the “initial-bean-in-free-pool” setting for our EJB3App…

<?xml version=’1.0' encoding=’UTF-8'?>
<deployment-plan xmlns="http://www.bea.com/ns/weblogic/deployment-plan" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bea.com/ns/weblogic/deployment-plan http://www.bea.com/ns/weblogic/deployment-plan/1.0/deployment-plan.xsd" global-variables="false">
<application-name>EJB3App</application-name>

<variable-definition>
<variable>
<name>initialPoolVariable</name>
<value>15</value>
</variable>
</variable-definition>

<module-override>
<module-name>EJB3App</module-name>
<module-type>ejb</module-type>
<module-descriptor external="true">
<root-element>weblogic-ejb-jar</root-element>
<uri>META-INF/weblogic-ejb-jar.xml</uri>
<variable-assignment>
<name>initialPoolVariable</name>
<xpath>/weblogic-ejb-jar/weblogic-enterprise-bean/[ejb-name="CalculatorBean"]/stateless-session-descriptor/pool/initial-beans-in-free-pool</xpath>
</variable-assignment>
</module-descriptor>
</module-override>

<config-root>C:EJB3_Plan_XML_Demo</config-root>
</deployment-plan>

Step11). provide the “build_with_plan.xml” file inside “C:EJB3_Plan_XML_Demo” to redepoy the application with the settings provided as part of our “plan.xml” file. Like following :

Redeploying_EJB_Using_Pla

Redeploying_EJB_Using_Pla

Step12). Now again Login to AdminConsole and then see the Monitoring Tab of your EJB3App … like following:

AfterRedeploying_UsingPlan

AfterRedeploying_UsingPlan

.

.

Thanks

Jay SenSharma


Copyright © 2010-2012 Middleware Magic. All rights reserved. |