Tag: EJB

Resource DataSource Injection in EJB3

Hi,

Jay SenSharma

Jay SenSharma

Here we are going to see how we can use the DataSources inside our EJB3.0 Application. Basically there are two Options to get the DataSource object inside the EJB3 Beans.

Option-1). Using Traditional Way we can get the dataSource Object by Looking up in the JNDI tree of the Server to get teh dataSource object.
Option-2). Using the resource Injection techniqueue we can get the DataSource object in two lines of codes…(it reduces the code length as well)
In the below demonstration we will use two fidderent methods to get the DataSource objects in above two ways using two different Business methods.

Step1). Please refer to the following Link to Create a DataSource through the Admin Console…http://middlewaremagic.com/weblogic/?p=2050

Step2). Now Create a Directory somewhere in your file system like “C:Resource_Injection” this directory is going to become our EAR Application.

Step3). Now Create another Directotry “MyEJB” inside “C:Resource_Injection”.

Step4). Write the EJB Interface “CalculatorRemote.java” inside “C:Resource_InjectionMyEJB” like following:

package calculator;
import javax.ejb.*;
import javax.sql.DataSource;
@Remote
public interface CalculatorRemote
{
public String getDataSourceUsingTraditionalWay(String query);
public String getDataSourceUsingResourceInjection(String query);
}

Step4a). Write the EJB Stateless Session Bean class “CalculatorBean.java” inside “C:Resource_InjectionMyEJB” like following:

package calculator;
import javax.ejb.*;
import javax.naming.*;
import javax.sql.*;
import java.sql.*;
import javax.annotation.*;

@Stateless(mappedName="calc")
public class CalculatorBean implements CalculatorRemote
{
@Resource(mappedName="TestDSJndi")
DataSource injectedDataSource;
public String getDataSourceUsingResourceInjection(String query)
{
System.out.println("inside betterWayToGetDataSourceUsingResourceInjection() method ");
System.out.println("betterWayToGetDataSourceUsingResourceInjection() got DS = "+injectedDataSource);
String result=this.executeSQL(query,injectedDataSource);
return result;
}

public String getDataSourceUsingTraditionalWay(String query)
{
DataSource traditionalDS=null;
try{
InitialContext ic=new InitialContext();
traditionalDS=(DataSource)ic.lookup("TestDSJndi");
System.out.println("nt Inside getDataSourceUsingTraditionalWay.....Got DataSource = "+traditionalDS);
}
catch(Exception e)
{
System.out.println("nt Unable to get DataSource using getDataSourceUsingTraditionalWay: "+e);
}
String result= this.executeSQL(query,traditionalDS);
return result;
}

public String executeSQL(String query,DataSource ds)
{
Connection con=null;
Statement stmt=null;
ResultSet rs=null;
String resultString="";
try{
con=ds.getConnection();
stmt=con.createStatement();
rs=stmt.executeQuery(query);
int tableCount=1;
System.out.println("nt Following Tables Are Available in Systables of Pointbase..");
while(rs.next())
{
String tableName=rs.getString(2);
System.out.println("t Table-"+tableCount+":t"+tableName);
tableCount++;
resultString=resultString+"<BR>"+tableName;
}
}
catch(Exception e)
{
System.out.println("nt Exception Occured: "+e);
}
finally
{
try { if(rs!=null) rs.close(); }
catch (Exception rse) {}
try { if(stmt!=null) stmt.close(); }
catch (Exception sse) {}
try { if(con!=null) con.close(); }
catch (Exception cse) {}
}
return "Result Of Query: "+query+" is Following: "+resultString;
}
}

Step5). Open a command prompt then run “setWLSEnv.cmd” here and then compile the EJBs like following:

Compiling EJB  Classes

Compiling EJB Classes

Step6). Now Create a Directory “MyWebApp” inside “C:Resource_Injection”

Step7). Now Create “WEB-INF” Directory and provide the following “web.xml” file inside “C:Resource_InjectionMyWebAppWEB-INF”

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


NOTE: Make Sure that you are using the Latest “web.xml” Schema because the Resource Injection and EJB Injection is supported from Servlet Specification 2.5…So make sure that u are not using any “web.xml” file which is using DTD declarations.

Step8). Provide the following “index.jsp” file inside “C:Resource_InjectionMyWebApp” directory.

<%@ page import="javax.sql.*,calculator.*, javax.naming.*" %>
<%
InitialContext ic=new InitialContext();
CalculatorRemote remote=(CalculatorRemote)ic.lookup("calc#calculator.CalculatorRemote");
String result=remote.getDataSourceUsingTraditionalWay("SELECT * FROM SYSTABLES");
System.out.println("nt Result TRADITIONAL WAY: "+result);
out.println("<h2>Result TRADITIONAL WAY</h2><BR> "+result);

System.out.println("<h2>Standard Way of Getting DataSource Using Resource Injection BELOW</h2>");
String resultInjected=remote.getDataSourceUsingResourceInjection("SELECT * FROM SYSTABLES");
System.out.println("nt Result RECOMMENDED INJECTED WAY: "+resultInjected);
out.println("<h2>Result RECOMMENDED INJECTED WAY</h2><BR> "+resultInjected);
%>

Step9). Create a “META-INF” directory inside “C:Resource_Injection” to provide the EAR deployment descriptors inside it. Create a file “application.xml” inside “C:Resource_InjectionMETA-INF” like following:

<?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">
<module>
<ejb>MyEJB</ejb>
</module>
<module>
<web>
<web-uri>MyWebApp</web-uri>
<context-root>MyWebApp</context-root>
</web>
</module>
</application>

Step10). Your Application is ready for deployment…Open Admin Console and then Deploy the “Resource_Injection” there….this is your EAR application.

Step11). Hit the Application like : http://localhost:7001/MyWebApp/index.jsp

.
.
Thanks
Jay SenSharma


EJB3 WebLogic10.3 and Generics Issue

Hi,

Jay SenSharma

Jay SenSharma

If we use any Generic implementation in EJB3.0 deployed on weblogic Server then we face some errors like following:

Example:
package test;
import java.util.List;
public interface TestGenericsInEJB3
{
public List callPlainMethod();
public List<User> callGenericMethod();
}

If our EJB3 Bean uses the above Interface as a remote Interface then we will find the following kind of exception while invoking it remotely.

java.lang.AssertionError: Can not find generic method public abstract java.util.List<test.
TestGenericsInEJB3> callGenericMethod() in EJB Object
at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.getTargetMethod(RemoteBusinessIntfProxy.java:159)
at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:53)
at $Proxy79.
callGenericMethod(Unknown Source)
at jsp_servlet.__index._jspService(__index.java:53)

There are two following possibilities for the above Exception:

Case-1: When the business interface extends java.rmi.Remote, and extends some generic methods from a super class, the deployment will fail.
Workaround: This case is a limitation in WLS 10.3 or greater and hence no workaround applicable.

Case-2: When the business interface doesn’t extend java.rmi.Remote, the invocation on the generic business methods will fail.
Workaround: It can be resolved by downloading the needed classes from the server side. If network downloading is disabled, however, the invocation will fail still.

If network downloading isn’t permitted in the user’s environment, it is recommended that you run appc first, then add the generated classes to the classpath of the client side. Please refer to the following link to see how we can generate the EJB Client Jar: http://middlewaremagic.com/weblogic/2010/04/02/generating-ejb3-clientjar/

.
.
Thanks
Jay SenSharma


Generating EJB3 ClientJar using APPC utility

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


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