package ejbexample.client;
import java.util.*;
import java.math.*;
import javax.naming.*; // pakotne, kas satur vārdu servisa klases
import javax.rmi.PortableRemoteObject;
import ejbexample.ejb.BankSessionEJB; // komponenta saskarne
import ejbexample.ejb.BankSessionEJBHome; // home saskarne
import ejbexample.valueobjects.*; // vērtības objektu pakotne
public class BankSessionEJBClient
{
public static void main(String [] args)
{
try
{
Context context = new InitialContext();
Object obj = context.lookup("BankSessionBean"); // meklē home saskarni
BankSessionEJBHome bankSessionEJBHome = (BankSessionEJBHome)
PortableRemoteObject.narrow(obj, BankSessionEJBHome.class);
BankSessionEJB bankSessionEJB; // komponenta saskarne
bankSessionEJB = bankSessionEJBHome.create(); // izveido komponenta instanci
CustomerVO cust = new CustomerVO(); // izviedo klienta aprakstu (value object)
cust.setPersonasKods("101078-12334");
cust.setAdrese("Ikskile, Lapu iela - 15");
cust.setVards("Janis");
cust.setUzvards("Berzs");
cust.setDzimsanasDatums( (new GregorianCalendar(1978, 9, 10)).getTime());
bankSessionEJB.addCustomer( cust); // pievieno klienta datus datubāzei
bankSessionEJB.openNewAccount("101078-12334","8875264445849"); // pievieno konta datus
bankSessionEJB.deposit("8875264445849",new BigDecimal("124.00"));
System.out.println("acounts...");
AccountVO[] konti = bankSessionEJB.readCustomersAccounts("101078-12334");
for (int i =0; i<konti.length; i++) // izdrukā kontu sarakstu
{
System.out.println(konti[i].getKontaNumurs());
System.out.println(konti[i].getSumma());
}
}
catch(Throwable ex)
{
System.out.println("Error: "+ex.getMessage());
}
}
}
Klase InitialConext veic sākotnējo savienojumu ar OC4J. Savienojuma parametrus var nodod šādos veidos:
java.naming.factory.initial=com.evermind.server.rmi.RMIInitialContextFactory java.naming.provider.url=ormi://localhost/ExampleBankApp java.naming.security.principal=admin java.naming.security.credentials=admin
Mērķis ir izveidot vienkāršu sesijas komponentu, kurš satur vienu metodi, kas atgriež "Hello World !" rindiņu. Šis komponents izmantos attālinātās saskarnes, lai to varētu izsaukt pa tīklu.
Komponenta saskarnē norāda komponenta biznesa loģikas metodes. Tā ir attālināta saskarne, tās metodes izsauc pa tīklu. Saskarnei ir šādas īpašības.
Mūsu piemērā nepieciešama tikai viena metode.
package helloworldejb;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
public interface HelloWorldSessionEJB extends EJBObject {
String hello() throws RemoteException;
}
Šī saskarne satur ar komponenta dzīves ciklu saistītas metodes. Piemērā ir nepieciešama tikai viena metode, kas izveido sesijas komponenta instanci. Šī metode atgriež izveidotā komponenta saskarni.
package helloworldejb;
import javax.ejb.EJBHome;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import helloworldejb.HelloWorldSessionEJB;
public interface HelloWorldSessionEJBHome extends EJBHome {
HelloWorldSessionEJB create() throws RemoteException, CreateException;
}
Izvietošanas deskriptors ejb-jar.xml apraksta komponenta tipu un tā sastāvdaļas.
<?xml version = '1.0' encoding = 'windows-1257'?>
<!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>
<description>Session Bean ( Stateless )</description>
<display-name>HelloWorldSessionEJB</display-name>
<ejb-name>HelloWorldSessionEJB</ejb-name>
<home>helloworldejb.HelloWorldSessionEJBHome</home>
<remote>helloworldejb.HelloWorldSessionEJB</remote>
<ejb-class>helloworldejb.HelloWorldSessionEJBBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>
<?xml version = '1.0' encoding = 'windows-1257'?>
<!DOCTYPE orion-ejb-jar PUBLIC "-//Evermind//DTD Enterprise JavaBeans 1.1 runtime//EN" "http://xmlns.oracle.com/ias/dtds/orion-ejb-jar.dtd">
<orion-ejb-jar>
<enterprise-beans>
<session-deployment name="HelloWorldSessionEJB" location="HelloWorldBean"/>
</enterprise-beans>
<assembly-descriptor>
<default-method-access>
<security-role-mapping impliesAll="true" name="<default-ejb-caller-role>"/>
</default-method-access>
</assembly-descriptor>
</orion-ejb-jar>
package helloworldejb;
import javax.naming.*;
import javax.rmi.PortableRemoteObject;
import helloworldejb.HelloWorldSessionEJB;
import helloworldejb.HelloWorldSessionEJBHome;
import javax.naming.NamingException;
public class HelloWorldSessionEJBClient {
public static void main(String [] args) {
try {
Context context = new InitialContext();
// atrod home saskarni
Object obj = context.lookup("HelloWorldBean");
// atrasto objektu pârveido par home saskarni
HelloWorldSessionEJBHome helloWorldSessionEJBHome =
(HelloWorldSessionEJBHome)PortableRemoteObject.narrow(obj, HelloWorldSessionEJBHome.class);
// izveido sesijas komponenta instanci
HelloWorldSessionEJB helloWorldSessionEJB = helloWorldSessionEJBHome.create();
// izsauc vienu no komponenta metodēm
String greeting = helloWorldSessionEJB.hello();
System.out.println(greeting);
helloWorldSessionEJB.remove(); // izdzēš komponenta instanci
}
catch(Throwable ex) {
System.out.println("Error: "+ex.getMessage());
}
}
}
Fiziskais resursu izvietojums klientam EJB vidē ir noslēpts. Sekojošas priekšrocības:
EJB aplikācijas klients, gribot atrast EJB komponentu raksta sekojoši:
// savāc objektu pēc vārdu servisa nosaukuma
Object obj = initialContext.lookup("BankSessionBean");
// pārveido par "Home" interfeisu
BankSessionEJBHome home = (BankSessionEJBHome)
PortableRemoteObject.narrow(obj,
BankSessionEJBHome.class);
Plakana (nehierarhiska) vārdapgabala trūkumi ir acīmredzami. Piemēram, A.Čehova stāstā "Vaņka Žukovs" galvenais varonis raksta garu vēstuli, kurai pievieno adresi "На деревню дедушке".
Tāpat kā JDBC, arī JNDI piedāvā Javas klientiem unificētu interfeisu, bet JNDI funkcionalitāti priekš dažādiem serveriem nodrošina dažādi "servisa piegādātāji", kuri darbojas līdzīgi datubāžu draiveriem.
Sākotnējā konteksta inicializācija:
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.evermind.server.rmi.RMIInitialContextFactory");
env.put(Context.SECURITY_PRINCIPAL, "admin");
env.put(Context.SECURITY_CREDENTIALS, "base");
env.put(Context.PROVIDER_URL, "ormi://localhost/ExampleBankApp");
InitialContext ic = new InitialContext(env);

Šādi izskatās "JNDI pārlūka" spraudnis priekš Eclipse. Tas attēlo JNDI koka struktūru dotajiem JNDI servisa parametriem.
Konteksts tomēr uzvedas savādāk, nekā, piemēram failu sistēmas direktorija java.io.File. Konteksts var darboties tikai ar saviem saistījumiem, bet tas nevar pateikt savu absolūto taciņu (salikto vārdu), vai pāriet direktoriju kokā uz augšu. JNDI kontekstiem bieži nevar arī viennozīmīgi pateikt, kura ir saknes direktorija, jo InitialContext var uzstādīt dažādās vietās - to apakškonteksti pēc tam var daļēji pārklāties.
