Chapter 2. Working with Notes/Domino Configuration Files

In Chapter 1, “Working with XSP Properties,” you saw how the xsp.properties file served as a configuration file for the XPages runtime. In an analogous manner, both the Notes client and the Domino server have a configuration file that sets parameters for various elements of core behavior: notes.ini.

Whereas the xsp.properties file is specific to XPages, notes.ini has many masters to serve; it is a common resource that all components in the Notes/Domino core share. As a consequence, the notes.ini files in your particular Notes/Domino installations might contain hundreds of diverse settings. For instance, a current check of the notes.ini file for my own Notes client shows that it has 198 entries, while my Domino server notes.ini contains 112 entries. The good news is that only a small fraction of these entries are directly relevant to XPages.

INI Variables You Should Know About

The notes.ini file is located in the root installation folder of the client and server. Listing 2.1 shows the first 20 lines of a sample Domino server notes.ini file, which includes all the entries that relate to XPages (directly or indirectly) as of Notes/Domino 8.5.3. These entries are emphasized using a shaded background.

Listing 2.1. Sample Snippet from a Domino Server notes.ini Configuration File


[Notes]
NotesProgram=C:Domino
Directory=C:Dominodata
JavaEnableDebug=1                                                              
JavaDebugOptions=transport=dt_socket,server=y,suspend=n,address=8000           
KitType=2
InstallType=4
HTTPJVMMaxHeapSize=256M                                                        
HTTPJVMMaxHeapSizeSet=1                                                        
JavaMaxHeapSize=64M                                                            
JavaMinHeapSize=16M                                                            
PartitionNumber=1
XPagesPreload=1                                                                
XPagesPreloadDB=teamdisc.nsf/ByAuthor.xsp                                      
FaultRecovery_Build=Build V853_06152011NP
Timezone=0
OSGI_HTTP_DYNAMIC_BUNDLES=update/extlibupdate.nsf,sbtupdate.nsf                
NSF_QUOTA_METHOD=2
JavaUserClasses=D:jdbcutilsjdbcdrivers.jar;D:javacustomlibs                
ServerName=lehenaghmore/XYZ


Table 2.1 describes these entries.

Table 2.1. Sample Domino Server notes.ini Settings

Image
Image

Table 2.1 describes the various notes.ini variables that can be added to debug XPages applications, extend their capabilities, and optimize their performance. Unless otherwise stated, it can be assumed that any given INI variable under discussion applies to the Domino server rather than the Notes client. In addition, any INI variable can be added or edited in one of three ways:

• By directly editing the notes.ini file using a text editor.

• On the server, using a Domino console command of this form:

set conf varname=value

• On a server using the Name & Address Book (NAB) configurations parameters document. This approach is particularly useful in server clusters because the configuration replicates across all servers. As a result, the administrator doesn’t need to manually configure each server.

On the Domino server, after a notes.ini variable is set, it is typically necessary to restart the HTTP task for the server to read and use the variable. In some cases, it is necessary to restart the server itself. Tasks on the Domino server that have Java programs embedded within them typically initialize and run a separate instance of the server’s JVM per task. For instance, the Agent Manager, the HTTP task, and others all run unique instances of the server’s JVM. It is also worth pointing out that, in many cases, notes.ini settings apply across all server tasks and are not necessarily tied to the HTTP task. Variables that apply only to the HTTP task are prefixed with HTTP in the variable name. If a variable applies to more than the HTTP task, users must use caution when modifying those variables; the consequences of the changes made will reach beyond the XPages runtime and, indeed, the HTTP task.

Depending on the task, the requirements on the JVM instance differ. As a result, various INI variables have been added to notes.ini to make the different JVM instances as configurable as possible. This enables the Domino server administrator to fine-tune the memory consumption of the Domino server while simultaneously optimizing the performance delivered to the end user.

Because the XPages runtime is written almost entirely as a Java program, the HTTP process must have a larger maximum Java heap size than was historically necessary for most Domino servers. That is not to say that XPages applications consume more memory than “traditional” Notes applications; however, resources now must be allocated to the Java process where traditionally they were not required.

