IBM: DeveloperWorks China website: All topic: Lotus
Java Access to Domino Objects, Part 2
content:
SSL Encrypted Servlet Connection Pool SSO (Single Login) Session Time-time Recycling Troubleshooting Path and Path Remote Computer Error Message NotesFactory Sign Note.ini Variable Conclusion Reference Author Treated to this article
related information:
Java access to the Domino Objects, Part 1 Connecting Domino to the Enterprise Using Java RedbookDomino and WebSphere Together Second Edition RedbookJava / CORBA toolkit documentationJava and Domino: Building e-Business Applications for the WebDomino Designer Help
Level: Advanced
Robert Perron
, Document architect, Lotus
Steve Nikopoulos
, Senior Software Engineer, Lotus
Kevin Smith
, Consultant software engineer, Lotus 2003 August
This article is a series of articles consisting of two parts: This article will introduce some of the advanced topics involved in the development of the Domino Objects to develop Java applications, including SSL encryption, servlet, connection pool, single sign-on, session timeout and recycling, This article also gives some troubleshooting techniques.
This article is a part 2 of a series of articles composed of two parts. In Part 1 of this series, you understand some of the basic knowledge of the Domino Objects from the Java application locally and remotely. This article you will learn about SSL encryption, servlet, connection pool, single sign-on, session timeout, and recycling. The article also includes a portion of the troubleshooting. This article assumes that you are familiar with the Domino Java API and have read the first article. SSL encrypted the previous article of this series discussed the Java application locally or remotely. Remote call requires HTTP and DIIOP access. You can use SSL (Secure Sockets Layer) to encrypt through the DIIOP port. For instructions on how to set DIIOP, see the previous article. The client code indicates encryption requirements by specifying a new second parameter in the CreateSession call. This parameter is a string array, the first element will be -orbenablesslsecurity as its value, for example:
String args [] = new string [1];
Args [0] = "-orbenablesslsecurity";
Session s = notesfactory.createsis
("myhost.east.acme.com: 63148", args,
"Jane Smith / EAST / ACME", "TOPS3CR3T"); still uses a non-SSL port (63148 in the first example) to obtain IOR. The actual service request is performed by the DIIOP SSL port. By default, the port is 63149. Before running the code, you must have a server and client that has a common trusted root certificate obtained from the certificate authority. It is best to tell this process into a series of steps. Step 1 Create a Key Ring. Open the Server Certificate Admin (Certsrv.nsf) database in the Domino server, create and fill the key ring using its form. For more information, see Administering The Domino System, Volume 2 or Domino Administrator Help. To test, you can create a key ring with a self-certification certificate using the CertadMincreateKeyringWithselfcert form. Step 2 Move the key ring to the server. The key ring contains a key ring file (KYR file) and a storage file (STH file). These files are generated on the computer that accesses the Server Certificate Admin database. Move these two key loops to or copied to a computer that contains the Domino server. Place them in the server's data directory. For example, if you create a key ring with a self-certification certificate using the default name, copy the file to the server's data file installed on the computer of C: / Lotus / Domino / Data, the server files will be: C: / Lotus / Domino/Data/selfcert.kyr c: /lotus/domino/data/selfcert.sth. Step 3 Copy TrustedCERTS.CLASS to the client and put it in the class path. Once the key loop file is located in the server, start or restart the DIIOP task will have a file named TrustedCerts.class in the Domino data directory. Distribute this file into any computer, you will access the server from this computer with CORBA through the SSL, and place the directory containing the file in the class path. For example, if you copy a file to the C: /Lotus/trustedCerts.class of the client, then the set class path will be as follows: set classpath: =% classpath%; C: / Lotus step 4 Enables SSL to the server. On the Server documentation of the server's Domino Directory, go to the Ports tab, then go to the Internet Ports tab. Under SSL settings, specify the SSL key file name (for example, Selfcert.Kyr). Go to the DIIOP tab. Make sure the SSL port number is correct - the default port number is 63149. Enable SSL port. And set Name & Password and Anonymous authentication as needed. The servletdomino server HTTP task supports servlet by loading a servlet engine and JVM. In the Server documentation of Domino Directory, go to the Internet Protocols tab, the Domino Web Engine tab, and Java Servlets tabs for settings. Domino Designer Help Document "Running Servlets in Domino" provides a detailed description of the general situation.
Below is an example of the above part of the Server document: Figure 1. Server Document By default, Domino finds a servlet executable code in the data directory under Domino / Servlet. For example, if the file named Domino / Servlet contains executable servlet, you can store it on the server as shown below: c: /lotus/domino/data/Domino/servlet/myservlet.class From the browser (default In the case where the servlet is run by specifying the / servlet and the name of the class file in the URL. For example: http://myhost.east.acme.com/servlet/myservlet If you are accessing Domino Objects, there are other two points. First, for remote access, the server's NOTES.INI file must specify the NCSO archive file for the variable javauserClasses. This variable is a class path of the JVM loaded by the HTTP task. Typical specification should be: javauserclasses = c: /lotus/domino/data/domino/java/ncso.ja, followed by the local access to the Domino Objects, NOTESTHREAD. Because other methods cannot be used in servlets, call notesthread.sinitthread before using any Domino Objects, and then call NOTESTHREAD.STERMTHREAD. The following code demonstrates simple servlets on the local access Domino Objects: import java.util. *;
Import java.io. *;
Import javax.servlet. *;
Import javax.servlet.http. *;
Import Lotus.domino. *;
Public class myservlet extends httpservlet
{
Public void doget (httpservletRequest Request,
HttpservletResponse response) THROWS IOException
{
Try
{
Notesthread.sinitthread ();
Session S1 = notesfactory.creatession ();
String name = s1.getusername ();
Response.setContentType (Text / HTML ");
ServletOutputStream out = response.getOutputStream ();
Out.println (" information from servlet: b>
);
Out.println ("
Name =" Name);
}
Catch (Exception E)
{
E.PrintStackTrace ();
}
Finally
{
NoteSthread.stermthread ();
}
}
} The local access of the Java class requires only HTTP. HTTP tasks must be run so that the browser can access the server to call the servlet. There is no need to use DIIOP tasks. For remote access, you must run the DIIOP task at the same time. The encoding will be relatively simple because notesthread is not used. It is very likely that you will not use the remote class to access Domino from the same computer. The preferred is local. However, other servlet managers (for example, WebSphere) can be run from different computers, how remote classes can be used. Here is a template: import java.util. *;
Import java.io. *;
Import javax.servlet. *;
Import javax.servlet.http. *;
Import Lotus.domino. *;
Public class myservlet extends httpservlet
{
Public void doget (httpservletRequest Request,
HttpservletResponse response) THROWS IOException
{
Try
{
Session S1 = NotesFactory.CreateSession ("MyServer.east.Acme.com");
String name = s1.getusername ();
S1.Recycle ();
Response.setContentType (Text / HTML ");
ServletOutputStream out = response.getOutputStream ();
Out.println (" information from servlet: b>
);
Out.println ("
Name =" Name);
}
Catch (Exception E)
{
E.PrintStackTrace ();
}
}
} The connection pool connection pool allows you to create multiple sessions using the same ORB (Object Reference Broker, because all sessions share a TCP / IP connection, so this will reduce network resources. In the Servlet application and server to the server, the connection pool is particularly useful. ORBs can be generated using one of the NotesFactory Createorb methods. Then create a session using the CreateSession method with the ORB parameter. The danger here is excessively loaded with network connections. The operation that spends a long period of time hinders the operation of sharing ORB's other sessions. The number of sessions created should not exceed the number of connections that can be processed, and it is reclaimed when a session is completed. The following code is a simple example, which uses an ORB, and up to 10 Domino sessions. When you run the servlet for the first time, the servlet creates a new ORB after each running servlet. The example uses the SSO described in the next section.
Import java.util. *;
Import java.io. *;
Import javax.servlet. *;
Import javax.servlet.http. *;
Import Lotus.domino. *;
Public class connpool3 extends httpservlet
{
Session s = null;
Static Org.omg.corba.orb orb = NULL;
Static int count = 0;
Static Object Sem = New Object;
Public void doget (httpservletRequest Request, httpservletResponse response) throws oException
{
Try
{
SYNCHRONIZED (SEM)
{
IF ((orb == null) || ((count % 10) == 0))
ORB = notesfactory.createorb ();
}
s = notesfactory.createsis ("MyHost1.east.Acme.com:63148",
ORB, REQUEST
String name = s.getuserName ();
S.Recycle ();
Response.setContentType (Text / HTML ");
ServletOutputStream out = response.getOutputStream ();
Out.println (" information from servlet: b>
);
Out.println ("
Name =" Name);
Out.println ("
count =" count);
}
Catch (Exception E)
{
E.PrintStackTrace ();
}
}
} SSO (single sign-on) single sign-on allows you to access multiple Domino and WebSphere servers over a server. The access server must set SSO as described in Administering The Domino System, Volume 2, or Domino Administrator Help. You can also refer to the Red Book Domino and WebSphere Together Second Edition. The following signatures created an SSO session after pre-authentication of the Domino or WebSphere server.
Session S = CreateSession (Host, String) access is based on the String token, which is previously obtained from Session.GetSessionToken, and the LTPATOKEN cookie used in the WEBSPHERE or HTTP cookie list in the servlet. Access to Session S = CreateSession (Host, Credentials) is based on org.omg.securityLevel2.credentials object. This method is used in a WebSphere environment where you use LoginHelper to create a Credentials object. Session S = CreateSession (Host, NULL) is based on the current Credentials object in the WebSphere environment. This method can be used from EJB (Enterprise JavaBeans in WebSphere. Access to Session S = CreateSession (Host, HttpservletRequest) is based on the Domino web server authentication. The following code illustrates basic knowledge. It uses the name and password access server to obtain the SSO token, and then use the token to access other servers in the same SSO domain.
Import Lotus.domino. *;
Public Class Sso1 Implements Runnable
{
Public static void main (String Argv [])
{
SSO1 T = New SSO1 ();
Thread NT = New Thread ((runnable) T);
Nt.start ();
}
Public void Run ()
{
String token = NULL;
Try
{
String host1 = "myhost1.east.acme.com:63148";
String name = "Jane Smith / EAST / ACME";
String Pw = "TOPS3CR3T";
Session s = notesfactory.creatession (Host1, Name, PW);
Token = S.GetSessionToken ();
S.Recycle ();
}
Catch (Exception E)
{
E.PrintStackTrace ();
}
Try
{
String host2 = "myhost2.east.acme.com: 63148";
Session s = notesfactory.creatession (Host2, token);
System.out.println (s.getusername ());
}
Catch (Exception E)
{
E.PrintStackTrace ();
}
}
} The next code is a servlet example, which acquires the SSO token from the HTTP cookie list.
Import java.io. *;
Import javax.servlet. *;
Import javax.servlet.http. *;
Import Lotus.domino. *;
Public Class Sso13 Extends httpservlet
{
Public void doget (httpservletRequest Request,
Httpservletresponse response
Throws ServleTexception, IOException
{
Cookie [] cookies = NULL;
String sessionToken = NULL;
Try
{
Cookies = Request.getCookies ();
}
Catch (Exception E)
{
E.PrintStackTrace ();
}
IF (cookies! = null)
{
For (int i = 0; i { IF (cookies [i] .getname (). Equals ("ltpatoken")))))) { SessionToken = cookies [i] .GetValue (); } } } IF (sessionToken! = null) { Try { Notesthread.sinitthread (); Session session = notesfactory.creatession (null, sessionToken); Response.setContentType ("text / plain"); ServletOutputStream out = response.getOutputStream (); Out.println ("UserName:" session.getusername ()); } Catch (NotSexception E) { E.PrintStackTrace (); } Finally { Notesthread.stermthread (); } } } Session timeout For remote sessions, the server will have the maximum idle time limit. If a session's idle time exceeds this limit, the server will abort this session and release the resource. In the Server document, you can set this value in the Idle Session Timeout field of the Internet Protocols -> Diiop tag, the default value is 60 minutes. Figure 2. Server documents In the client code, use the session.isvalid () method to determine if a remote session is available. If the remote session is timeout, the isvalid () method will return false values. The following example will create a remote session and re-access this session. This session is still available in the conditional statement. If it is not available, the program will recreate a session. Import Lotus.domino. *; Public Class Isvalidtest IMPLEments Runnable { String host = null, user = "" ", pwd =" "; Session s = null; Public static void main (String Argv []) { IF (argv.length <1) { System.out.println ("Need to Supply Domino Server Name); Return; } Isvalidtest T = New IsvalidTest (Argv); Thread NT = New Thread ((runnable) T); Nt.start (); } Public isvalidtest (String Argv []) { Host = argv [0]; IF (argv.length> = 2) user = argv [1]; IF (argv.length> = 3) PWD = argv [2]; } Public void Run () { Try { S = NotesFactory.createSession (Host, User, PWD); String p = s.getPlatform (); System.out.println ("Platform =" P); } Catch (Exception E) { E.PrintStackTrace (); } // Later the Same Day Try { IF (! s.issalid ()) S = NotesFactory.createSession (Host, User, PWD); String n = s.getusername (); System.out.println ("UserName =" N); } Catch (Exception E) { E.PrintStackTrace (); } } } The isvalid () method will activate the session, and the session will reset the timeout clock. Recycling Java does not know the heavyweight backend Domino Objects, only recognizing the lightweight Java objects of these objects. For local categories, Domino Objects uses memory in the process of running a Java program. If you do not reclaim these memory, garbage collection will not occur until the program exits. Memory uses may exist in the following cases: The program is running for a long time especially when servlet belongs to such programs. The program is an iterative process for the Domino Objects that it is an iteration. All Domino Objects has a reclaim method. The recycling method will terminate the current object and all its sub objects and release their memory. When there is a problem with memory usage, it is highly recommended to recycle memory. For example, you can place the following statements (where the session is the session object) is placed behind the DOGET code in the servlet. This will reclaim all Domino Objects after each call servlet. Session.Recycle (); the following statement can be placed behind the loop of the processing document (where DOC is the Document object) (in any application). This will reclaim the Document object and all the sub-objects (such as items) at each call. Doc.recycle (); for remote Domino Objects, the recycling is not so important. At that time, memory use was in the DIIOP process, and garbage collection was performed by threads. The entire session will be automatically reclaimed if the TCP / IP connection is lost. Recycling also has the following signatures: Recycle (java.util.Vector Objects) where the vector contains Domino Objects. This signature effectively batchs the reclaim request to improve the efficiency of remote calls. When recycling, please follow the following guidelines: recovery only when the object is no longer needed. For local Domino Objects, reclaim this object in the thread of the object. For local Domino Objects in the session, Recycle () can only be called after exiting all other threads. When using notesthread.sinitthread () and notesthread.stermthread (), Recycle () is called before Stermthread. If multiple objects represent the same Domino object, reclaim an object will reclaim all objects. If you try to use the recycled object, the result is unclear. There may be no mistakes. Troubleshooting Next section will introduce a fault overhaul program for general problems. Class paths and paths ensure that the code can access the necessary classes. Suppose Notes and Domino software are installed in C: / Lotus / Domino, then class paths and paths must be set as shown below: Environmental Path Path Local Applications or Servletc: /lotus/domino/Notes.jarc: / Lotus / Domino Remote Applications or Servletc: /lotus/domino/data/domino/java/ncso.jar does not apply to local categories Path is important because notes.jar needs to use Notes / Domino binaries and Notes.ini. If Domino from a computer without Domino software, you must copy the NCSO archive to the computer. Class paths should reflect the location of the archive in the computer. For SSL, classpaths must specify folders that contain trustedcerts.class. Remote computers To use Domino Objects remotely, you must run the remote computer, you must run the Domino server, the client computer must use the correct host name or IP address. In Windows, if you have access to server computers, you can get information such as host name, DNS server, and IP address by the following DOS commands:> IPConfig / ALL In the client computer, you must access server computers. You can try ping commands:> ping hostname or> ping ipaddress If you can't ping a remote computer, it is a problem with the network. It may be a problem with physical network connection, network settings, or input names. These issues must be solved to continue the followed operation. If you can ping a remote computer, try the Telnet command to see if the port of the remote computer is correct. For HTTP, the default port is 80. For DIIOP, the default port is 63148. > Telnet Host Port If you can ping your computer, but you can't Telnet port, it may be one of the following situations: not running Domino Server. Run the server, but no HTTP or DIIOP task is run. If you access the IOR via the web server port, you should be able to access the Domino Server from the browser using the following URLs. Server, you can use the following console command to check the Diiop task:> Tell Diiop Show Config is some typical output: > TELL DIIOP SHOW CONFIG Dump of Domino IIOP (DIIOP) Configuration Settings Full Server Name: CN = Buffalo / O = ZOO Common Server Name: Buffalo / ZOO Refresh Interval: 3 minutes Host Full Name: buffalo.mycompany.com Host Short Name: Buffalo Host Address: 9.99.99.999 Public Host Name / Address: 9.99.99.999 TCP Port: 63148 enabled SSL Port: 63149 enabled Initial Net Timeout: 120 SECONDS Session Timeout: 60 minutes Client Session Timeout: 62 Minutes IOR file: d: /dom60x/data/domino/html/diiop_ior.txtssl key file: d: /dom60x/data/mykeyfile.kyr Java Key File: D: /DOM60X/Data/domino/java/trustedCerts.class Allow Ambiguous Names: False Web name authentic: false User Lookup View: ($ USERS) Allow Database Browsing: True TCP Name / Password Allowed: True TCP Anonymous Allode: True SSL Name / Password Allowed: True SSL Anonymous Allode: True Multi-Server Session Authentication: enabled Multi-Server Session Configuration: MyssoConfig Internet Site: Disabled Single Server Cookies: Disabled Error Messages are some error messages and possible explanations. HTTP JVM java.lang.classNotFoundException and http jvm java.lang.noclassdeffounderror These messages are displayed on the server console. They indicate that the client is trying to use the remote class, but the JavauserClasses is specified in the NOTES.INI in the server. NotSexception: COULD NOT GET IOR from Domino Server: java.net.connectexception: Connection Refused This error message indicates one of the following: The server is run. The code does not run the HTTP task, and the code gets IOR via the HTTP port. The code does not run the Diiop task, and the code gets IOR via the DIIOP port. Specifies the IP port, but the port is incorrect. NotSexception: Could Not get IOR from Domino Server: java.net.connectException: Operation Timed OUT In the bar error message indicates that there is a network configuration error. Notesexception: Could Not get IOR from Domino Server: java.net.unknownhostException This error message indicates one of the following: The computer name or IP address is not specified correctly. Not running the computer. NotSexception: COULD NOT OPEN NOTES session: org.omg.corba.comm_failure: java.net.connectException: Connection Refused This error message indicates that you are not running DIIOP tasks on the server. Notesexception: Invalid User Name / Password This error message indicates that the code is trying to use unknown name or invalid password to access Domino Directory. Notesexception: Server Access Denied This error message indicates an Anonymous access, but is not allowed. Notesexception: User username is not a server This error message indicates that the session is tried to run the session through the Domino Directory on the client. Notesexception: Wrong Password This error message indicates that the code provides an error password when attempting to access through the Notes ID. If the code does not send a password, the access is originally anonymous. If authentication is required (for example, try to open the database), the Lotus Notes box will appear to ask you to enter your password. This box will always display until the user provides the correct password or click Cancel. Reference to createSession Is Ambigous This error message will appear during the compilation process. Indicates that NULL is used as the CreateSession parameter. In most cases, "String NULL" must be used. UnsatisfiedLinkerRor: NCREATESSESSION This error message indicates that the local session does not use NOTESTHREAD. Provide NotSthread.sinitthread and Stermthread, or use Notesthread. NOTESFAACTORY Signature NotesFactory CreateSession method You can create a local or remote session object. Local sessions can be used to make local sessions using Notes ID or Domino Directory. Remote session uses Domino Directory. For the NOTESFAACTORY signature complied with the following format: Hostname = hostname | HostName: Port | ipaddress | ipaddress: Port Using the local session using the Notes.jar and NotSthread. The following method signs are used to create a local session using the Notes ID. CreateSession () CreateSession (String) NULL CreateSession ("" ") CreateSession (String) NULL, (STRING) NULL, PASSWORD CreateSession (", (string) NULL, Password) CreateSessionWithfullaccess () // Useful on Server ONLY CreateSessionWithfullaccess (Password) // Useful on Server Only uses the local session of Domino Directory (server only), NOTES.JAR and NOTESTHREAD. The following method signs are used to create a local session using Domino Directory. CreateSession (String) NULL, "", "") // anonymous CreateSession (",", "") // anonymous CreateSession ((String) NULL, Username, Password CreateSession ("", username, password) Using Domino Directory Remote session requires ncso.jar or equivalent file. Also, if the client gets IOR using the DIIOP port or HTTP port, you must access the server via a DIIOP port or an HTTP port. The following method signs are used to create remote sessions using Domino Directory. CreateSession (Hostname) // anonymous CreateSession (Hostname, Username, Password) CreateSession (hostname, -orbenablesslsecurity, username, password) CreateSessionWithior (IOR) // anonymous CreateSessionWithior (IOR, Username, Password) CreateSessionWithior (IOR, -ORBENABLSECURITY, Username, Password) Getior (Hostname) Notes.ini Variable The NOTES.INI variable of the Domino server will affect DIIOP tasks. Variable Description DiiopConfigUpdateInterval Specifies the time that DIIOP should check to refresh the configuration data in Domino Directory, indicated in minutes. The default value is 3 minutes DiiOPDNSLOOKUP to determine if DIIOP should perform DNS name for each client that uses DIIOP services: 1 - Enable DNS Find 2 - (default) Disable DNS Find When using the server console display task, You can see this information DiiopiorHost specifies the host name or IP address and uses it through the DIIOP identification server. The default name is based on the "Fully Qualified Internet Host Name" field under the Basics tab in the Server document. The preferred method for setting this value is to use the Host Name / Address field under the DIIOP and the Internet Protocols tab in the Server document. In R5, the variable is called DIIOP_iOR_HOST, but it is backward compatible with DiiopignoreportLimits (Linux only) to ignore port restrictions, so that the default DIIOP ports 63148 and 63149 can be used. Some Linux systems set port restrictions, not allowing DIIOP usual defaults: 1 - ignore restrictions; use ports 63148 and 63149 2 - comply with restrictions; use ports 60148 and 60149 in R5, this variable is called DIIOP_IGNORE_PORT_LIMITS, but it The backward compatibility is still valid. Diioploglevel Specifies the level of the information provided by DIIOP to the server console and log: 0 - Display only errors and warnings 1 - also display information message 2 - also display session initialization and termination message 3 - also display session statistics 4 - - Also showing transaction messages can be used in the server console to set this value DIIOPCOOKIECHECHECHDDRESS to serve the server-based cookie for the Applet downloaded with the Domino HTTP server, which determines whether the IP address of the client access to the cookie must Matching the IP address of the client to receive cookies: 0 - (default) does not have to match 1 - Must match Most cases, the client IP address does not have to match. Using HTTP to send cookies, HTTP is usually sent through the proxy server. Cookie's user is applet, and Applet does not pass the agent server Diiopcookietimeout to serve the server-based cookie with the Domino HTTP server downloaded with the Domino HTTP server, which specifies the number of minutes of each cookie. Unable to use the expired cookie to sessions with DIIOP tasks. The default value of this variable is 10. The minimum value of 1 End the literary series is synthesized by using Java to access Domino Objects. In Part 2 of this series, we talked about SSL encryption, servlet, connecting pool, single sign-on, session timeout, and recycling. At the same time, it also contains a section that introduces troubleshooting. Combined with the first article of local and remote calls and access control, now, you should have a bamboo with Java application. Robert Perron is a document architect in Lotus, WESTFORD, Massachusetts. Since the beginning of the 1990s, he has been developing documents for Lotus Notes and Domino, mainly dedicated to programmable functions. He has developed a document for LotusScript and Java Notes, and with others with 60 minute guide to lotusscript 3 - Programming for Notes 4 book. He also wrote a number of articles in LDD Today. Last year, he wrote the article "A Comprehens / Domino 6" for the View. Referring Abstract You can see this article on our website on the world of developerWorks. Java access to the Domino Objects, Part 1 Connecting Domino to the Enterprise Using Java Redbook Domino and WebSphere Together Second Edition Redbook Java / CORBA toolkit documentation Java and Domino: Building e-Business Applications for the Web Domino Designer Help About the Author Robert Perron is a document architect in Lotus, WESTFORD, Massachusetts. Since the beginning of the 1990s, he has been developing documents for Lotus Notes and Domino, mainly to develop programmable. He has developed a document for LotusScript and Java Notes, and with others with 60 minute guide to lotusscript 3 - Programming for Notes 4 book. He wrote a number of articles for ldd Today. Last year, he wrote the article "A Comprehens / Domino 6" for the View. Steve Nikopoulos is a senior software engineer of the Domino Server Programmability team. His recent work includes remote Domino Objects, Domino / WebSphere integration, and single sign-on. He likes to ride a bicycle with his family in the air time. Kevin Smith is a consultant software engineer in Westford IBM Messaging & Collaboration Development, and is currently responsible for the development of programmable functions of Domino servers. He entered Lotus in 1990, which is a technical support engineer of Lotus 1-2-3 / M. One of the Lotus Adventure Investment Project. Page