Home > Articles

Java Agents, Servlets, Applets, and Applications

The Java language can be used in several different contexts with Notes and Domino. In particular, you can use Java in agents, servlets, applets, and applications. Each of these different contexts interacts differently with the Domino environment, so let me explain these contexts. In Chapter 2, "Domino Designer and the Integrated Development Environment (IDE)," I told you about the differences between these types of programs and when each language could be used. I'd like to examine each of the Java contexts now in more detail.

Some of the main characteristics of these different types of programs are how they are created, how they are invoked, and how they are terminated. I'll describe these characteristics in each section.

Domino Java Agents

Java agents in Domino are really just special cases of the NotesThread class that we saw earlier. To create an agent, you extend the AgentBase class. However, the AgentBase class itself is just an extension of the NotesThread class, so without necessarily knowing it, your agent is also a NotesThread.

When I showed you how a NotesThread is started, I said that you need to provide only one routine, the runNotes method. When the NotesThread is started, the runNotes method is invoked automatically. In the special case of agents, however, the Notes system has some additional housekeeping chores to perform before it can start your code. So, in the case of agents, Notes commandeers the runNotes method, declares it final so you cannot use it, and substitutes the NotesMain method for your code. Here is how a Notes Java agent actually starts up:

  1. java.lang.Thread:start initializes the new thread environment and calls the thread's run method on the new thread.

  2. NotesThread:run initializes the Notes environment and calls AgentBase:runNotes.

  3. AgentBase:runNotes initializes the agent environment and calls your agent's NotesMain method.

  4. YourAgent:NotesMain is your agent code.

The AgentBase runNotes method sets up an AgentContext object and creates a Session object. Because your agent extends the AgentBase class, you can use this.getSession to get the Session object that was created by runNotes.

If we look at the code that is automatically produced by the Domino Designer IDE for a Java agent, it should now be very clear. Notice that the getSession call omits the this qualifier. You can use either this.getSession or just plain getSession. It is important to understand the shorthand and why you don't need to use the this qualifier. (It's because getSession is defined in AgentBase and your agent extends AgentBase, so in effect your agent is an AgentBase.) Here's the code:

import lotus.domino.*;

public class JavaAgent extends AgentBase {
  public void NotesMain() {
   try {
     Session session = getSession();
     AgentContext agentContext = session.getAgentContext();
     // (Your code goes here)

   } catch(Exception e) {
     e.printStackTrace();
   }
  }
}

Your Java agent automatically terminates when your NotesMain method ends. After it ends, control is returned in the reverse order to AgentBase:runNotes and then NotesThread:run. When run finishes, the thread itself is finished.

Also notice in the automatically generated code that an AgentContext is obtained. The AgentContext includes information such as the effective username, the current database, and the set of unprocessed documents that the agent should handle, along with several other agent properties.

Remember that an agent can run on either the Notes client or a Domino server. When the agent is running on the Notes client, the effective user is the current workstation user ID. However, when the agent is running on the server, the effective user is the user who last signed the agent. In addition, via the agent properties, you can also set up the agent to run with the identity of a Web user.

You can run a Java agent on a Domino server via a URL. You do this from a Web browser with the following syntax:

http://server/database.nsf/agentname

The database must exist, of course, and the specified agent must be a shared agent within the database. To send output back to the Web user, you must create a PrintWriter object by getting it from the AgentBase object. Here is how you do that:

Session s = getSession();
AgentContext ac = s.getAgentContext();
PrintWriter pw = getAgentOutput(); // Get AgentOutput
pw.println("<h1>Hello World</h1>");  // Send output back to browser

For this to work, make sure that your agent is declared as a shared agent. Note that you can specify this choice only when the agent is created. After it's created, you cannot turn a nonshared agent into a shared agent. You make an agent shared by checking the checkbox directly beneath the agent's name in the Create Agent dialog box.

The capability to run an agent on the server is similar to the servlet capability. There are a few differences, however. First, an agent is stored within a Domino database. Because of this, it can be replicated and can travel along with the database to another server. In addition, Java agents use the Domino security model and are more secure than servlets. Agents are written by extending AgentBase as previously described, and you use a NotesMain method for your agent code.

Java Servlets

Java servlets are stored as Java class files and archive (JAR) files within a directory on the server. Servlets can be initialized and stay active within the Domino server. When resident, a servlet can process many requests in a multithreaded manner from several Web clients at once. The capability to remain in memory can provide servlets with an important performance advantage for certain applications. Because servlets might be handling many requests simultaneously, it is critical that servlets be threadsafe.

One common use for servlets is to access non-Domino databases via JDBC. You can also access Domino databases using the Java techniques described in previous sections. Servlets are an industry standard for server-side Java programming, whereas agents are Domino-specific. Servlets are typically implemented as extensions of the javax.servlet.http.HttpServlet class. There is a full discussion of servlets in Chapter 27, "Using IBM WebSphere for Java Servlets and Java Server Pages (JSP)."