Administrators have always been able to apply heap size minimum and maximum limits across all Java processes running on the Domino server via two INI variables, JavaMaxHeapSize and JavaMinHeapSize. Both are discussed later. With the release of Domino 8.5.2, two new variables have been added that increase the flexibility of these limits: HTTPJVMMaxHeapSize and HTTPJVMMaxHeapSizeSet. Before delving into the various heap size variables that are available to Domino’s JVM, it is worth explaining what the Java heap is and how it affects performance.

The Java Heap

The JVM’s heap is responsible for storing all objects that a Java program creates. The JVM creates a Java object when the constructor for an object is called within a running program. The JVM stores the object (on its heap) until all references to the object have been released. Only when all references have been released does the JVM allow garbage collection to occur on the object. The term garbage collection describes the process by which Java deletes previously created objects and makes the memory previously allocated to those objects available for other objects to use.

The size of the Java heap determines the frequency at which garbage collection needs to be run. In larger applications, it is not uncommon to set the size of -Xms (minimum heap size) and -Xmx (maximum heap size) to be the same, to give a fixed heap size. This helps to improve overall performance, particularly boot performance (performance when the application is bootstrapping/starting on the server).

One of the main memory goals of a JVM is to keep its memory footprint within the constraints provided via its vm arguments (that is, within the minimum and maximum heap limits). As a result, when a JVM notices that the amount of memory it is using is nearing the amount of memory allocated to it, the JVM runs garbage collection in an attempt to keep its memory footprint below the amount currently allocated. If the minimum heap size is a small number, garbage collection must run frequently to keep the memory footprint as small as possible. Each time the amount of memory the JVM uses nears the amount of memory currently allocated to the JVM, garbage collection is run. Garbage collection algorithms have been optimized significantly with each release of Java, but garbage collection doesn’t come for free. A performance impact occurs each time the garbage collector must be executed. Furthermore, when garbage collection is running, it takes priority over all other processes running within the JVM. Figure 2.1 illustrates sample memory consumption of the HTTP task’s JVM during startup when the minimum heap size is set to 16MB. The same battery of tests was run against the XPages runtime in all the following graphs. You can see that, as minimum heap size increases, the amount of time spent performing garbage collection decreases.

Image

Figure 2.1. Memory consumption by HTTP JVM when JavaMinHeapSize is set to 16MB

As you can see in Figure 2.1, each time the amount of memory the JVM uses nears the allocated memory threshold, garbage collection is run. The graph shows that there will be an impact on performance during startup due to the low minimum heap size. When the JVM determines that, after garbage collection, the amount of allocated memory is not enough to create a new object, the JVM allocates more memory for itself, if possible.

Figure 2.2 illustrates how much time the JVM spends performing garbage collection during the same time period in Figure 2.1.

Image

Figure 2.2. Time spent performing garbage collection when JavaMinHeapSize is set to 16MB

From looking at Figure 2.1 and 2.2, you can easily see that the JVM performs garbage collection approximately two minutes into the scenario. Next, you can see from Figure 2.3 and 2.4 that, as the minimum heap size is increased, the amount of time spent in garbage collection decreases.

Image

Figure 2.3. Memory consumption by HTTP JVM when JavaMinHeapSize is set to 48MB

Image

Figure 2.4. Time spent performing garbage collection when JavaMinHeapSize is set to 48MB

Figure 2.3 illustrates sample memory consumption for the same scenario, but this time with the minimum stack size set to 48MB.

Finally, Figure 2.4 illustrates the amount of time spent in garbage collection during the same scenario.

Although it is difficult to give an exact figure for optimal JVM performance, if the server administrator/developer knows that the amount of memory the JVM requires is likely to regularly exceed the minimum allocated to the JVM, it is advisable to increase the minimum heap size, if possible. This results in less time spent performing garbage collection and more time being allocated to processes that perform tasks that the end user can see.

We have discussed the reasoning behind setting JavaMinHeapSize to a reasonable size, but we have not mentioned the impact of setting the opposing settings HTTPJVMMaxHeapSize and JavaMaxHeapSize. Both of these settings are responsible for setting the maximum heap size of the JVMs of the HTTP task and all other tasks, respectively. The maximum heap size, as the name suggests, is the maximum size that the JVM’s heap can expand to. If after garbage collection the JVM calculates that it does not have enough memory to create an object without exceeding the maximum heap size, it throws an OutOfMemoryException. If XPages developer or server administrators notice that the Domino server is throwing OutOfMemoryExceptions regularly, the HTTPJVMMaxHeapSize variable should be the first area for investigation.

