25
1 Copyright 2000 SyncTank Solutions, Inc. JNDI, It’s All in the Context Russell Castagnaro Chief Mentor 4Charity.com [email protected] Copyright 2000 SyncTank Solutions, Inc. Introduction • Presenter – Russell Castagnaro – Chief Mentor • 4Charity.com SyncTank Solutions, Inc [email protected] – Experience

2001: JNDI Its all in the Context

Embed Size (px)

DESCRIPTION

Back in 2001 I was giving talks on how to use Java Naming and Directory Interface effectively.

Citation preview

Page 1: 2001:  JNDI Its all in the Context

1

Copyright 2000 SyncTank Solutions, Inc.

JNDI, It’s All in the Context

Russell CastagnaroChief Mentor [email protected]

Copyright 2000 SyncTank Solutions, Inc.

Introduction• Presenter

– Russell Castagnaro

– Chief Mentor • 4Charity.com • SyncTank Solutions, Inc

[email protected]

– Experience

Page 2: 2001:  JNDI Its all in the Context

2

Copyright 2000 SyncTank Solutions, Inc.

Introduction• 4Charity.com

– Application Service Provider for the Non-Profit industry

– Pure Java development– Http://www.4charity.com– Locations:

• San Francisco,CA • Honolulu, HI

– We’re Hiring…

Copyright 2000 SyncTank Solutions, Inc.

Why JNDI?You can:• Develop networked application.• Find remote objects.• Interface with distributed systems.• Interact with non-Java, networked

systems

Page 3: 2001:  JNDI Its all in the Context

3

Copyright 2000 SyncTank Solutions, Inc.

Presentation Goals• Review of basic JNDI.• Using JNDI for local service resolution.• JNDI as an alternative to static

constants.• Using Custom Contexts with JNDI.• Implementing Singletons.• Using RMI and IIOP.• Using Events in JNDI.

Copyright 2000 SyncTank Solutions, Inc.

Who needs JNDI?• If you want to use J2EE, you need

JNDI.• JNDI is the standard way to access

distributed and local resources for enterprise applications.

Page 4: 2001:  JNDI Its all in the Context

4

Copyright 2000 SyncTank Solutions, Inc.

What is JNDI?• JNDI is a set of interfaces.• Provides a programming interface,

allowing for Discovery and Registration.• Standards-based approach, providing

common API to a searchable structure of objects.

• Naming Services• Directory Services

Copyright 2000 SyncTank Solutions, Inc.

What is a Naming Service?• Provides the ability to map a name or

identifier to objects or services.• A tree-like structure, nodes can be

associated with other nodes or objects.• Objects are bound into the JNDI tree.• Objects can be resolved by performing

a lookup using the composite name.

Page 5: 2001:  JNDI Its all in the Context

5

Copyright 2000 SyncTank Solutions, Inc.

Naming

JNDI Tree lives in the Server as a collection of

Named Object References

Object/ Service

Reference

Copyright 2000 SyncTank Solutions, Inc.

What is a Directory Service?• Provides a structure containing objects.• Allows access to object attributes.• Enables searching the structure using

these attributes.• Think of a computer’s file system or an

SQL database.• Simple JNDI has one attribute, the

object’s name.

Page 6: 2001:  JNDI Its all in the Context

6

Copyright 2000 SyncTank Solutions, Inc.

JNDI is Like a Database• Start with a database instance.• Use a tablespace or ownership area.• Access a table in the tablespace.• Access a row in the table.• Access a column in the row.

sqlplus scott@beq-local

“SELECT name FROM scott.emp;”

Copyright 2000 SyncTank Solutions, Inc.

JNDI is Like a File System

• Start with a mounted drive.• Use a subdirectory.• Access a subdirectory.• Access a file.

“C:/data/your_client/financials.xls”

Page 7: 2001:  JNDI Its all in the Context

7

Copyright 2000 SyncTank Solutions, Inc.

Using JNDI• Start with an Initial Context.• Navigate to a Sub-Context.• Drill-down through other sub-contexts.• Access the object or service.

new InitialContext().lookup(“name”);

Copyright 2000 SyncTank Solutions, Inc.

Comparisons

