Programming considerations for resettable JVMs

When you are developing Java applications to run in a resettable JVM, you need to ensure that the programs do not perform unresettable actions or leave cross-heap references in the JVM. In a resettable JVM, if an unresettable event (caused by an unresettable action or by a cross-heap reference still in scope) is recorded, the JVM is destroyed and cannot be reused, so CICS incurs the CPU cost of initializing a new JVM.

Unresettable actions are listed in the document Persistent Reusable Java Virtual Machine User's Guide, SC34-6201. You should log the unresettable actions and cross-heap references during the development process in order to identify and eliminate them.

To log unresettable actions and cross-heap references during testing of your Java programs, include the system properties listed below in the JVM properties file for the JVM that you are using. There is also one option to be included in the JVM profile. The CICS® System Definition Guide has more detailed information about each of these system properties. In particular, note that when you include some of these system properties in the JVM properties file with any value, the function is enabled. To disable the function, you need to comment out or remove the system property; there is no value you can specify for the system property that disables the function.
ibm.jvm.events.output={event.log | path | stderr | stdout}
This system property enables event logging in the JVM, and it must be specified in order to enable the other system properties related to event logging. The CICS-supplied sample JVM properties file dfjjvmpr.props specifies the file event.log, which is created in the directory defined by the WORK_DIR option in the JVM profile. You can also store the text records describing the events in a HFS file of your choice, or in the stderr or stdout file for the JVM. Bear in mind that the output from multiple JVMs will be interleaved in the file event.log, or in a HFS file that you have chosen, or in the stderr or stdout files if only one file is used. If you are only obtaining output from a single JVM, you can specify a single file for this system property. If you are obtaining output from multiple JVMs, you should specify stderr or stdout, and also ensure that the -generate option is used for the STDERR or STDOUT option in the JVM profile, to generate a separate output file for each JVM. Alternatively, if you specify stderr or stdout, you can use the USEROUTPUTCLASS option in the JVM profile to redirect the output to another destination of your choice and add headers to it (see Redirecting JVM output).
ibm.jvm.unresettable.events.level={max | min}
This system property specifically enables the logging of unresettable events (caused by an unresettable action or by a cross-heap reference still in scope), and sets the level of logging required. Specifying min produces a list of reason codes that define the unresettable events found, and specifying max produces the reason codes and also a stack trace where appropriate.
ibm.jvm.crossheap.events=on
This system property specifically enables the logging of cross-heap references. Cross-heap references are references between the middleware heap and the transient heap in the JVM. They are logged to the event output destination at the time that each reference is created. The log entry includes a full stack trace to identify the line of code that created the cross-heap reference.

Most of the cross-heap references that are logged will be removed before the JVM is reset, through the normal actions of the CICS and JVM code, and through any actions that your application takes for this purpose. However, if any cross-heap references are not removed before the JVM is reset, they cause the JVM to perform a trace-for-unresettability check. Any references that are found to be in live objects trigger unresettable events, which cause the JVM to be marked as unresettable and destroyed. Any references that are found to be in unreferenced middleware heap objects (garbage) are reported as reset trace events, which do not cause the JVM to be destroyed, but have still wasted processor time by causing the trace-for-unresettability check. You should therefore ensure that all cross-heap references created by your applications are removed from the JVM before it is reset.

ibm.jvm.resettrace.events=on
This system property specifically enables the logging of reset trace events. Reset trace events are caused by cross-heap references that are still present in out-of-scope JVM objects (garbage) in the JVM at reset time. (If the cross-heap reference is still in scope, it causes an unresettable event.) Reset trace events do not cause the JVM to be marked as unresettable and destroyed, but you should still eliminate the cross-heap references that caused them, because the trace-for-unresettability check that is required for these cross-heap references reduces the performance of the JVM.
java.compiler=NONE
The activities of the Java just-in-time (JIT) compiler can interfere with the logging of unresettable events, reset trace events and cross-heap events. During the development process, specify the system property java.compiler=NONE (the word NONE must be in upper case) in the JVM properties file to turn off the JIT compiler for the JVM. Remember to turn the JIT compiler back on when you have finished investigating unresettable events, reset trace events and cross-heap events in your application.
Use the information from the output in your event log to eliminate the causes of unresettable events and reset trace events from your Java programs. The following example shows an unresettable event in an event log:
[EVENT 0xa]
TIME=30/08/2003 at 15:14:33.107
THREAD=EXAMPLE.TASK100.SAMP (0:22c8abf0)
CLASS=UnresettableEvent
DESCRIPTION=Attempt to load a native library in untrusted code
STACK=
     JAVA STACK TRACE
[END EVENT]
In this example, the reason code for the unresettable event is 0xa. The meaning of the reason codes for unresettable events can be found in Appendix A of the document Persistent Reusable Java Virtual Machine User's Guide, SC34-6201.

Where an unresettable event is caused by an unresettable action, rewrite your application code to remove the unresettable action. Your Java programs should not perform unresettable actions when they are used in a production environment. If a program absolutely has to perform unresettable actions, you should run it in a single-use JVM instead (see Single-use JVMs (REUSE=NO)).

Where an unresettable event or a reset trace event is caused by a cross-heap reference, you can use the memory location listed for the event to identify the cross-heap reference recorded in the event log which is responsible for triggering the event. You can then use the stack trace associated with the cross-heap reference to help you to fix the problem. The document Persistent Reusable Java Virtual Machine User's Guide, SC34-6201, has more information about debugging reset trace events. You might have to perform compensatory actions in application code to cause a cross-heap reference to be removed, which could include closing files or streams, emptying collections, or other kinds of clean-up activity. If you cannot remove the cross-heap reference in application code, consider contacting your IBM support representative for further advice.

Invocations of Java programs that run in a resettable JVM are completely isolated from subsequent invocations of programs in the same JVM. This means that the programs cannot pass on state to subsequent invocations.