HTTPJVMMaxHeapSize Variable

This variable sets the maximum Java heap size to be used by the Domino server’s HTTP task. This INI variable passes its value through to the HTTP task’s JVM. This variable correlates directly with Java’s -Xmx vm argument. The value of this INI variable gets passed to the JVM as the value of the –Xmx vm argument. This setting was introduced in Domino 8.5.2 to allow administrators to set (in most cases) a higher heap limit for the JVM running within the HTTP task, and thus a higher heap limit for the XPages runtime.

In the past, it was typical to recommend setting a 64MB heap limit for all JVMs running on the Domino server (running on a 32-bit platform). With the introduction of XPages, it was quickly acknowledged that, for servers running several XPage applications simultaneously with many concurrent users, allocating more memory to the JVM serving the XPage applications was necessary. The initial recommendation prior to version 8.5.2 was to increase the JavaMaxHeapSize setting to accommodate the need for increased memory. However, increasing this setting for servers on 32-bit systems could cause them to run out of memory, as all JVMs (not just the HTTP task’s JVM) were running with this higher limit. A new solution was required, and two new INI variables resulted (HTTPJVMMaxHeapSize and HTTPJVMMaxHeapSizeSet).

For servers that have intensive XPage needs, it is now normal to recommend setting a maximum HTTP JVM heap size of 256MB (for 32-bit systems). A 1GB JVM maximum heap size is recommended for 64-bit systems. The task of identifying how much memory is enough memory to allocate as the maximum heap size is a delicate balancing act. If this number is too small, the performance of your XPages runtime will be negatively affected. Conversely, assigning a number that is too high adversely affects the performance of the entire system. Developers and system administrators should be wary of setting this value to an unreasonably high value for the system in question. If this variable is set too high, other applications running on the system will likely slow down and performance as a whole for the system will degrade. Users should be vigilant when changing this variable on the Notes client because it has a direct impact on the application’s memory footprint.

Sample usage:

HTTPJVMMaxHeapSize=256M

HTTPJVMMaxHeapSizeSet Variable

This variable notifies the HTTP task that the HTTPJVMMaxHeapSize setting has been specifically set and should not be programmatically overwritten. The HTTP task checks for the HTTPJVMMaxHeapSize variable each time the HTTP task starts. If the variable is not present, the HTTP task queries notes.ini for the JavaMaxHeapSize variable. If this variable is present, it assigns the value of JavaMaxHeapSize to HTTPJVMMaxHeapSize and sets HTTPJVMMaxHeapSizeSet to 1. If JavaMaxHeapSize is not present the HTTP task sets the value of HTTPJVMMaxHeapSize to 64MB for 32-bit systems and to 1GB for 64-bit systems, and sets HTTPJVMMaxHeapSizeSet to 1.

If HTTPJVMMaxHeapSize is set to less than 256MB on a 64-bit system, it is automatically reset to 256MB on HTTP startup and HTTPJVMMaxHeapSizeSet is set to 1.

Users should be vigilant when changing this variable on the Notes client because it has a direct impact on the memory footprint of the Notes client.

JavaMaxHeapSize Variable

Domino tasks that run Java programs require a JVM instance to execute the Java program. Until release 8.5.2, the JavaMaxHeapSize variable was responsible for controlling the maximum heap size for all JVMs running on the server. As of release 8.5.2, the HTTPJVMMaxHeapSize variable has responsibility for controlling the size of the heap of the HTTP task’s JVM. The JavaMaxHeapSize variable controls the maximum heap size of all other JVMs running on the server. The JavaMaxHeapSize variable is responsible for passing the -Xmx vm argument to all server JVMs (apart from HTTP’s JVM).

Because the JavaMaxHeapSize setting affects potentially multiple JVM instances and multiple tasks, the server must be restarted after changing the variable’s value. Users should be vigilant when changing this variable on the Notes client because it has a direct impact on the memory footprint of the Notes client.

Sample usage:

JavaMaxHeapSize=256M

JavaMinHeapSize Variable

This variable sets the minimum heap size for all JVMs running within the Domino server (and Notes client). The minimum heap size is the amount of memory initially set aside for the JVM. This variable is responsible for passing its value through to the JVM as the -Xms vm argument.