JNDI File System RDBMS

Initial Context Mount Point (c:\)Database instance

SubContext Subdirectory TablespaceSubContext Subdirectory TableObject File Data (row)rmi://myserver:8080/myobjects.example.object

c:\data\your_client\financials.xls

SELECT * FROM Demo.Employee

Page 8: 2001:  JNDI Its all in the Context

8

Copyright 2000 SyncTank Solutions, Inc.

JNDI Examplepackage com.synctank.labs.jndi;import javax.naming.*;public class TestJNDI {

public static void main(String _arg[]){Object o = null; InitialContext ctx= null;try{

ctx = new InitialContext(System.getProperties());o = ctx.lookup("myobjects.example.object");String s = (String)o; System.out.println("Found a string: "+s);

} catch (ClassCastException e) {System.out.println("Found a "+o.getClass().getName() +": "+o.toString() );

} catch (NamingException ne) {System.out.println("We have a problem!"); ne.printStackTrace();

} finally {try { ctx.close(); }catch (Exception e ) {}

}} }

Copyright 2000 SyncTank Solutions, Inc.

JNDI Example• Primary classes are located in the

javax.naming package.• Primarily use Context objects:

– javax.naming.Context

– javax.naming.InitialContext

– javax.naming.directory.InitialDirContext

– javax.naming.ldap.InitialLdapContext

• Use a context that matches your needs.

Page 9: 2001:  JNDI Its all in the Context

9

Copyright 2000 SyncTank Solutions, Inc.

JNDI Providers• JNDI Providers are the services that will be

accessed.

• More on the Service Provider Interface Later.

• Most application servers come with some Naming service.

• J2SDK v. 1.3 includes code for many interfaces.

• Many are downloadable, for free, at http://java.sun.com/products/jndi/serviceproviders.html#12

Copyright 2000 SyncTank Solutions, Inc.

Starting the Service• FS service doesn’t need to be started!• RMI Registry (JNDI Service)

– start rmiregistry.exe OR– java.rmi.registry.LocateRegistry.createRegistry(port);

• Weblogic JNDI service– start startWebLogic.cmd OR – ./startWebLogic.sh &

Page 10: 2001:  JNDI Its all in the Context

10

Copyright 2000 SyncTank Solutions, Inc.

Getting the Initial Context

• Similar to JDBC. Use a Hashtable object.• Two required properties:

– Context.INITIAL_CONTEXT_FACTORY– Context.PROVIDER_URL

• Other optional properties:– Context.SECURITY_PRINCIPAL

– Context.SECURITY_CREDENTIALS

– And many, many more..

Copyright 2000 SyncTank Solutions, Inc.

Getting the Initial Context• Context.INITIAL_CONTEXT_FACTORY

– Actually “java.naming.factory.initial”– Name of the Factory that creates Initial Contexts.

• Context.PROVIDER_URL

– Actually “java.naming.provider.url”– Tells JNDI where to find the service.

• Context.SECURITY_PRINCIPAL

– Who is the connecting?

• Context.SECURITY_CREDENTIALS

– What is authentication object (password, certificate,..)

Page 11: 2001:  JNDI Its all in the Context

11

Copyright 2000 SyncTank Solutions, Inc.

Getting the Initial Context• Place the correct properties in a

Hashtable or Properties object.• Call the constructor for the InitialContext

class, pass the Hashtable as a parameter.

• Catch (throw) any Naming Exceptions!• Remember to close() the context when

done.

Copyright 2000 SyncTank Solutions, Inc.

Getting the Initial Context

public static InitialContext getInitialContext() throws NamingException {// use the factory and url supported by your providerString factory = "weblogic.jndi.WLInitialContextFactory";String url = "t3://localhost:7001"; // “http://localhost:7001”; String user = null; String password = null;java.util.Hashtable p = new java.util.Properties();p.put(Context.INITIAL_CONTEXT_FACTORY, factory);p.put(Context.PROVIDER_URL, url);if (user != null && password != null ) {

p.put(Context.SECURITY_PRINCIPAL, user);p.put(Context.SECURITY_CREDENTIALS, password);

}return new InitialContext(p);

}