Java Applets

An applet is a set of one or more Java classes that is downloaded to a Web browser and executed within the context of the JVM in the Web browser itself. Regular Java applets are independent of Notes and Domino. You can have Java applets that are created and served by a Web server, such as Domino or any other Web server.

Just as Domino Java agents are special cases of the Java Thread class, with release 5 of Notes and Domino you can have specialized Domino applets as well. Let me first describe a regular Java applet, and then I'll explain how Domino Java applets are different.

An applet in Java is actually invoked by the Web browser. There is no main method in a Java applet. In fact, there are four important methods in a Java applet: init, start, stop, and destroy. Here are their definitions:

  • void init()—This method is invoked when the applet is first loaded. It is called only once.

  • void start()—This method is invoked after the init method. It is also invoked when the page comes into view or the browser is restored from an icon view.

  • void stop()—This method is invoked when the page is left or when the browser is minimized into an icon.

  • void destroy()—This method is invoked when the applet is no longer required. It is called after the stop method.

For completeness, I should mention that a Java applet is not actually a base class. As a matter of fact, it is four layers down in the hierarchy. The upper layers are Component, Container, Panel, and Applet. In other words, Applet extends Panel, which extends Container, which extends Component. These classes can be found in the java.awt package.

If you are using the Java Swing classes, an additional class called JApplet is available. This is similar to the Applet class but uses the Swing classes rather than the standard user interface classes.

It is beyond my scope here to explain all these other classes, but you should be aware of them. Suffice it to say that these other classes deal with user-interface characteristics, such as layout and the graphical appearance of the applet. For more information on applets, see Chapter 15, "Developing Java Applets for Use with Domino."

Domino Java Applets

What exactly is a Domino Java applet? A regular applet that is served by a Domino server to a Web browser might qualify, but that is not what I mean by a Domino Java applet. A Domino Java applet is an applet that has the capability to access Domino objects. In other words, it can do everything that a normal applet can do, but it can also access Domino.

What does it mean to access Domino? This is an important question. Remember that a regular applet is a Java program running within the JVM in the Web browser. Consider this hypothetical case. Suppose you have the newest gadget, a Web-enabled television set. This TV is a pure Java machine. It has a Java Virtual Machine (JVM) installed and can download and execute Java programs, but it certainly isn't a personal computer. Can you execute a Domino Java applet? Yes. In your Web television set, you can access Domino databases, traverse views, and use a Java program to perform functions that you might have used LotusScript for previously.

It is important to understand the capabilities of a Domino Java applet and to understand how this type of applet differs from a regular, ordinary Java applet. Let's take a look at a Domino Java applet.

A Domino Java applet is similar in concept and implementation to a Domino Java agent. If we want to create a Domino Java applet, we must extend the AppletBase class. This is analogous to extending the AgentBase class for agents. After we have extended AppletBase, there are four important methods for our Domino Java applet:

  • void notesAppletInit()—This method is invoked when the applet is first loaded. It is called only once.

  • void notesAppletStart()—This method is invoked after the notesAppletInit method. It is also invoked when the page comes into view or the browser is restored from an icon view.

  • void notesAppletStop()—This method is invoked when the page is left or when the browser is minimized into an icon.

  • void notesAppletDestroy()—This method is invoked when the applet is no longer required. This method is called after the notesAppletStop method.

I'm sure that you can see the immediate similarity to the four methods that are defined for a regular applet. Just as in the case for agents, the four notesApplet methods correspond to the underlying methods. I should also mention that the regular init, start, stop, and destroy methods are declared final within AppletBase, so you are not allowed to override them, and you should not call them directly.

A few additional methods are in the AppletBase class. These methods are openSession, closeSession, and getSession. openSession calls getSession, and I don't think there is any additional function performed in openSession that does not also occur in getSession. Thus, you can probably consider them synonyms, but openSession and its counterpart closeSession are the preferred methods.

The openSession (and getSession) method is similar to the getSession method found in AgentBase. Remember that we need to have a Session object to access the Domino objects. After we have this Session object, we can pretty much traverse the entire object model hierarchy. There are two forms for openSession within AppletBase:

Session s = openSession();  // Anonymous access
Session s = openSession(String userid, String password);

The first of these methods is used for anonymous access, and in the second method, you pass the user ID and password strings.

When you are finished with the Session object, you can close it with closeSession.

closeSession(s);  // Close the previously opened Session.

The last method in AppletBase is the IsNotesLocal method. This routine returns true if the applet is running within a Notes client and is accessing a local database. It returns false if you are accessing a remote server.

If you are using the Java Swing classes, you can extend your applet from the JAppletBase class rather than the AppletBase class. The JAppletBase class supports an identical set of methods to the AppletBase class.