Users should think carefully before increasing this variable on the Notes client because it impacts the memory footprint of the client.

Sample usage:

JavaMinHeapSize=16M

JavaEnableDebug Variable

Chapter 6 discusses this variable in much greater detail. This variable signals to the Domino server that its JVM should be started in debug mode. Enabling this variable is the first step required when configuring the Domino server for remote debugging. In the following example the variable is set to a value of 1. This variable’s value acts like a Boolean flag, with 1 being true (or on) and 0 being false (or off).

Sample usage:

JavaEnableDebug=1

JavaDebugOptions Variable

Chapter 6 discusses this variable in much greater detail. This variable is used to pass debugger information, such as debug port numbers and debug transport protocol names, to the server’s JVMs.

Sample usage:

JavaDebugOptions=transport=dt_socket, server=y,suspend=n,address=8000

JavaUserClasses Variable

Setting the notes.ini parameter JavaUserClasses allows for a class to be loaded via the JVM system loader so that classes (and jars) can be shared across JVM instances. This variable is discussed in the section, “Enabling Extended Java Code with the java.policy File,” later in this chapter.

This section touched on a few of the more commonly used JVM vm arguments. However, literally dozens of arguments to the JVM are available. You can find a full list here: www.tinyurl.com/JVMLaunchOptions.

You likely will never need to use many of them, but having a reference to these arguments is worthwhile because some will prove useful in the long term.

OSGI_HTTP_DYNAMIC_BUNDLES Variable

The XPages APIs have been available since Domino 8.5.2. Through the use of the XPages extension APIs, customers can create their own extensions of the XPages runtime. Customers can create their own XPages artifacts, such as (but not limited to) XPage controls, converters, validators, and data sources.

Typically, these artifacts are packaged within OSGi bundles (plug-ins). The artifact creator distributes the OSGi bundles. Under normal circumstances, a server administrator is expected to install the OSGi bundles (via copy and paste) into a folder location within the Domino server.

Feedback from administrators and developers alike indicated that this method of bundle installation is not optimal, mainly because organizations are hesitant to place unsigned JAR files into their Domino server.

Domino 8.5.3 introduced the OSGI_HTTP_DYNAMIC_BUNDLES variable. This variable enables the bundle provider to place OSGi bundles within an update site database that can be signed and provided to the server administrator. The plug-in signer must be among the server’s list of individuals who can run unrestricted methods and operations. Those familiar with Domino server administration will understand that granting this level of authority to an individual or group should not be done without first ensuring that the signer is completely trusted. Allowing individuals or groups to run unrestricted in this manner implies that those listed have access to run agents or XPages that can access the underlying OS APIs.

The HTTP task automatically provisions (installs) the OSGi bundles from the database into the server, without the need for physically copying the bundles into the server (note that the update site database in question must be based on the version 8.5.3, or newer, update site template). The bundles at all times remain within the database, and the HTTP task is responsible for dynamically adding the bundles to the list of runtime OSGi bundles as the task is starting. As with any databases/code received from third parties, administrators should ensure that the update site databases are not malicious in nature before installing them on a production server. This model is recommended for use where an update site needs to be deployed across multiple servers. If OSGi bundles need to be installed on multiple servers in a cluster, administrators are advised to create an update site database (based on the 8.5.3 update site template). Administrators should next upload their OSGi bundles to the update site database. After the bundles are uploaded, a replica of the update site database should be created on each server where the bundles are to be installed. Finally, in the server’s Name and Address Book, a Configuration/Parameters document must be created with the OSGI_HTTP_DYNAMIC_BUNDLES INI variable set to the location of the update site database. Using this model ensures that the bundles are installed on each server where the update site database is replicated to. After the bundles are deployed, the HTTP task on each server must be restarted.

Figure 2.5 shows the update site database with an update site imported into the database. As you can see from the figure, multiple toolbar buttons within the database support the easy import of existing update sites.

Image

Figure 2.5. Notes 8.5.3 Eclipse update site database

Sample usage:

OSGI_HTTP_DYNAMIC_BUNDLES=update/extlibbundles.nsf,sbtbundles.nsf

XPagesPreload Variable

This feature, along with its XPagesPreloadDB sidekick, was introduced in Notes/Domino 8.5.3 to boost the initial startup time of XPages applications. When set to 1, the XPagesPreload variable causes the Notes/Domino Java class loader to load the XPages Java runtime classes when the client or server is starting up. Two distinct groups of classes are loaded:

