Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Writing standalone Java code that connects to IBM Lotus Domino Chhatrapal Dhapekar Project Manager, Notes Client & App. Dev Team IBM Software Group Pune, India Ranjit Rai Staff Software Engineer IBM Software Group Pune, India June 2009 Abstract: The objective of the article is to provide guidance to Java™ developers on how to write standalone Java code that can seamlessly connect to IBM® Lotus® Domino®. This guide to the Java objects and APIs can be used to build Domino applications, providing a bridge for traditional Domino developers. Table of Contents Overview and prerequisites................................................................................................. 1 Setting up CLASSPATH, PATH, or ENVIRONMENT variables ................................. 2 Run-time requirements.................................................................................................... 2 Application security ........................................................................................................ 3 Compiling Java Programs with sample output ................................................................... 3 Troubleshooting .................................................................................................................. 7 Conclusion ........................................................................................................................ 12 Resources .......................................................................................................................... 12 About the authors .............................................................................................................. 12 Overview and prerequisites Java standalone applications can be written in Java that accesses the Domino objects. We cover the steps necessary to integrate Domino objects into a Java application, including local and remote calls to Domino objects. Before writing Java applications we must set up a few variables. First, it’s important to have the Java Development Kit (JDK) to use when compiling the code. The JDK to be used depends on the Domino version you are running (Domino 8.5 uses JDK 1.5). Setting up CLASSPATH, PATH, or ENVIRONMENT variables For a Microsoft® Windows® environment, go to Environment Variables and add the variables below with the correct path. If the variables are not present, create new ones. To compile a Java program that uses the lotus.domino package, the classpath must include Notes.jar (local) or NCSO.jar (remote), for example: set CLASSPATH=.;c:\Program Files\IBM\Lotus\Notes\jvm\lib\ext\Notes.jar set CLASSPATH=.;C:\Program Files\IBM\Lotus\Notes\data\domino\java\NCSO.jar and set PATH C:\Program Files\Java\jdk1.5.0_18\bin Run-time requirements A computer that is running a: Java application that makes local Domino calls must contain Domino Server, Domino Designer, or Notes Client, and must include Notes.jar in the classpath. Java application that makes remote Domino calls need not contain Domino or Notes but must contain one of the NCSO archives and must include it in the classpath. Domino agent that makes Domino calls must include Notes.jar in the classpath. Domino agents as well as Java applications, whether at the client or the server, can be written in Java and use these Java Notes classes to access Domino information. These are the same backend objects accessible through LotusScript and OLE. In Java, the Session class is the root class of the Java package. The Domino object classes do not include the front-end classes rooted at NotesUIWorkstation. Remote Java programs can access the Domino object classes on the Domino server using CORBA/IIOP network communication mechanisms. NOTE: The lotus.domino package has the same content as the Release 4.6 lotus.notes package, plus new classes, methods, and other enhancements. The Release 4.6 lotus.notes package continues to be supported for backward compatibility only; it does not contain the new classes, methods, and other enhancements. The session class (lotus.notes.Session class) is the root of the Domino object hierarchy, providing access to the other Domino objects, and represents the Domino environment of your Java program. The lotus.domino classes allow you to access named databases (lotus.notes.Database class), views and folders (lotus.notes.View class), and documents (lotus.notes.Document class) within a database, along with items within a document (lotus.notes.Item and lotus.notes.RichTextItem classes). Application security Any Java standalone application runs with the permission of the current Notes ID. On a server the application will run with the server ID permission. A Notes password prompt will appear when the application requires authentication. Sometimes authentication may not be required because an application is only accessing databases locally on the machine, not connecting to any remote Domino server. Compiling Java Programs with sample output Listing 1 shows the code for an application that makes local calls and extends the NotesThread class. Listing 1. Code to make local calls and extend NotesThread class import lotus.domino.*; public class platform1 extends NotesThread { public static void main(String argv[]) { platform1 t = new platform1(); t.start(); } public void runNotes() { try { Session s = NotesFactory.createSession(); // To bypass Readers fields restrictions // Session s = NotesFactory.createSessionWithFullAccess(); String p = s.getPlatform(); System.out.println("Platform = " + p); } catch (Exception e) { e.printStackTrace(); } } } Let’s examine the first line of code from above: import lotus.domino.*; The lotus.domino classes are located in the Program directory on the file system of the Notes client and server in the Notes.jar file. A .jar file is like a .zip file that contains multiple compiled Java .class files that are compressed into a single file. You can use any .zip file tool to decompress and recompress .jar files. In the second line: public class platform1 extends NotesThread { NotesThread is a lotus.domino class that contains access to Domino session. Object.Domino session accesses Domino objects on the server or workstation on which the agent is running. The example in listing 1 above demonstrates the minimal amount of code needed for a Java program that uses the Domino classes. The examples instantiate a Session object and print the String output of its getPlatform method (Platform property). To compile code written using a text editor, in a Command Prompt, type the following: C:\>javac platform1.java C:\>java platform1 Platform = Windows/32 C:\> Listing 2 shows the code for an application that makes local calls and implements the Runnable interface. Listing 2. Code that makes local calls and implements a Runnable interface import lotus.domino.*; public class platform2 implements Runnable { public static void main(String argv[]) { platform2 t = new platform2(); NotesThread nt = new NotesThread((Runnable)t); nt.start(); } public void run() { try { Session s = NotesFactory.createSession(); String p = s.getPlatform(); System.out.println("Platform = " + p); } catch (Exception e) { e.printStackTrace(); } } } Listing 3 is an application that makes local calls and uses the static NotesThread methods. Listing 3. Code that makes local calls and uses static NotesThread methods import lotus.domino.*; public class platform3 { public static void main(String argv[]) { try { NotesThread.sinitThread(); Session s = NotesFactory.createSession(); String p = s.getPlatform(); System.out.println("Platform = " + p); } catch(Exception e) { e.printStackTrace(); } finally { NotesThread.stermThread(); } } } Listing 4 demonstrates an application that makes remote (IIOP) calls. The example requires the user to enter the name of the host Domino server and optionally a user name and password. If a user name and password are not supplied, the server must allow anonymous access. Listing 4. Code that makes remote IIOP calls import lotus.domino.*; public class platform4 implements Runnable { String host=null, user="", pwd=""; public static void main(String argv[]) { if(argv.length<1) { System.out.println( "Need to supply Domino server name"); return; } platform4 t = new platform4(argv); Thread nt = new Thread((Runnable)t); nt.start(); } public platform4(String argv[]) { host = argv[0]; if(argv.length >= 2) user = argv[1]; if(argv.length >= 3) pwd = argv[2]; } public void run() { try { Session s = NotesFactory.createSession( host, user, pwd); String p = s.getPlatform(); System.out.println("Platform = " + p); } catch (Exception e) { e.printStackTrace(); } } } To connect to a server remotely, you must specify the server name at run time, typing the following in a Command Prompt: C:\>javac platform4.java C:\>java platform4 test 85.ibm.com Platform = Windows/32 The remote server must be accessible over TCP/IP, and the server name should respond successfully to a ping command from the client machine on which the Java code is being compiled: C:\> ping test85.ibm.com If there are any problems, verify that the Fully qualified Internet host name in the Server Document’s Basics tab is correct (see figure 1), and that the entry is present in the host file. Figure 1. Fully qualified Internet host name field Also, to connect to the Domino server remotely, the DIIOP task must be running on the Domino server. To verify that DIIOP is running on your Domino Server and whether the Server is listening on port 63148; from the Domino Server Console, type > sh Task (see figure 2). Figure 2. Show Tasks ouput If the DIIOP task is not listed, use following command to load it: > load DIIOP Troubleshooting If you see the following error: C:\>java platform4 127.0.0.1 NotesException: Could not get IOR from Domino Server: http://127.0.0.1/diiop_ior .txt at lotus.domino.NotesFactory.requestIORPlain(Unknown Source) at lotus.domino.NotesFactory.requestIORUsingArgs(Unknown Source) at lotus.domino.NotesFactory.getIOR(Unknown Source) at lotus.domino.NotesFactory.createSessionUP(Unknown Source) at lotus.domino.NotesFactory.createSession(Unknown Source) at platform6.run(platform6.java:27) at java.lang.Thread.run(Unknown Source) Caused by: java.io.FileNotFoundException: http://127.0.0.1/diiop_ior.txt at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source) It occurs because the diiop_ior.txt file is created during the initial load of the DIIOP task in the HTML directory specified for the Web site. No sessions are created using IIOP when this file cannot be found. To check the configuration details, use the command Tell DIIOP show config (see figure 3). Figure 3. Tell DIIOP show config output The output shows the complete path for “IOR File” and the associated parameters to check, in the case of undesired results (see table 1). Table 1. DIIOP parameters and their definitions DIIOPConfigUpda teInterval This parameter specifies how often, in minutes, DIIOP should look to refresh its configuration data from the Domino directory. The default value is 3 minutes. DIIOPDNSLookup This parameter indicates that DIIOP should do a DNS name lookup for every client that connects and uses DIIOP services. This information is visible when using the server console command "show tasks". Set the value to 1 to enable DNS lookups for client. The default value is 0 (Off). DIIOPIORHost This parameter is used to specify an alternate hostname or IP address that what would be the default on the Domino server. The default on the server is based on the value the Server Document "Fully qualified Internet host name:" setting. To have DIIOP advertise its existence using an alternate hostname or IP address you can set DIIOPIORHost to the alternate host name or address. The preferred method of setting this value is through the Server Document -> Internet Tasks -> DIIOP tab. Note: This notes.ini parameter in R5 was known as DIIOP_IOR_HOST and it is still a valid alternate spelling for backwards compatibility. DIIOPI gnorePortLimits This parameter is only valid on a Linux platform. It indicates that DIIOP may use the default ports of 63148 and 63149. On some Linux installations the default ports are not available for use and DIIOP will automatically select the port 60148 and 60149. Set this value to 1 to use the higher valued defaults. Note: This notes.ini parameter in R5 was known as DIIOP_IGNORE_PORT_LIMITS and it is still a valid alternate spelling for backwards compatibility. DIIOPLogLevel This parameter increases the level of information that DIIOP reports to the server console and to the log. Valid settings are from 0 to 4. This value can be set manually by modifying the notes.ini directly or it can be set using the "tell diiop log=n" command. Possible values are: 0 1 2 3 4 DIIOPCookieChec kAddress Show Errors and Warnings only Also show informational messages Also show session init/term messages Also show session statistics Also show transaction messages This parameter modifies the behavior of the server based cookies used with applets which are downloaded by the Domino HTTP server. The default value is 0 (disabled) which means that DIIOP will not require the client's IP address using one of these cookies to match the IP address of the client that was issued the cookie. The client IP addresses will not match in most cases because the cookie is issued to the browser using the HTTP protocol which is typically routed through proxy servers and; therefore, the client appears to be the proxy server. While the user of the cookie is the applet running in the browser it's network traffic does not go through a proxy server. Set the value to 1 to enable the checking of client IP addresses for these cookies. DIIOPCookieTime out This parameter modifies the behavior of the server based cookies used with applets which are downloaded by the domino HTTP server. It specifies the number of minutes each cookie is valid. When a cookie expires it can not be used to obtain a session with the DIIOP task. The default value is 10 minutes and the minimum setting is 1 minute. DIIOP_DEBUG_INV OKE Use for debugging only. It provides a level of logging beyond DIIOPLogLevel. Each transaction that the DIIOP task receives is logged along with the object ID that was the target. Valid values are: 1 Show transaction details when a transaction finishes 2 Show transaction details when a transaction starts 3 Show the start of the transaction, before we even know which one it is Messages from this debug variable look like this: 01/17/2003 11:11:56.59 AM [0638:0008-06D8] OS00058ECD5 createSession 01/17/2003 11:11:56.64 AM [0638:0008-06D8] OS00058ECD5 createSession 81 ms 01/17/2003 11:11:56.97 AM [0638:0008-06D8] SN00058FBED-SN00058FBED getSessionData_U 01/17/2003 11:11:56.97 AM [0638:0008-06D8] SN00058FBED-SN00058FBED getSessionData_U 2 01/17/2003 11:23:14.80 AM [0638:0008-06D8] SN0005A04CA-SN0005A04CA getDatabase 01/17/2003 11:23:15.00 AM [0638:0008-06D8] SN0005A04CA-SN0005A04CA getDatabase 199 ms 01/17/2003 11:23:15.13 AM [0638:0008-06D8] DB0005A04E5-SN0005A04CA getAgent_U 01/17/2003 11:23:15.16 AM [0638:0008-06D8] DB0005A04E5-SN0005A04CA getAgent_U 43 ms Where: ReqBegn> ReqDone> OS00058ECD5 DB0005A04E5SN0005A04CA ReqBegn> ReqDone> ReqBegn> ReqDone> ms ReqBegn> ReqDone> ReqBegn> ReqDone> Indicates the start of a request. Indicates the end of a request. This is the ID of the object that will be performing the request. Look for a discussion of object IDs elsewhere in this document. When two IDs are present, the first ID is of the object that will be performing the request and the second is the id of the session object. The session object is the parent object almost all objects that are used. createSessio The name of the method that will be performed. These n names correspond to the IDL as defined in getSessionDa inc\ncorba.idl. ta_U getDatabase getAgent_U 81 ms The amount of time that was spent executing the 2 ms request. This time does not include time spent reading the request from the network and writing the response to the network. DIIOP_DEBUG_CWB ASE Use for debugging the Base object code that interacts with the LSXBE C++ objects. Valid values are: 1 Basic debugging information. Most useful when able to cross reference with code. 2 Adds information about object reference counts. DIIOP_DEBUG_OBJ MGR Use this sparingly. It generates a lot of data that is mostly useful with debugging the object manager code. A better alternative to start with is DIIOP_DEBUG_CWBASE. DIIOP_DEBUG_FUL LID Use this with DIIOP_DEBUG_CWBASE or DIIOP_DEBUG_OBJMGR. This debug variable will cause debug messages that include object ids to show all the information in an object's id. Every object instance is assigned a unique id. All of the contents of the object id are used to find and validate requests to use a diiop object. If this variable is not enabled the object ids are shown in this format: SN00058FBED Where: I. First two or three letters indicate the object type. In the case above SN indicates a Session object. See the IdNameTable in noi\cwbase.cpp for the complete mapping of object types II. The remaining value is a shortened time stamp of the object's creation time. The time stamp is shortened using diiop's start time If this variable is enabled the object ids are shown in this format: SN-0-185256CB1-5C4F15 Where: I. The first part is the object type II. The second part is the object's bucket number III. The third part is the object's slot number IV. The fourth part is the low-order part of the object's time stamp. V. The fifth part is the high-order part of the object's time stamp. DIIOP_DEBUG_ALL Shortcut to setting all these notes.ini variables. DIIOP_DEBUG_INVOKE DIIOP_DEBUG_CONNMGR DIIOP_DEBUG_OBJMGR DIIOP_DEBUG_SSLCERT DIIOP_DEBUG_CONFIG DIIOP_DEBUG_ORB Starting with the V7 M3 build, DIIOP_DEBUG_ALL is a shortcut to: DIIOP_DEBUG_INVOKE=2 DIIOP_DEBUG_CONNMGR=1 DIIOP_DEBUG_SSLCERT=1 DIIOP_DEBUG_CONFIG=1 DIIOP_DEBUG_CWBASE=1 DIIOP_DEBUG_CON FIG Use this to debug how DIIOP reads configuration information from the directory. To see the configuration that DIIOP is currently using, use the server command: "tell diiop show config" or "tell diiop dump config" DIIOP_DEBUG_CON NMGR Use this to debug actions performed by the connection manager code in DIIOP. DIIOP_DEBUG_SSL CERT Use this to debug actions related to generation of the TrustedCerts.class when SSL is enabled in DIIOP. DIIOP_DEBUG_COO KIE Use this to debug actions related to cookies. Cookies are the server based tokens used to share authentication information between the HTTP and DIIOP tasks. They are not related to single sign-on or LTPA tokens. DIIOP_DEBUG_IOR Use this to debug actions related to the generation or consumption of DIIOP's initial IOR that is provided to clients over the HTTP protocol. DIIOP_DEBUG_ORB Use this to debug actions related to the ORB code processing requests. Conclusion You should now have a basic understanding of how to write and compile Java applications, and how to troubleshoot them if problems arise during local and remote calls to Domino objects. Resources Lotus Domino Designer documentation: http://www.ibm.com/developerworks/lotus/documentation/dominodesigner/?S_TACT=10 5AGX13&S_CMP=LPLOTUS IBM Redbooks publication: “Connecting Domino to the Enterprise Using Java”: http://www.redbooks.ibm.com/abstracts/SG245425.html?Open developerWorks Lotus Notes and Domino product page: http://www.ibm.com/developerworks/lotus/products/notesdomino/ About the authors Chhatrapal Dhapekar is a Project Manager for the Notes Client & Application Development Team based in the IBM Technical Support Center in Pune, India. He is a Lotus Certified Professional (CLP) and worked extensively in Java Programming before joining IBM in 2006. Ranjit Rai is Technical Advisor for the IBM Technical Support Center in Pune, India. He is a Lotus Certified Professional (CLP), having more than eight years of experience working on Lotus Domino.