| Home: www.vipan.com | Vipan Singla | e-mail: vipan@vipan.com |
localhost at port 7001), use the "java weblogic.admin" stand-alone Java application.
java weblogic.admin http://localhost:7001 SHUTDOWN system systemPWD
java weblogic.admin http://localhost:7001 PING 23 2048
java weblogic.admin http://localhost:7001 CONNECT 30
java weblogic.admin http://localhost:7001 LIST cubicle system systemPWD
java weblogic.admin http://localhost:7001 VERSION
java weblogic.admin http://localhost:7001 LICENSES
localhost at port 7001), use the Weblogic console either from Windows Start menu or by issuing (after setting the Weblogic client classpath):java weblogic.console
localhost at port 7001), go to url http://localhost:7001/AdminMain. This will call the Weblogic administration servlet which is available by default. When the authentication dialog box pops up, you MUST login as username "system" with your Weblogic system password (look in "weblogic.properties" files if you forgot).
t3://localhost:7001). Replacing "t3" with "http" in clients is OK but slower. T3 is named after "Tengah" which is the old name for Weblogic.
weblogic.class.path with a value of weblogicDir\lib\weblogicaux.jar;weblogicDir\classes;
weblogicDir\license;weblogicDir\myserver\classes to the Java system properties list.
It not only allows Weblogic to activate EJBs and dynamically load classes during runtime, but also enables you to "hot-deploy" your EJBs into a running Weblogic server.
weblogicDir\lib\weblogicaux.jar;weblogicDir\classes. The file "cloudscape.jar" can also be included if using the CloudScape pure-Java file-based database (as opposed to a database server such as Oracle or MySql running on a port).
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
public interface Converter extends EJBObject
{
public double dollarToYen(double dollars) throws RemoteException;
public double yenToEuro(double yen) throws RemoteException;
}
import java.io.Serializable;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
public interface ConverterHome extends EJBHome
{
Converter create() throws RemoteException, CreateException;
}
import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
public class ConverterEJB implements SessionBean
{
public double dollarToYen(double dollars)
{
return dollars * 121.6000;
}
public double yenToEuro(double yen)
{
return yen * 0.0077;
}
public ConverterEJB() {}
public void ejbCreate() {}
public void ejbRemove() {}
public void ejbActivate() {}
public void ejbPassivate() {}
public void setSessionContext(SessionContext sc) {}
}
jar cvf converting.jar Converter.class ConverterHome.class ConverterEJB.class
<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC
'-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN'
'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'>
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>conv</ejb-name>
<home>ConverterHome</home>
<remote>Converter</remote>
<ejb-class>ConverterEJB</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
<assembly-descriptor></assembly-descriptor>
</ejb-jar>
jar uvf <path-to>converting.jar META-INF
<?xml version="1.0"?>
<!DOCTYPE weblogic-ejb-jar PUBLIC
'-//BEA Systems, Inc.//DTD WebLogic 5.1.0 EJB//EN'
'http://www.bea.com/servers/wls510/dtd/weblogic-ejb-jar.dtd'>
<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>conv</ejb-name>
<jndi-name>ConverterApp</jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>
jar uvf <path-to>converting.jar META-INF
java weblogic.ejbc converting.jar convertingWLS.jar
java weblogic.deploy -host http://localhost -port 7001 systemPWD ConverterApp file:///convertingWLS.jar
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import Converter;
import ConverterHome;
public class ConverterClient
{
public static void main(String[] args)
{
try
{
Context initial = new InitialContext();
Object objref = initial.lookup("MyConverter");
ConverterHome home =
(ConverterHome)PortableRemoteObject.narrow(objref,
ConverterHome.class);
Converter currencyConverter = home.create();
double amount = currencyConverter.dollarToYen(100.00);
System.out.println(String.valueOf(amount));
amount = currencyConverter.yenToEuro(100.00);
System.out.println(String.valueOf(amount));
currencyConverter.remove();
}
catch (Exception ex)
{
System.err.println("Caught an unexpected exception!");
ex.printStackTrace();
}
}
}
javac -classpath .;c:\j2ee\j2ee.jar ConverterClient.java
java -cp .;c:\j2ee\j2ee.jar;c:\weblogic\classes; c:\weblogic\lib\weblogicaux.jar ConverterClient
|
A servlet can maintain session with numerous clients and yet connect as one client to the EJB server. Thus, the server need only maintain one EJB instance per servlet instead of hundreds of EJB instances for, say, stand-alone Java application clients.
Many different servlets may connect to the same EJB server, wanting to run the same business method to validate something. So, the EJB server will still have the option of creating multiple instances of an EJB.
Servlets usually work with a session EJB which in turn works with an entity EJB.
Reason not to have business logic in entity EJBs: On any method call to an entity EJB, the EJB server first checks the underlying database to make sure that the entity EJB instance being accessed contains the most up-to-date data (Other clients may have modified the underlying data). This means calling the time-consuming "ejbLoad()" and "ejbStore()" methods. But the server does not do that for session EJBs, so they are faster.
extends SessionBean or EntityBean depending on which one you want.
extends EJBHome interface (not implement). It is used as a factory to create, find and delete instances of your EJB class.
extends EJBObject interface (not implement). The subclass of its server-side skeleton is the actual "remote" object that your client will be accessing and calling methods on.
SessionContext or EntityContext object depending on the type of EJB,
Although a servlet could have validated the data itself and written it to the database, by using an EJB, many servlets or applets can access the same business logic which only needs to be changed in one place instead of changing it in each client.
The EJB server also adds automatic transaction control, if you want it.
Multiple clients can not get the same EJB by "creating" new stateful session beans and setting their data attributes to the same values.
EJBHome, "remote" interface extends EJBObject.
When many clients call the "findByPrimaryKey()" method and specify the same primary key, the EJB server creates only one instance of the entity EJB object with that primary key. It, however, creates remote stubs specific to each client. Your one EJB object can retrieve client-specific information through the EntityContext object.
Remember, clients never access the EJB object directly. They call the methods of the "remote" interface (stub). The EJB server passes these calls to the server-generated "remote" object WHICH, IN TURN, PLACES A LOCAL CALL TO THE CORRESPONDING METHODS OF THE EJB OBJECT.
The primary key class and all its attributes must be "public" with a no-argument constructor (if you want to write one). It must be serializable so that it can be sent to the client over the wire. It must define its own public int hashcode() and public boolean equals(Object other) methods. Its data attributes must be among those persisted to the underlying database.
When you change the values in the EJB class, the EJB server automatically updates the corresponding attributes in the primary key class.
|
javax.ejb.CreateException and return the EJB's "remote" interface.
java.rmi.CreateExeception.
SessionContext or EntityContext object which contains the client and associated "remote" object information
SessionContext object.
java.rmi.RemoteException in the EJB class methods. It is technically not a remote object. The remote objects are the server-generated classes implementing the EJB's "home" and "remote" interfaces. The EJB instance merely responds locally to method calls from those implementations.
jar uvf ... and restart the server (or hot deploy).
ejb-jar.xml file. It basically tells the EJB server the class names for the home interface, the remote interface and the real working EJB class itself. It also tells the server whether it is an entity EJB or a session EJB.
You also give a (fake) name to your EJB here and refer to this EJB with that fake name in all related .xml files. It will not be used outside the XML files for deployment. Here is a minimal example of an "ejb-jar.xml" file:
<enterprise-beans>
<session>
<ejb-name>FibonacciComputationEJB</ejb-name>
<home>com.bea.EJBD.examples.FibonacciComputationHome</home>
<remote>com.bea.EJBD.examples.FibonacciComputation</remote>
<ejb-class>com.bea.EJBD.examples.FibonacciComputationBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
You can specify multiple beans in one file, one bean per The jBoss server requires "jBoss.xml" for the same purpose.
weblogic-ejb-jar.xml.
<ejb-name>name-you-gave-in-ejb-jar.xml</ejb-name>
<jndi-name>GreenBeans</jndi-name>
java -verbose -d c:\junk2 -classpath c:\junk2; c:\j2ee\j2ee.jar -sourcepath c:\junk c:\junk\pkg1\subpkg1\src-file.java
jar tvf to list the JAR file contents, just to make sure. This is a standard Java requirement.
The best way to do this is to first change your current directory to just above the first directory of your package structure
cd c:\junk2 jar cvf c:\junk2\junky.jar pkg1
This will have the effect of starting with the first directory within your package structure and recursively bundle all files and subdirectories within it, preserving the directory tree.
If you have multiple packages, run the jar uvf command on each package but after changing directory to the root of each package.
cd c:\junk jar uvf c:\junk2\junky.jar META-INF
"META-INF" must be written in all uppercase letters even if your operating system (Windows) is not case-sensitive (because Java is!).
cd c:\junk jar uvf c:\junk2\junky.jar META-INF
Note that this will pick up all the files and subdirectories of the "META-INF" directory and bundle them into the JAR file.
Other servers take your JAR file and generate these on the fly as needed during startup and deployment.
For Weblogic, you need to run a command to do so.
java weblogic.ejbc c:\junk2\junky.jar c:\junk\junkyForWeblogic.jar
[EJB]: Creating output jar:wantedFinalJar.jar
weblogic.ejb.deploy= \ c:/junk2/junky.jar, \ <path-to>someOther.jar
The "weblogic.ejb.deploy" property can only appear in one place and all comma-separated JAR files are to be added there.
Enter any name in the "Deployment unit name" field but enter the full absolute path name to the JAR file in the "Bean file location" field.
java weblogic.deploy -host http://www.ahost.com -port 7001 systemPWD
EjbJndiNameWanted file:///c:/test/EJB/yourEJB.jar
If you have problems running the tool, make sure that the "classes" subdirectory of your weblogic installation and the "weblogicaux.jar" file are in the "java" classpath.
If you get errors while deploying, make sure that the JDBC drivers and databases you have specified in your EJB are in the Java classpath as well (e.g. "cloudscape.jar")
Other commands of the "weblogic.deploy" application:
java weblogic.deploy list systemPWD java weblogic.deploy undeploy systemPWD c:/test/EJB/yourEJB.jar java weblogic.deploy -help
java weblogic.ejb.ui.deployer.DeployerTool
Stateful to Stateless for a stateless session EJB)
<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC
'-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN'
'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'>
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>cart</ejb-name>
<home>shop.ShoppingCartHome</home>
<remote>shop.ShoppingCart</remote>
<ejb-class>shop.ShoppingCartBean</ejb-class>
<session-type>Stateful</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
<assembly-descriptor></assembly-descriptor>
</ejb-jar>
<?xml version="1.0"?>
<!DOCTYPE weblogic-ejb-jar PUBLIC
'-//BEA Systems, Inc.//DTD WebLogic 5.1.0 EJB//EN'
'http://www.bea.com/servers/wls510/dtd/weblogic-ejb-jar.dtd'>
<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>cart</ejb-name>
<jndi-name>ShoppingCartEJB</jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>
<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC
'-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN'
'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'>
<ejb-jar>
<enterprise-beans>
<entity>
<ejb-name>Transcript</ejb-name>
<home>transcript.TranscriptHome</home>
<remote>transcript.Transcript</remote>
<ejb-class>transcript.TranscriptBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>transcript.TranscriptPK</prim-key-class>
<reentrant>False</reentrant>
<cmp-field>
<field-name>school</field-name>
</cmp-field>
<cmp-field>
<field-name>gpa</field-name>
</cmp-field>
<cmp-field>
<field-name>degree</field-name>
</cmp-field>
<cmp-field>
<field-name>id</field-name>
</cmp-field>
<cmp-field>
<field-name>major</field-name>
</cmp-field>
<cmp-field>
<field-name>name</field-name>
</cmp-field>
</entity>
</enterprise-beans>
<assembly-descriptor></assembly-descriptor>
</ejb-jar>
<?xml version="1.0"?>
<!DOCTYPE weblogic-ejb-jar PUBLIC
'-//BEA Systems, Inc.//DTD WebLogic 5.1.0 EJB//EN'
'http://www.bea.com/servers/wls510/dtd/weblogic-ejb-jar.dtd'>
<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>Transcript</ejb-name>
<persistence-descriptor>
<persistence-type>
<type-identifier>WebLogic_CMP_RDBMS</type-identifier>
<type-version>5.1.0</type-version>
<type-storage>
META-INF/weblogic-cmp-jar.xml
</type-storage>
</persistence-type>
<persistence-use>
<type-identifier>WebLogic_CMP_RDBMS</type-identifier>
<type-version>5.1.0</type-version>
</persistence-use>
</persistence-descriptor>
<jndi-name>TranscriptEJB</jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>
<?xml version="1.0"?>
<!DOCTYPE weblogic-rdbms-bean PUBLIC
"-//BEA Systems, Inc.//DTD WebLogic 5.1.0 EJB RDBMS Persistence//EN"
"http://www.bea.com/servers/wls510/dtd/weblogic-rdbms-persistence.dtd">
<weblogic-rdbms-bean>
<pool-name>TranscriptPool</pool-name>
<schema-name></schema-name>
<table-name>Transcript</table-name>
<attribute-map>
<object-link>
<bean-field>school</bean-field>
<dbms-column>SCHOOL</dbms-column>
</object-link>
<object-link>
<bean-field>gpa</bean-field>
<dbms-column>GPA</dbms-column>
</object-link>
<object-link>
<bean-field>degree</bean-field>
<dbms-column>DEGREE</dbms-column>
</object-link>
<object-link>
<bean-field>id</bean-field>
<dbms-column>ID</dbms-column>
</object-link>
<object-link>
<bean-field>major</bean-field>
<dbms-column>MAJOR</dbms-column>
</object-link>
<object-link>
<bean-field>name</bean-field>
<dbms-column>NAME</dbms-column>
</object-link>
</attribute-map>
<finder-list>
</finder-list>
<options>
<use-quoted-names>false</use-quoted-names>
</options>
</weblogic-rdbms-bean>
<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC
'-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN'
'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'>
<ejb-jar>
<enterprise-beans>
<entity>
<ejb-name>AlarmClockBMP</ejb-name>
<home>examples.AlarmClockBMPHome</home>
<remote>examples.AlarmClockBMP</remote>
<ejb-class>examples.AlarmClockBMPBean</ejb-class>
<persistence-type>Bean</persistence-type>
<prim-key-class>examples.AlarmClockBMPPK</prim-key-class>
<reentrant>False</reentrant>
</entity>
</enterprise-beans>
<assembly-descriptor></assembly-descriptor>
</ejb-jar>
<?xml version="1.0"?>
<!DOCTYPE weblogic-ejb-jar PUBLIC
'-//BEA Systems, Inc.//DTD WebLogic 5.1.0 EJB//EN'
'http://www.bea.com/servers/wls510/dtd/weblogic-ejb-jar.dtd'>
<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>AlarmClockBMP</ejb-name>
<jndi-name>AlarmClockBMPEJB</jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>
initCtx.lookup("java:/comp/env/your-env-name");
Note that, in the client's classpath, you will need:
All these required files may be bundled up in a JAR file and physically shipped to the client. The client can then just include that JAR file in its classpath.
Note that you do not need to give the actual bean implementation class (the one that extends EntityBean or SessionBean) to the client. So, you are free to make changes to it on the server side as long as the method arguments and return values in the "home" and "remote" interfaces still remain valid.
Just to compile the client, you do not need the Weblogic (or some other EJB server) specific library classes or JAR files. However, you do need these when running the client if you are connecting to the Weblogic server.
<weblogic-dir>\classes;%lt;weblogic-dir>\lib\weblogicaux.jar.
java weblogic.deploy -host http://www.ahost.com -port 7001 list systemPWD
import javax.naming.*;
import java.util.*;
import javax.rmi.PortableRemoteObject;
...
...
...
try {
Properties env = new Properties();
env.setProperty("java.naming.factory.initial",
"weblogic.jndi.WLInitialContextFactory");
env.setProperty("java.naming.provider.url", "http://localhost:7001");
Context ctx = new InitialContext(env);
Object oj = ctx.lookup("Blnky");
BlankyHome hm = (BlankyHome)PortableRemoteObject.narrow(
oj, BlankyHome.class);
} catch(NamingException e) { ... }
remove(a-handle), remove(an-object), getEJBMetaData(), getHomeHandle().
Blanky bl = (Blanky)PortableRemoteObject.narrow(hm.create(), Blanky.class);
getEJBHome(), getHandle(), getPrimaryKey(), isIdentical(), remove().
bl.getHandle()) while you were still connected to the EJB object AND saved (serialized) that handle to a disk file.
Your client program can then crash, restart, retrieve the handle from the disk (which will instantiate the same handle object again), and call getEJBObject() method on that handle to reconnect to the EJB object you were dealing with. Of course, the EJB object should still exist on the EJB server.
//Saving the handle to a disk file
Handle handle = bl.getHandle();
try {
ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream("myhandle.ser") );
oos.writeObject(handle);
oos.flush();
oos.close();
}catch (Exception e) {}
//Later, retrieving the handle from the disk
//Another client can also retrieve it to "share" the EJB object!
File handleFile = new File("myhandle.ser");
Blanky bl2;
if (handleFile.exists())
{
FileInputStream fis = new FileInputStream(handleFile);
ObjectInputStream ois = new ObjectInputStream(fis);
Handle handle = (Handle) ois.readObject();
bl2 = (Blanky) handle.getEJBObject();
}
Now, call Blanky's methods on bl2 to run your business.
isIdentical() method on a stateless-session-EJB always returns true.
This is the ideal scenario. In reality, to improve performance, there are four isolation levels:
In EJB's UserTransaction object, you set these isolation levels as follows:
TransactionRequired exception to the client without even accessing the EJB. The EJB server will not, however, start a transaction on behalf of the client when calling this EJB's methods (see "TX_REQUIRED").
javax.transaction.UserTransaction interface. This interface has "begin()", "commit()" and "rollback()" methods.
entityCtx.setRollbackOnly(); to flag the unsuccessful statement execution within your own method to the rest of the world, but not start roll-back yourself)
Type 2 driver translates its calls to the native (C, C++ etc.) API calls of the wanted database and then calls the wanted database directly. Both need database-specific native drivers to be installed on the client machine.
Type 4 driver is for databases that have written their APIs in Java (as opposed to C or C++). So, no translation is needed by the driver, it calls the database using its Java API. Type 1, 2 and 4 are two-tier (client-server) drivers.
Type 3 driver is a multi-tier (n-tier) driver. It is database independent unlike Type 2 and 4 drivers. Type 3 driver itself connects to a web or application server on a network. The server, in turn, knows how to pass the driver calls to the wanted database which is also connected to the same network. The server generally talks to the wanted database using Type 1, 2 or 4 drivers.
Class.forName("some-class-name-string") method.
How it works: Class.forName() method looks for the specified .class file in the classpath of the "java" command used to execute the .class file containing this method call. If found, this method loads the .class file specified as the method argument in the running Java VM. During loading, this class registers itself with the DriverManager class.
//////// Simple Connection
Connection connection
= DriverManager.getConnection("jdbc:dbVendorHere:dbNameHere");
//////// Type 2 connection using a username and password
// (Pass empty strings if none required)
Properties dbprops = new Properties();
dbprops.put("user", "scott");
dbprops.put("password", "tiger");
dbprops.put("server", "DEMO");
Connection connection =
DriverManager.getConnection("jdbc:weblogic:oracle", dbprops);
//////// Type 3 connection using server-side connection pools
Properties t3props = new Properties();
// Specify the URL of the Weblogic server to connect to, including port
t3props.put("weblogic.t3.serverURL", "t3://localhost:7001");
// Create "phoneBook" connection pool. Only required parameters are shown here.
// Append to "myserver\weblogic.properties" file:
// weblogic.jdbc.connectionPool.phoneBook=\
// url=jdbc20:weblogic:oracle,\
// driver=weblogic.jdbc20.oci.Driver,\
// maxCapacity=10,\
// capacityIncrement=1,\
// props=user=SCOTT;password=tiger;server=DEMO
// Must also add an ACL for the connection pool
// weblogic.allow.reserve.weblogic.jdbc.connectionPool.phoneBook=everyone
t3props.put("weblogic.t3.connectionPoolID", "phoneBook");
// (Optional) Connection name to display in Weblogic Console
t3props.put("weblogic.t3.name", "SimpleDB");
// (Optional) Your description to display in Weblogic Console
t3props.put("weblogic.t3.description", "Phone Book Connection");
// Instantiate a weblogic t3 driver object from known class name
Class.forName("weblogic.jdbc.t3.Driver");
Connection connection =
DriverManager.getConnection("jdbc:weblogic:t3", t3props);
Statement statement = connection.createStatement();
ResultSet class extends the Enumeration class.
try
{
connections.setAutoCommit(false);
Statement stm = connection.createStatement();
stm.executeUpdate("UPDATE ...");
stm.executeUpdate("UPDATE ...");
stm.executeUpdate("UPDATE ...");
...
connection.commit();
}
catch(Exception e)
{
connection.rollback();
}
jdbc:weblogic:t3 driver in a client-side class file. Never use this driver in a server-side class file. It always makes calls over the TCP/IP.
Here "t3" is the name of Type 3 driver that connects to the Weblogic server (no relations to Weblogic's "t3" communications protocol).
jdbc.weblogic.oracle or Oracle-provided JDBC driver) or Weblogic's "POOL" driver in a server-side class file. All of these drivers support connection pooling.
# Two-tier connection testing java utils.dbping ORACLE bill secret DEMODATABASE # Multi-tier connection testing java utils.t3dbping http://localhost:7001 scott tiger DEMODATABASE weblogic.jdbc.oci.Driver jdbc:weblogic:oracle
weblogic.jdbc.connectionPool.phoneBook=\
url=jdbc20:weblogic:oracle,\
driver=weblogic.jdbc20.oci.Driver,\
maxCapacity=10,\
capacityIncrement=1,\
props=user=SCOTT;password=tiger;server=garbage
#Must also add an ACL for the connection pool
weblogic.allow.reserve.weblogic.jdbc.connectionPool.phoneBook=everyone
weblogic.jdbc.DataSource.gold=phoneBook # Or, to support transactions (JTS) weblogic.jdbc.TXDataSource.gold=phoneBook
javax.sql.DataSource and place it in Weblogic's JNDI under the name "gold".
javax.sql.DataSource:
javax.sql.DataSource ds = (javax.sql.DataSource) ic.lookup("gold");
Connection connection = ds.getConnection();
import java.sql.*;
public class PrintDB {
static String last;
static String first;
static String phone;
public static void main(String args[]) {
Properties dbprops = new Properties();
dbprops.put("user", "sa");
dbprops.put("password", "");
dbprops.put("server", "DEMO");
dbprops.put("database", "mydb");
try {
Class.forName("COM.cloudscape.core.JDBCDriver");
Connection connection =
DriverManager.getConnection("jdbc:cloudscape:E:\\student\\SimpleDB",
dbprops);
Statement statement = connection.createStatement();
ResultSet resultSet;
String sql;
statement = connection.createStatement();
// Insert or update a database
// sql =
// "INSERT INTO CONTACT_TABLE (\"LAST\",\"FIRST\",\"PHONE\") VALUES ('"
// + last + "','" + first + "','" + phone + "')";
// statement.executeUpdate(sql);
// printout entire database
sql = "SELECT * FROM CONTACT_TABLE";
resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
last = resultSet.getString(1);
first = resultSet.getString(2);
phone = resultSet.getString(3);
System.out.println("\t" + last + ", " + first + ", " + phone);
}
statement.close();
resultSet.close();
connection.close();
} catch (Exception e) {
System.out.println("Error:" + e);
}
}
}
// This will be passed by Weblogic's t3 (Type 3) database driver
// to the underlying database connection object
// Properties dbprops = new Properties();
// dbprops.put("user", "jose");
// dbprops.put("password", "canaima");
// dbprops.put("server", "theServer");
// dbprops.put("database", "E:\\student\\SimpleDB");
// This is for the Weblogic's t3 driver itself
Properties t3props = new Properties();
t3props.put("weblogic.t3.name", "SimpleDB");
t3props.put("weblogic.t3.description", "Phone Book Connection");
// Pass "dbprops" to the underlying database connection
// t3props.put("weblogic.t3.dbprops", dbprops);
t3props.put("weblogic.t3.driverClassName",
"COM.cloudscape.core.JDBCDriver");
t3props.put("weblogic.t3.driverURL", "jdbc:cloudscape");
t3props.put("weblogic.t3.serverURL", "t3://localhost:7001");
t3props.put("weblogic.t3.cacheRows", "100");
// Must create a "phoneBook" connection pool in weblogic.properties file.
// Append to "myserver\weblogic.properties" file:
// weblogic.jdbc.connectionPool.phoneBook=\
// url=jdbc:cloudscape:e:\\student\\SimpleDB,\
// driver=COM.cloudscape.core.JDBCDriver,\
// initialCapacity=4,\
// maxCapacity=10,\
// capacityIncrement=2,\
// props=user=none;password=none;server=none
// Must also add an ACL for the connection pool
// weblogic.allow.reserve.weblogic.jdbc.connectionPool.phoneBook=everyone
t3props.put("weblogic.t3.connectionPoolID", "phoneBook");
try {
// Instantiate a weblogic t3 driver object from known class name
Class.forName("weblogic.jdbc.t3.Driver");
// Get a connection object using a Type 3 database
// (which is really just a connection pool)
Connection connection =
DriverManager.getConnection("jdbc:weblogic:t3", t3props);
Statement statement = connection.createStatement();
} catch(Exception e) {}
|
com.bea.someContext)
java.naming.factory.initial (same as the Context.INTIAL_CONTEXT_FACTORY constant): Vendor-specific class file name to load to be able to read the vendor's JNDI tree.
java.naming.provider.url (same as the Context.PROVIDER_URL constant): This will be, for example, the URL to access the Weblogic server such as http://localhost:7001. Also, you can specify initial context here which can be any subcontext under the root context.
java.naming.factory.object (same as the Context.OBJECT_FACTORIES constant): This specifies a colon-separated list of class names for objects bound in the JNDI. When a "lookup()" method is called, JNDI finds the class name of the object, loads that class, instantiates the object (may be by deserializing its attributes) and returns the object to the calling method.
java.naming.security.principal (same as the Context.SECURITY_PRINCIPAL constant): Username to connect to JNDI (e.g. "system"). Weblogic default is "guest".
java.naming.security.credentials (same as the Context.SECURITY_CREDENTIALS constant): Password to authenticate the username (e.g. "systemPWD")
import javax.naming.*;
import java.util.*;
Properties env = new Properties();
env.setProperty("Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
env.setProperty(Context.PROVIDER_URL, "http://localhost:7001");
/*
// Alternative property name usage
env.setProperty("java.naming.factory.initial",
"weblogic.jndi.WLInitialContextFactory");
env.setProperty("java.naming.provider.url", "http://localhost:7001");
*/
try {
Context ic = new InitialContext(env);
AddressBook ab = new AddressBook("Tom", "35 Vernon Terrace",
"485-7613", 23);
// (Re)Bind an instantiated Java object to a name in JNDI
ic.rebind("Tom H", ab);
// Usually, in a separate client code
// AddressBook ab = (AddressBook) ic.lookup("Nerney");
// System.out.println("Name: " + ab.getName());
} catch (NamingException e) {
e.printStackTrace();
}
NameClassPair item = null;
NamingEnumeration enum = null;
// Instantiate "ic" with getInitialContext.
// Then, specify context name to look into, empty string for ROOT context
enum = ic.list("");
while (enum.hasMore()) {
// Each item on the list is an instance of NameClassPair.
item = (NameClassPair) enum.next();
// Get name of the object as known to JNDI
System.out.println("Object Bound As: " + item.getName());
// Get the actual class name to which the bound object belongs
System.out.println("Class Type of Bound Object: " + item.getClassName() );
}
try {
Context initialContext = new InitialContext(env);
printContext(initialContext, 0);
} catch (NamingException e) {
System.out.println(e);
}
public static void printContext(Context dir, int numLevelsDeep)
{
// The listBindings method returns a NamingEnumeration
Binding item = null;
NamingEnumeration enum = null;
try {
enum = dir.listBindings("");
while (enum.hasMore())
{
try {
// Each item on the list is an instance of NameClassPair.
item = (Binding) enum.next();
// Print out some leading spaces.
for (int i = 0; i < numLevelsDeep; i++)
{
System.out.print(" ");
}
// Check if enum.next() returned a subcontext or a bound object
if (item.getObject() instanceof Context)
{
// If a Context, recursively call printContext() to print
// content tree
// How to bind a superclass to a subclass!
Context subContext = (Context) item.getObject();
System.out.println("DIR => " + item.getName());
printContext(subContext, numLevelsDeep + 1);
} else
{
Object ab = (Object) item.getObject();
System.out.println("Object => " + item.getName());
}
} catch (NamingException e) {
System.out.println("Inner Exception");
System.out.println(e);
}
}
} catch (NamingException e) {
System.out.println("Outer Exception");
System.out.println(e);
}
}
env.put(Context.SECURITY_PRINCIPAL, "system"); env.put(Context.SECURITY_CREDENTIALS, "weblogic");
Context subCtx = createSubcontext("some-name");
destroySubcontext("some-name");
String pwd = getNameInNameSpace(); //JNDI 1.2
#"com" is context under the root context weblogic.allow.list.com=everyone #Subcontexts are "dot"-delimited, groups are ","-delimited weblogic.allow.lookup.com.abcdef=friends,family #Or, Specify ","-delimited users weblogic.allow.lookup.com.abcdef.xyzpqr=bob,jane
env.setProperty("java.naming.factory.initial",
"com.sun.jndi.fscontext.RefFSContextFactory");
env.setProperty("java.naming.provider.url", "file:///");
com.sun.jndi.rmi.registry.RegistryContextFactory
Context is to cast "naming" only, DirContext is to cast "directory" services.
Attributes attrs = ( (DirContext)ctx).getAttributes("object's jndi name");
NamingEnumeration allAttrs = attrs.getAll();
While (allAttrs.hasMore() )
{
Attribute attr = (Attribute)allAttrs.next();
String id = attr.getID().toString();
Attribute val = attr.get(); //Only one value returned (vendor decides)
NamingEnumeration values = attr.getAll();
while (values.hasMore() )
{
System.out.println(values.next() );
}
// If a value cannot be added, nothing happens, otherwise it is added
// to the "attr" object copy. Underlying dir. is not modified
attr.add("blankety blank"); //attr knows it is an id or a name etc.
attr.remove("somevalue");
attr.clear(); //clear all values of this attribute
boolean isItThere = attr.contains("taco");
int howManyValues = attr.size();
}
modifyAttributes().
Obviously, this model is not very scalable. You are essentially loading up the whole database in a computer's memory and never letting go.
So, the "factory design pattern" was invented. You write an additional class whose sole job is to create instances of your main remote class on demand. You unregister your main object(s) from the server and, instead, register one instance of the factory class with the server. Now the clients know to first look up this factory object and call a pre-established method on it, passing their user id, to create an instance of the real object which they want to use. The factory class calls the real class's constructor, passing the user id to it. The real class's constructor looks up that user id's data in the database and populates the new object's data attributes with it. After the real object's constructor returns, the factory class passes a stub to the newly created object to the calling user. The user can now call the stub's methods to update his information (the business he or she wanted to conduct in the first place). If a user has not called any method on an instantiated object for some time, the factory object simply destroys it, thus conserving resources.
public HomeHandle getHomeHandle() method. You can serialize the returned value of the "HomeHandle" type to disk just like a regular Java object.
public EJBHome getEJBHome() method on it to reestablish connection to the server-side "home" object. If that "home" object dies in the mean time (server crashed, EJB undeployed etc.), you will get a RemoteException.
public Handle getHandle() method. You can serialize the returned value of the "Handle" type to disk just like a regular Java object.
public EJBObject getEJBObject() method on it to reestablish connection to the server-side "remote" object. If that "remote" object dies in the mean time (remove() called, server crashed, EJB undeployed etc.), you will get a RemoteException.