• Java classes from the XPages runtime plug-ins (com.ibm.xsp.core and so on)

• The Java classes referenced in the *-faces-config.xml files in the core plug-ins (core-faces-config.xml, extsn-faces-config.xml, and so on)

The first group is loaded from a fixed list of runtime classes (465 objects total in version 8.5.3), not only from the core com.ibm.xsp.* plug-ins, but also from common utility classes, JavaScript wrapper classes, and underlying JSF runtime classes.

In the second instance, all the faces-config.xml files in the following core plug-ins are read and the classes declared within are loaded in a batch. These mostly consist of XPages control renderers, data sources, and complex types.

com.ibm.xsp.core

com.ibm.xsp.extsn

com.ibm.xsp.designer

com.ibm.xsp.domino

com.ibm.xsp.rcp

Note that com.ibm.xsp.rcp is a Notes client–only plug-in and that both groups of classes are loaded simultaneously on separate threads. Also, unless these preload variables are set in notes.ini, no XPages class loading of any description is performed before the first XPages application is opened in a given client or server session.

XPagesPreloadDB Variable

Whereas the XPagesPreload variable is concerned with loading critical pieces of the core runtime platform, XPagesPreloadDB is concerned with the application layer. The XPagesPreloadDB variable points to one or more NSF applications, which can be local to the client or server or on a remote server. Any nominated NSF can also include an optional XPages .xsp filename. The following sample notes.ini variable declaration includes an example of a local NSF that specifies an XSP page (ByAuthor.xsp) and an NSF on a remote server (bigIron) that does not:

XPagesPreloadDB=teamdisc.nsf/ByAuthor.xsp,bigIron!!expenseDb.nsf

In the normal course of events, when an end user from a browser loads an XPages application, the XPages runtime loads the NSF as a virtual web application module. The concept behind preloading is to load the web application module into memory at startup time in the same way it would occur normally if a real user had submitted an actual application load request. Thus, the XPages runtime fakes a real request for each argument in the XPagesPreloadDB comma-separated list. This means that an XPages URL is constructed for each argument and sent to the web application server. The web application server loads the application module, caches it, and renders back markup if an XPages file is specified. The XPages runtime simply throws away the response from the web application server, but the module has been loaded into memory and will be available instantly for the next real user request.

When and Why Is Preloading Important?

Preloading the runtime technology and/or XPages applications is important when initial application load time is a project requirement—in other words, preloading is important almost all the time! While the XPages preloading features work on both the Notes client and Domino server, it can be especially significant when an XPages application is run in the Notes client but the NSF itself resides on a remote Domino server. In this scenario, application startup performance can be slower than normal, depending on the load and latency of the network infrastructure on which the applications are deployed. To understand this fully, however, you need to quickly look at how XPages runs in the Notes client.

In a typical, albeit oversimplified, XPages web application scenario, a user makes a request for an XPage to a Domino server that responds by generating the XPages content and emitting the markup back to the user’s browser client. The same applies when running an XPages application in the Notes client, except that the Expeditor (XPD) web application server and (XULRunner) browser client are embedded in the client platform and thus are running on the local desktop computer. When running with a local client NSF application—say, a replica of an XPages web application that has been taken offline—this all runs the same as the typical web scenario and with a similar performance profile. Figure 2.6 summarizes the XPages client runtime model.

Image

Figure 2.6. XPages in the Notes client

However, when the NSF is not a local replica, but a file on a remote server, all the data displayed as content in the XPage must be fetched across the network from the remote server. This can result in numerous network transactions being carried out just to populate the XPage. On top of this, however, all the XPages and Custom Control design elements themselves must be fetched from the remote NSF to be executed in the local Notes web application server. In terms of performance optimization, network transactions should always be minimized because applications inevitably slow down due to the extra time required to complete network transactions (that is, over and above the time required to fulfill equivalent local disk access operations). On networks with high latency, the performance impact can be significantly exacerbated. Preloading an application ensures that any remote network activity required for application design artifacts is absolutely minimized by the time the end user first touches the application. It also ensures that the web container has been started in advance of the first user request, to eliminate overhead. Thus, the XSP preload INI variables can really help mitigate the performance issues outlined here.