I have not described, until now, the magic that is used to implement Domino access from a Web-enabled television set. Hold on to your hats, here come the acronyms: CORBA and IIOP. These two technologies are important because they basically enable you to perform client/server computing, using Web browsers and Java over the Internet. The client can be any Java-enabled Web browser, and the server is Domino. I describe these technologies in more detail in Chapter 15.

Accessing Domino Databases from Java Applications

There are a couple of scenarios for accessing Domino from standalone Java applications. First, you can access local Domino databases if you have Java and the Notes executable files present on your computer. This will typically be the configuration on your desktop or laptop computer if you are using the Notes client.

Second, with those magic components CORBA and IIOP, you can create a standalone Java application that runs on your desktop but accesses a remote Domino server. In this case, all you need to have present on your local computer is a JVM and the appropriate archive files. You do not need to have the Notes executable files present.

In the earlier section, "Java Applications and Multithreading," I showed you the basics of standalone Java applications and how to initialize the Notes/Domino environment. As mentioned, a standalone application can extend NotesThread, or you can create a class that implements the Runnable interface. In either case, you must also have a static main routine. This main routine is invoked by the JVM machine. Here is an example of a Java program that extends NotesThread. This is an example that must run locally. It does not use CORBA or IIOP.

import lotus.domino.*;

public class MyNotesMain4 {
  public static void main(String args[ ]) {
   try {
    ExtendedThread etMyThread = new ExtendedThread(); // My Thread
    etMyThread.start(); // This will eventually invoke my runNotes();
    etMyThread.join();  // Wait for thread to finish
   }
   catch(InterruptedException e) {
   }
  }
}
public class ExtendedThread extends NotesThread {
  public void runNotes() {
   try {
     Session s = NotesFactory.createSession(); // Create a new Session
     String v = s.getNotesVersion(); // Notes version
     String p = s.getPlatform();   // Platform
     System.out.println("Running version " + v + " on platform " + p);
   }
   catch (Exception e) {
     e.printStackTrace();
   }
  }
}

Here is how this routine starts up:

  1. JVM calls MyNotesMain4:main, which creates an ExtendedThread, which extends NotesThread. The main then calls ExtendedThread:start (which is actually implemented in Thread:start).

  2. Thread:start (ExtendedThread:start) initializes the thread and calls ExtendedThread:run. Because ExtendedThread extends NotesThread, the run method is actually implemented in NotesThread:run.

  3. The NotesThread:run routine initializes the NotesThread environment and calls the ExtendedThread:runNotes method. This is where your code resides.

NOTE

Do not confuse the Thread:start routine with the Applet:start routine. Although they have the same method name, they are completely different methods. Thread:start is a system routine that starts a thread; Applet:start is an optional user-written routine invoked by a browser when an applet starts.

The following example uses CORBA and IIOP. This main program can run on a client that does not have the Notes executables locally.

import lotus.domino.*;

public class MyNotesMain5 {
  public static void main(String args[ ]) {
   try {
    RunnableThread rtMyThread = new RunnableThread(); // My Thread
    // NotesThread extends java.lang.Thread
    NotesThread theThread = new NotesThread(rtMyThread); 
    theThread.start(); // This will eventually invoke my run();
    theThread.join();  // Wait for thread to finish
   }
   catch(InterruptedException e) {
   }
  }
}
class RunnableThread implements Runnable {
  public void run() {
   try {
     String IOR = lotus.domino.NotesFactory.getIOR("ACMESERVER");
     System.out.println("IOR='" + IOR + "'");
     Session s = NotesFactory.createSessionwithIOR(IOR, 
     "John Doe/AcmeCorp", "secretpassword");
     String v = s.getNotesVersion(); // Notes version
     String p = s.getPlatform();   // Platform
     System.out.println("Running version " + v + " on platform " + p);
   }
   catch (Exception e) {
     e.printStackTrace();
   }
  }
}

This code is an example of the Runnable interface. The major point to notice in this example is the fact that we have a new variable called IOR. IOR stands for Interoperable Object Reference. The IOR is specified as a string. If you print it out, you'll notice that it is a huge hexadecimal string. This string is used to set up the CORBA communication between the client and the server. If you are debugging online, you'll also notice a fairly long delay when you create the Session because of all the CORBA initialization. After the CORBA initialization has finished, however, the application will run fairly quickly.

If you want to eliminate the need for the IOR, you can use the createSession method with the three parameters host, userid, and password. Here is the syntax:

Session s = NotesFactory.createSession(hostname, userid, password);

Hostname is the same parameter you pass to the getIOR method. The regular createSession method will obtain the IOR for you, making it a little easier to use.

The two examples MyNotesMain4 and MyNotesMain5 showed two different ways to create a standalone application. MyNotesMain4 created an inherited thread, and MyNotesMain5 created a Runnable class. You can use CORBA via either method.

One final note about this example: If you want to try this example yourself, you must substitute your server name, your user ID, and your password at the appropriate points in the program.

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020