Page 12: 2001:  JNDI Its all in the Context

12

Copyright 2000 SyncTank Solutions, Inc.

Getting the Initial Context (file system)

public static void main(String[] args) {Hashtable env = new Hashtable(11);env.put(Context.INITIAL_CONTEXT_FACTORY,

"com.sun.jndi.fscontext.RefFSContextFactory");String root = "file:/jdk1.3"; if (args != null && args.length > 0) root = args[0];

env.put(Context.PROVIDER_URL, "file:/jdk1.3");try {

Context ctx = new InitialContext(env); String start = ""; if (args != null && args.length > 0) start = args[0];

listBindings(ctx,start);ctx.close();

} catch (NamingException e) {System.out.println("List Bindings failed: " + e);

}}

Copyright 2000 SyncTank Solutions, Inc.

EJSkin LookupProperties p = new Properties();p.put(Context.INITIAL_CONTEXT_FACTORY,

“com.ejskin.context.SkinnyInitialContextFactory");p.put(Context.PROVIDER_URL,

“ejs://ejs.ejs.com:666");Context ctx = new InitialContext(p);SkinnyAppp app = (SkinnyApp)ctx.lookup(“SkinyApp.fore”);

Page 13: 2001:  JNDI Its all in the Context

13

Copyright 2000 SyncTank Solutions, Inc.

Resolving Objects• Once you have a context any lookup is a relative search.• user.russell.castagnaro.wallet can be resolved from:

– The initial context as ctx.lookup(“user.russell.castagnaro.wallet”);

– A subcontext “user.russell” as ctx.lookup(“castagnaro.wallet”);

• Access a sub-context using the lookup method from any context.Context ctx = new InitialContext(p); Context sub = ctx.lookup("user");sub = sub.lookup("russell"); sub = sub.lookup(”castagnaro");Object o = sub.lookup("wallet");

Copyright 2000 SyncTank Solutions, Inc.

JNDI Perusal• It is possible to dynamically access all of

the objects bound into the JNDI tree with two overloaded methods:– public abstract NamingEnumeration list(java.lang.String) throws

NamingException;– public abstract NamingEnumeration list(javax.naming.Name) throws

NamingException;– public abstract NamingEnumeration listBindings(java.lang.String) throws

NamingException;– public abstract NamingEnumeration listBindings(javax.naming.Name)

throws NamingException;

• There is a very large difference between the two methods!

Page 14: 2001:  JNDI Its all in the Context

14

Copyright 2000 SyncTank Solutions, Inc.

JNDI Perusal

• listBindings()– Returns an enumeration of Binding objects.– Bindings contain the actual object* from the tree!– May take a long time!

• list()– Returns an Enumeration of NameClassPair objects.– Access to the Name and class, but not the object.– Faster than the alternative, like a ‘shallow get.’

* Remote objects are an exception.

Copyright 2000 SyncTank Solutions, Inc.

JNDI Perusal Example Codepublic static void list(Context ctx,StringBuffer sb) {

try {NamingEnumeration enum = ctx.listBindings("");while (enum.hasMore()) {

Binding binding = (Binding)enum.next();Object obj = (Object)binding.getObject();if (obj instanceof Context) {

sb.append("---> "); sb.append(binding.getName());sb.append("."); list((Context)obj,_sb);

} else {sb.append(binding.getName()); sb.append("\n"); }

}} catch (NamingException e) {

System.out.println(e);}

}

Page 15: 2001:  JNDI Its all in the Context

15

Copyright 2000 SyncTank Solutions, Inc.

JNDI Perusal Output---> javax.--->

jts.UserTransaction

---> transaction.UserTransaction

--->jms.QueueConnectionFactory

TopicConnectionFactory

PrePackagedSessionEJB_EO

---> weblogic.

---> fileSystem.

---> ejb.EJBManager---> common.T3Services---> jdbc.JdbcServices

---> connectionPool.ejbpoolcs1demoPoolcs--->jts.CoordinatorFactory[]CoordinatorFactory---> server.myserverWebLogic---> rmi.--->jms.ServerSessionPoolFactory---> jndi.---> internal.RemoteContextFactoryRemoteContextFactory

Copyright 2000 SyncTank Solutions, Inc.

Adding Objects• You can use the bind() or rebind() methods to

add objects to the tree. • If an object extends java.io.Serializable, it is

copied and placed into the tree.• If an object extends java.rmi.Remote, a copy of

the stub is placed into the tree.• rebind() will automatically overwrite an existing

object.• bind() throws a javax.naming.NamingException

Page 16: 2001:  JNDI Its all in the Context

16

Copyright 2000 SyncTank Solutions, Inc.

Adding Objectspublic static void main(String args[]) throws java.rmi.RemoteException{

Hashtable ht = new Hashtable();ht.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");ht.put(Context.PROVIDER_URL, "t3://localhost:7001");try {

Context ic = new InitialContext(ht);//serializable, an actual copy put into the treeic.bind("Object1",new String("Object1"));ic = ic.createSubContext(“foo”);//remote, a copy of the stub placed in the treeic.bind("Trivial",new TrivialImpl("Trivial!"));

} catch (NamingException e){System.out.println(e.getMessage());

}}

Copyright 2000 SyncTank Solutions, Inc.

Other Features• Use unbind() to remove an object from the

tree.• Use rename() to change its registered

name.• Use custom startup classes to bind

objects into the tree upon start up.• Use custom properties to automatically

bind objects into the tree.

Page 17: 2001:  JNDI Its all in the Context

17

Copyright 2000 SyncTank Solutions, Inc.

Other Features• Removing Items from the JNDI Tree

try {

Context ic = new InitialContext(ht);

ic.unbind(data);System.out.println(data+ " successfully unbound.");

} catch (NamingException e) ..

• Renamingtry {

Context ic = new InitialContext(ht);

ic.rename(oldName, newName);} catch (NamingException e) ..

Copyright 2000 SyncTank Solutions, Inc.

Local Data Access• Accessing local data using constants

requires recompilation to change those values

public static String SOME_VALUE=“foo”;

• Using JNDI gives you the freedom to pin values that need to be shared, without access to:– System properties– File Systems– Custom Classes

Page 18: 2001:  JNDI Its all in the Context

18

Copyright 2000 SyncTank Solutions, Inc.

Local Data Access• Enterprise Java Beans require the use of

this JNDI for deployment values.• Allows deployment specialists to change

values without recompilation.• EJB deployment descriptor snippet:

<env-entry>

<env-entry-name>foo</env-entry-name>

<env-entry-type>String</env-entry-type>

<env-entry-value>bar</env-entry-value>

</env-entry>

Copyright 2000 SyncTank Solutions, Inc.

Local Data Access• Use a local context and lookup the object

by prepending “java:comp/env”ctx = new InitialContext();String foo = (String)ctx.lookup(“java:comp/env.foo”);

Page 19: 2001:  JNDI Its all in the Context

19

Copyright 2000 SyncTank Solutions, Inc.

Using Custom Startup Classes

• Using a custom WebLogic startup Classpublic String startup(String _name, java.util.Hashtable

_args) throws Exception {TrivialImpl o = new TrivialImpl(); System.out.println("TrivialImpl instanciated..");Context context = getInitialContext(); context.rebind(_name, o);System.out.println("Bound..");

return ("TrivialImpl bound to the name "+_name);}public void setServices(weblogic.common.T3ServicesDef

services){}

Copyright 2000 SyncTank Solutions, Inc.

Using a Startup Servlet

public void init(ServletConfig config) throws ServletException {super.init(config);String className = config.getInitParameter("CLASS_NAME");String jndiName = config.getInitParameter("JNDI_NAME");if (className != null && jndiName != null) {try{

Object o = Class.forName(className).newInstance();Context ctx = new InitialContext();ctx.rebind(jndiName,o);log("StartupServlet has bound "+ className +" into”+ the JNDI tree as "+ jndiName);

} catch (Exception ne) {throw new ServletException(ne);

}}

Page 20: 2001:  JNDI Its all in the Context

20

Copyright 2000 SyncTank Solutions, Inc.

Singletons• You need one and only one instance of

a particular class.• You want to provide access to

distributed applications/ services.• Don’t make static methods! Make the

class an RMI object.• Bind the object’s implementation into

the JNDI tree.• Essentially what happens for EJBHome

interfaces.

Copyright 2000 SyncTank Solutions, Inc.

CORBA Objects• When accessing CORBA objects, things

used to be more complicated.• RMI over IIOP, included in Java 2,

solves this problem.• Narrowing the object maps it from a

CORBA object to a Java object auto-magically.

Page 21: 2001:  JNDI Its all in the Context

21

Copyright 2000 SyncTank Solutions, Inc.

Narrowing• If you access services using RMI over

IIOP (WebSphere, Iona, etc.).• If you use HomeHandle or Handle

objects (EJB 1.1). • Use PortableObject.narrow()• Pass an Object and the class you

expect from the remote method call.

Copyright 2000 SyncTank Solutions, Inc.

Class NarrowingObjectOutputStream stream = ...;Account account = ...;Handle handle = account.getHandle();stream.writeObject(handle);// A client can read the handle from stable storage, and use the

// handle to resurrect an object reference to the

// account entity object.

//

ObjectInputStream stream = ...;Handle handle = (Handle) stream.readObject(handle);Account account = (Account)javax.rmi.PortableRemoteObject.narrow(handle.getEJBObject(), Account.class);account.debit(100.00);

Page 22: 2001:  JNDI Its all in the Context

22

Copyright 2000 SyncTank Solutions, Inc.

JDBC and JNDI• It is possible to use JNDI to store JDBC

connection objects:SampleDataSource sds = new SampleDataSource();

sds.setServerName(“BEQ-LOCAL”);

sds.setDatabaseName(“demo”);

Context ctx = new InitialContext();

ctx.bind(“EmployeeDB”, sds);

• Application servers typically feature datasource publishing:weblogic.jdbc.TXDataSource.ejbDataSource=ejbPool

weblogic.jdbc.DataSource.ejbPool=ejbPool

Copyright 2000 SyncTank Solutions, Inc.

JDBC and JNDI• Use them later to avoid prior knowledge of

driver information:Context ctx = new InitialContext();

DataSource ds = (DataSource)ctx.lookup(“ejbDataSource”);

Connection con = ds.getConnection();

Page 23: 2001:  JNDI Its all in the Context

23

Copyright 2000 SyncTank Solutions, Inc.

Events• JNDI Events provide local or remote

callback functionality.• Similar to the event model used in Swing.• Uses subclasses of the

javax.naming.NamingListener interface.• NamingListeners:

– NamespaceChangeListener– ObjectChangeListener– UnsolicitedNotificationListener

Copyright 2000 SyncTank Solutions, Inc.

Events• JNDI Events require the use of a different

type of context.• New Context interfaces:

– EventContext for standard naming services

– EventDirContext for LDAP service

• Access Contexts in a familiar way:EventDirContext edc = (EventDirContext)

(new InitialDirContext(env).lookup("ou=People"));

Page 24: 2001:  JNDI Its all in the Context

24

Copyright 2000 SyncTank Solutions, Inc.

JNDI Gotchas• Use rebind() wisely.

• Know the URL and InitialContextFactory class name.

• When using advanced features (LDAP, etc.) place the correct resources in your classpath..\lib\rmiregistry.jar;.\lib\providerutil.jar;

.\lib\jndi.jar;.\lib\jaas.jar;.\lib\ldap.jar;

.\lib\ldapbp.jar;.\lib\fscontext.jar

• J2EE has made deploying JNDI services much easier, look for vendors to support advanced features 2Q 2000.

Copyright 2000 SyncTank Solutions, Inc.

Review• JNDI is used for all advanced J2EE

features.• JNDI provides an easy method of accessing

remote or local resources.• Use bind() or rebind() to register objects.• Use lookup() to resolve objects.• Use your server vendors startup facilities for

initial JNDI registration.

Page 25: 2001:  JNDI Its all in the Context

25

Copyright 2000 SyncTank Solutions, Inc.

Finally• Thanks for attending.• Live in Hawaii or Bay Area? Do you like

this stuff? Email your resume to us!• Source Code Available:

– http://www.synctank.com/softwaresummit

[email protected]

• Aloha!