Tip

Administrators can apply INI settings like this to many client computers in one fell swoop using a desktop policy settings document. The process is described in detail in this IBM support document: www.tinyurl.com/PushNotesIniSettings


Avoid Unnecessary Network Transactions in Your Application Code

Now that you understand the potential negative impact of network transactions on page loading when running a remote NSF application in the Notes client, it is important to apply this lesson to your own application code: In other words, do not fall into the same trap by loading application data inefficiently. A use case that we have encountered on more than one occasion with sample customer applications is highlighted here—avoid it at all costs. This example has to do with customizing views.

XPages makes it easy to access and display view data using container controls such as the View panel, Repeat control, or Data Table. These controls attach to a Domino view via a data source and display its content by iterating though the view entries, accessing the row data, and formatting it for display according to various design-time parameters. The controls offer the powerful capability of adding customized view columns to the output, which often transform back-end view data or compute new values based on Domino view data for display purposes. However, there are efficient and inefficient ways of customizing view column data. The egregious offender is the column value computation that uses Server Side JavaScript code to do something like this:

return rowData.getDocument().getItemValueString("Customer");

Here, rowData is the sample variable name parameter on the container control (that is, the name assigned to the var property) that gives access to the current row in the view as it is being read and rendered at runtime. When the page content is being built, the underlying document for the current view entry is opened and an item value is read from the document instance. This operation is repeated for every row displayed in the view control. In one particular real-world instance, a View control was configured with two custom columns, both of which opened the underlying document to extract item data, and the View control was configured to show 25 rows at a time. Thus, in one fell swoop, 50 extra and expensive network transactions had to be carried out for this page when this NSF was run as a remote application on the Notes client. Ouch!

When custom columns are required, it is always best to work with columns that are already defined in the back-end Domino view and then retrieve the column content for custom computation using the getColumnValue() API call on the NotesXspViewEntry JavaScript class. If the required column does not exist in the back-end Domino view, add it if you have sufficient design privilege, but do not open the underlying document to read the item and then have this bad practice repeated iteratively for every view entry to be displayed.

A simple example of a customized column is the concatenation of two back-end view column values into a single XPages View control column, formatted in a particular way. You can achieve such a custom value using Server Side JavaScript (in particular, by leveraging the aforementioned getColumnValue() API call) to extract the column data from the Domino view:

return "" + rowData.getColumnValue("Area") + ":" + rowData.getColumnValue("Customer");

Optimizing Client Memory Usage

Most of the usage scenarios outlined in this chapter deal with notes.ini variables and are of primary importance when used within the Domino server. However, a number of settings used on the Notes client can help configure the memory-management settings of the Notes client.

The Notes client is based on Eclipse since release 8.0. As a result, Notes requires a JVM to launch and run. The JVM that Notes uses is installed as a part of the Notes client and launches each time the Notes client is launched. The JVM is installed to the jvm folder, which is a child of the Notes program directory (for example C:Notesjvm).

The Notes JVM can be configured by modifying jvm.properties, which resides in <notes_program_directory>framework cpdeploy. Users should be careful when modifying the jvm.properties setting: Changing some settings can negatively impact the Notes client’s performance. It is advisable to keep a backup copy of jvm.properties before modifying it.

Similar to the notes.ini heap variables discussed previously, two Notes client jvm.properties attributes provide the same vm arguments to the Notes client’s JVM. Table 2.2 outlines both of those properties.

Table 2.2. Notes Client JVM Memory Management Properties

Image

Users should take note when modifying the value of these properties. If the user is confident that the system has enough overall system memory to support increasing the memory allocated to the Notes client, increasing the minimum and maximum JVM heap size for the Notes client can yield performance improvements for the Notes client.

vmarg.Xms

This property corresponds to the -Xms vm argument. The value of this property is passed to the JVM as the minimum heap size allowed for the JVM. Increasing this property leads to an increased initial heap size for the Notes client JVM.

vmarg.Xmx

This property corresponds to the -Xmx vm argument. The value of this property is passed to the Notes client’s JVM as the maximum heap size allowed for the JVM. Increasing this property allocates more memory to the Notes client JVM and, ultimately, the Notes client. Listing 2.2 shows how to set the minimum and maximum memory arguments via jvm.properties.

Listing 2.2. Sample Notes client jvm.properties Values


vmarg.Xmx=512m
vmarg.Xms=128m


Any variable can be passed into the Notes client’s JVM using jvm.properties. vm arguments are passed to the Notes client’s JVM using the vmarg.arg notation. The argument name succeeding the dot is passed directly to the Notes client’s JVM as in vmarg.Xnolinenumbers=-Xnolinenumbers.

Enabling Extended Java Code with the java.policy File

Another configuration file to know about is the java.policy file. The XPages Java Security Manager uses this file to determine what classes are trusted in the XPages runtime environment of the Notes client and Domino server. It is located in the jvmlibsecurity folder under the Notes/Domino root installation directory. The Notes client has an additional java.policy file in its root directory. This is done to support the Mac platform. The content of both files is effectively concatenated as one by the security manager on the Notes client. Listing 2.3 shows a snippet from the java.policy file on an 8.5.3 Domino server, with some lines highlighted for special attention.

Listing 2.3. Sample Snippet from a Domino Server java.policy Configuration File


// Standard extensions get all permissions by default

grant codeBase "file:${java.home}/lib/ext/*" {                           
     permission java.security.AllPermission;                             
};                                                                       

// default permissions granted to all domains

grant {
     // Allows any thread to stop itself using the java.lang.Thread.stop()
     // method that takes no argument.
     // Note that this permission is granted by default only to remain
     // backwards compatible.
     // It is strongly recommended that you either remove this permission
     // from this policy file or further restrict it to code sources
     // that you specify, because Thread.stop() is potentially unsafe.
     // See "http://java.sun.com/notes" for more information.
     permission java.lang.RuntimePermission "stopThread";

     // allows anyone to listen on un-privileged ports
     permission java.net.SocketPermission "localhost:1024-", "listen";

     // "standard" properies that can be read by anyone

     permission java.util.PropertyPermission "java.version", "read";
     permission java.util.PropertyPermission "java.vendor", "read";
     permission java.util.PropertyPermission "java.vendor.url", "read";
     "java.vm.specification.name", "read";
     permission java.util.PropertyPermission "java.vm.version", "read";
     // etc ...
     permission java.util.PropertyPermission "java.vm.vendor", "read";
     permission java.util.PropertyPermission "java.vm.name", "read";

     permission java.util.PropertyPermission "javax.realtime.version", "read";

};

// Notes java code gets all permissions

grant codeBase "file:${notes.binary}/*" {
     permission java.security.AllPermission;
};

grant codeBase "file:${notes.binary}/rjext/*" {
     permission java.security.AllPermission;
};

grant codeBase "file:${notes.binary}/ndext/*" {
     permission java.security.AllPermission;
};

grant codeBase "file:${notes.binary}/xsp/-" {                            
     permission java.security.AllPermission;                             
};                                                                       

grant codeBase "file:${notes.binary}/osgi/-" {
     permission java.security.AllPermission;
};


The first grant statement in Listing 2.3 declares that the security manager trusts any Java JAR files located in the jvmlibext folder under the root Notes/Domino directory. This means that you could drop your own custom Java libraries into this location, and they would be included in the class path and trusted by the security manager at runtime. This is not a recommended practice, however, because the location is intended for global system libraries; including private custom libraries there would pollute the model.

At the bottom of the listing are some other locations that are also granted all permissions by the security manager. Shaded in gray is the xsp subfolder; you can include your own custom Java libraries at this location (say, by including a JAR file in the xspshared folder). This is no longer a recommended practice, but it is still supported for historical reasons. You can also encapsulate your custom Java classes in a plug-in and place them in the OSGi location (the last entry in the listing), to ensure that your classes are successfully loaded. However, this is also not recommended because the upgrade installer removes everything under the osgi folder whenever the server is next upgraded. The recommended way is to deploy custom plug-ins in the workspace subfolder path under the server data directory (dominoworkspaceapplicationseclipseplugins). This location automatically inherits all Java 2 security settings of the OSGi directory, and contents are preserved in the event of an upgrade.

If you want to include custom Java code in an NSF and reuse it in other XPages applications, you must add a grant declaration, such as that shown in Listing 2.4.

Listing 2.4. A Grant Declaration for XPages Java Code Contained in an NSF Application


grant codeBase "xspnsf://server:0/xsp85code.nsf/-" {
 permission java.security.AllPermission;
};


The xspnsf protocol identifies the code source as coming from XPages in an NSF file. The server, port, and actual NSF file are then specified in the remaining part of the URL. You can refine the scope of the approved code source by further modifying the URL. For example, to allow only Java code called via Server Side JavaScript to execute, add a script path identifier. Listing 2.5 shows the modified grant declaration.

Listing 2.5. A Grant Declaration for XPages Java Called Via SSJS in an NSF Application


grant codeBase "xspnsf://server:0/xsp85code.nsf/script/-" {
 permission java.security.AllPermission;
};


Note also that some URLs are suffixed with an asterisk character (*), whereas others end with a hyphen (-). The former includes all files in the designated location; the latter is recursive, meaning it also includes any libraries found in subfolders of the location.

The other entries in the java.policy file may be vaguely interesting to you. For example, you can see where the other standard Java components, such as Notes/Domino extensions (ndext), are declared. There is also a collection of individual permission declarations:

permission java.util.PropertyPermission "java.version", "read";

This simply means that anyone is allowed to read the version of Java running on Notes/Domino. The other individual statements are equally straightforward.

Finally, custom libraries can also be included in the Java class path using the JavaUserClasses INI variable.

JavaUserClasses

This setting existed long before the advent of XPages in Notes /Domino 8.5, but it is still effective today as a directive to include custom or third-party libraries in the class path. The example included in Listing 2.1 shows how to add a JAR file or a file path location to the class path:

JavaUserClasses=D:jdbcutilsjdbcdrivers.jar;D:javacustomlibs

The list of JARs, ZIPs, or path locations is ultimately limited to 255 characters. This can be an issue when third-party libraries are installed into long-winded file system paths, but there are workarounds for this limitation. One solution is provided by way of another INI variable, named JavaUserClassesExt, that was introduced subsequently to perform the same function but is designed to accept a list of tags instead of a list of literal resources. Listing 2.6 shows an example.

Listing 2.6. A notes.ini Snippet Showing JavaUserClassesExt and Related Tags


JavaUserClassesExt=ibm,json
ibm=C:IBMfinancelib.jar
json=D:utilsjsonlib.jar
};


Note that the XPages Java Security Manager does not trust any Java class files added to the class path in this way. That is, the class files may be loaded, but any attempt to perform protected operations will be denied. You can use the AccessController.doPrivileged action if you need to add privileged operations to your custom Java code. Listing 2.7 shows a simple example of this.

Listing 2.7. A Simple Code Snippet That Calls Third-Party Java Code Via Server Side JavaScript in XPages


String getUserNameProtected() {
   String user = (String) AccessController.doPrivileged(
      new PrivilegedAction() {
         public Object run() {
            return System.getProperty("user.name");
            }
         }
      );
    return user;
}


If you want to experiment with extending the Domino class path, setting up a minimal test case is easy. For example, take a third-party standalone Java library, such as the Apache Commons BeanUtils, and install the JAR in one of the aforementioned jar locations, or put it in a private folder and add it to the class path using the JavaUserClasses setting. On an XPage, you can attach some Server Side JavaScript to a button such as the one shown in Listing 2.8.

Listing 2.8. A Simple Code Snippet That Calls Third-Party Java Code Via Server Side JavaScript in XPages


<xp:button value="Label" id="button1">
      <xp:eventHandler event="onclick" submit="true"
         refreshMode="complete">
            <xp:this.action><![CDATA[#{javascript:
// Instantiate the array stack, add an entry and print it out
var as = new org.apache.commons.collections.ArrayStack();
as.push("foo");
println(as.size());
println(as.get());}]]>
             </xp:this.action>
      </xp:eventHandler>
</xp:button>
println(as.get());


Clicking the button in the XPage on a web browser at runtime causes the array size (1) and array content (foo) to be printed on the server console if the Apache Commons BeanUtils library is properly loaded.

Conclusion

In this chapter, you explored some core Notes/Domino configuration files (namely notes.ini, jvm.properties, and java.policy) and saw how the variable settings can control many aspects of behavior of the XPages runtime on the Notes client and Domino server. These settings mostly serve as XPages debugging, performance, and extensibility aids. Hopefully, you found some nuggets that you can apply to solve or simplify problems you have encountered in your everyday XPages application development adventures.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.186.6