Calling Java classes from AME

Modifying a resource model's decision tree script to call Java classes

The Autonomic Management Engine, a primary component of the IBM® Autonomic Computing Toolkit, allows the use of JavaScript to define decision tree scripts that can be used for analysis, planning, and so on. Given that Java code is more powerful than JavaScript, it might be preferable to use Java code for creating the analysis components, whereas JavaScript might be suitable when simpler functionality is required. This article shows you how to call Java classes from the decision tree scripts as well as the associated setup. It also provides some guidance on issues that can potentially cause your decision tree scripts to fail and hints on what you can do to smoothly integrate Java code with the decision tree script.

Neeraj Joshi (jneeraj@us.ibm.com), Staff software engineer, IBM

Neeraj JoshiNeeraj Joshi works as a staff software engineer in the Autonomic Computing Division of IBM. He has a master's degree in computer science from North Carolina State University. He can be reached at jneeraj@us.ibm.com.



Balan Subramanian (bsubram@us.ibm.com), Staff software engineer, IBM

Balan SubramanianBalan Subramanian enjoys working as a Staff Software Engineer in the Autonomic Computing group at IBM in Research Triangle Park, NC, focusing on data collection, problem determination, and provisioning. His other interests include Web services, grid services, and pervasive computing. A Sun Certified Java Programmer, Balan received his master's degree in computer science from George Mason University in 2000 with a thesis on Web services performance. He was also a core developer on the IBM Generic Log Adapter for Autonomic Computing and as a development co-op on the AUIML toolkit. He has previously worked at IBM India. He can reached at bsubram@us.ibm.com.



Brad Topol (btopal@us.ibm.com), Software Engineer, IBM

Brad Topol Brad Topol is a senior software engineer in the WebSphere Advanced Technology group. Currently, he is actively involved in advanced technology projects in the areas of transcoding, distributed systems, networking, and graphical user interfaces. Brad can be reached at btopol@us.ibm.com.



22 June 2004

Introduction

The Autonomic Management Engine, provided in the Autonomic Computing Toolkit, allows much of the analysis and correlation required for autonomic managers to be performed using scripts written in JavaScript. While writing the actual script itself is quite easy using the Resource Model Builder, JavaScript has some limitations that curtail the amount of work you can accomplish within the Autonomic Management Engine without making it tedious to write scripts.

In general, the Java language provides more powerful constructs than JavaScript, and it might also be that much of the work to be done by the autonomic manager is in different components that have already been developed. In many cases, it is more efficient to make call outs to multiple components (one for analysis, one for planning, and so on) rather than try and contain all this functionality within a single decision tree script. This article walks you through the process of creating resource models that call Java source code.

In this article, we will modify the decision tree script that is part of the resource model created in Creating a simple resource model for processing Common Base Events from a file and add script fragments that call Java code. To illustrate this, we will create Java code to parse Common Base Events using utility classes from the Hyades Common Base Event implementation and code to correlate Common Base Events using a state-based approach.


Prerequisites

This article assumes you have installed the Resource Model Builder, the Autonomic Management Engine, and the Generic Log Adapter for Autonomic Computing, all available as part of the Autonomic Computing Toolkit (see Resources). It also assumes that you know how to build resource models using the Resource Model Builder, how to deploy the resource models, and how to start the autonomic management engine. If not, take a look at the developerWorks article Creating a simple resource model for processing Common Base Events from a file, which shows you how to do all of these tasks. Also, you must install the Problem Determination Scenario from the Autonomic Computing Toolkit to obtain the CanonicalSituationMonitor.zip file contained in the scenario. Because all you need from the scenario is the zip file CanonicalSituationMonitor.zip, use the do not check prerequisites option when you install the scenario. Information on how to download these components can be found in Resources.


Editing a resource model’s decision tree script to call batch files

To begin, look at how batch files and shell commands can be called from decision tree scripts in a resource model. If you followed the instructions in the referenced article, your resource model builder should now look like Figure 1 (when the source panel is selected).

Figure 1. Resource Model Builder with basic decision tree script
Resource Model Builder with basic decision tree script

Within a decision tree script, you can use the Svc.ShellCmd to execute any shell command by providing the shell command to be executed as a string argument.

Listing 1. Using Svc.ShellCmd
Svc.ShellCmd(“echo Hello World >> c:\\trial.log");

This adds the string “Hello World" to the trial.log file (note the use of \\ before the file name). To try this, scroll down to the visitTree function in the decision tree script source panel and add the code shown in Listing 1 immediately following the variable definitions. Next, deploy and start the resource model. The trial.log file is created in the specified path and statements are added to it for each cycle. If no path is specified and only the file name is provided, the file is created by default in the same directory from which you ran sara.bat. Figure 2 shows the decision tree script with the Svc.ShellCmd in the visitTree function.

Figure 2. Resource Model Builder with decision tree script containing call to a shell command
Decision Tree Script containing call to a shell command

Similarly, any batch file can be called using the Svc.ShellCmd function. If the output of the shell command/batch file goes to the console (StdOut), you cannot see the output when the batch file/shell command is called from inside the decision tree script when the resource model is executing with a running AME instance. However, the output is placed in the trace.log file of AME (in the sara\logs subdirectory found within the AME run time installation directory). Figure 3 shows how the trace.log file would look if we had used echo Hello World as the string parameter for the function call in Listing 1. The return value of the shell command or batch file execution is returned when Svc.ShellCmd is called and can be stored in a variable. However, note that this is the return value of the execution and usually not the actual output of the shell command or batch file unless the output is explicitly returned by the shell command or batch file.

Figure 3. trace.log file showing output of shell command called from the decision tree script
trace.log file with output of shell command execution

Creating the Java class for parsing Common Base Event strings

The resource model under consideration reads in as strings Common Base Events from the specified log file. So that different fields can be addressed and accessed using regular member references, it helps if you parse these strings into Common Base Event objects. The Hyades Common Base Event implementation provides utility functions to parse Common Base Event strings into Common Base Event objects. To create this code, you can use any IDE or compiler; we use WebSphere® Studio Application Developer (Application Developer) to create for parsing the Java code that will be called from the decision tree script. Ultimately, the code needs to reside within a JAR file.

It is important to note that the class to be called cannot be in the default package; it must have a package defined explicitly. Also, make sure that your Java code does not cause abnormal program termination (for example, System.exit).

The code shown in Figure 4 takes in a string and parses it into a Common Base Event. To compile it successfully, you need a two JAR files: hlevents.jar and hlcore.jar. Make sure that these are included in the list of JAR files used for the build. You can find both of these files in the lib folder within the Generic Log Adapter installation folder.

Figure 4. Application Developer window showing Java code for parsing Common Base Event strings
Application Developer window showing Java class for parsing Common Base Event strings

Next, we create a JAR file that contains the compiled code. This is accomplished in Application Developer by exporting into a JAR file. We call this JAR file custom.jar. Save this JAR file together with hlevents.jar and hlcore.jar.


Editing the resource model’s decision tree script to call Java classes

You must import the classes into the resource model before the decision tree script can use them. To import any package into the decision tree script, use the ImportPackage function, which takes the package name to be imported as a string argument. Place this function call at the top of the decision tree script before the variable definition section. To import custom packages (packages that are not part of the core packages that come with the Java Runtime Environment [JRE]), you must prefix the actual package name with Packages. Listing 2 shows the function call to import the java.util package and the function to import the code for parsing the Common Base Events.

Listing 2. Function calls to import java.util package
ImportPackage(java.util);		// import package from Java Runtime Libraries
ImportPackage(Packages.com.ibm.dw.ame);	// import custom package

Note that you do not have to add the .* at the end of the package specification as you would in the Java language.

Figure 5. Decision tree script with importPackage to import custom class files
RMB window with decision tree script that imports custom packages

Next, to create an object of a class in the imported package, create a JavaScript variable and initialize it with a new object instantiation of the class.

Figure 6. Decision tree script showing Java object instantiation
RMB window with decision tree script showing instantiation of a Java class

You can now call methods on the defined JavaScript variable. In this example, you need to parse Common Base Events as they are read in. Change the visitTree function as shown in Figure 7 to call the parser when each Common Base Event string is processed.

Figure 7. Decision tree script showing modified visitTree function
RMB window with decision tree script showing modified visitTree function

Things to remember

  • Java-like package names: You do not need to provide a .* at end of the package name provided as an argument to the ImportPackage function call. In fact, doing so throws an exception when trying to create an instance of the resource model using the mkrminstance command at the sara command line

  • Double quotes in package names: Do not enclose the package name within double quotes. This also throws an exception when trying to create an instance of the resource model

  • Object instantiation: Make sure that when instantiating an object of a class, the object name does not match the class name. While this is valid in Java code, it throws an exception when used in JavaScript. For example, the following code does not work. An exception is thrown when making an instance of the resource model.
    var CBEParser = new CBEParser();
  • Importing indirectly referenced classes: There is no need to import classes that are not explicitly used in variable declaration or object instantiations. For example, the getCBEObj method of the CBEParser class returns an object of type ICommonBaseEvent. However, there is no need to import the package containing the ICommonBaseEvent explicitly with an ImportPackage function call.

  • System.out in Java code: System.out calls are routed to the sara.bat console. The output of the sara.bat file and the System.out calls might overlap. Note than in the case of calling batch files or shell commands, console output was redirected to the Autonomic Management Engine's trace file (trace.log). You can try this by introducing a call to the printIt method of the CBEParser class; it prints the provided message with a timestamp prefixed to it.

  • System Calls: Care must be taken when writing the Java code that will be called from the decision tree script. Certain Java system calls can cause the Autonomic Management Engine to shut down. However, other Java system calls, like File I/O, are invaluable additions not easily available using JavaScript.

  • Exceptions thrown from the Java class: If uncaught exceptions are thrown at run time, or your Java class contains explicit throws of run time exceptions, AME logs the exception in the trace.log file as an Error and discards processing of the decision tree script. So, in this example, if when reading each of the Common Base Events and processing them through the Java class, an exception is thrown, the entire processing stops and no more Common Base Events are read in. Therefore, it is important that your Java class has proper exception handling built into it. In the example, CBEParser class, the tryException method always throws an exception that is caught by AME and logged in the trace.log file, after which execution of the decision tree script is halted. You can try this by placing this method call in different places within the visitTree function in the decision tree script and looking at the trace.log file to see how far along the script AME continued processing until it caught the exception and stopped processing.

  • Time consuming method calls: All method calls from the decision tree script execute in a blocking manner. So, if the method call takes some time to complete or if it is threaded, the decision tree script processing is suspended until the call returns. This is important because even if you have set the refresh interval for say x seconds ( requiring visitTree to be called every x seconds), if during the execution of the visitTree function there is a method call that takes y seconds to return, if y > x, then the refresh interval effectively becomes greater than x (the exact value is not y always and is not deterministic). You must make sure that your methods return as quickly as possible, and that the refresh interval is set at a value that is a true indication of what the refresh interval will be in the worst case when a method call takes a while to complete. You can accomplish this by studying the return times of the methods that might be called and determining the best indicative refresh interval.

  • Threading: You can create threads in the methods being called, but you must create a way to capture the results returned by the thread. If the method being called creates a thread and executes a join() operation on the thread before returning, then you only need to be aware of the previous issue with time consuming method calls. However, if the thread is created and the method call returns, the decision tree script no longer has a handle to the thread and cannot receive the results of processing performed by the thread. In this case, either the calling method must return the thread handle to the decision tree script so that it can be queried later for completion and availability of the results, or there must be some other method call in the class that can provide the results of the processing. The former tightly couples the decision tree script with the thread, which might not be wanted because the thread is, in effect, created by the other class. Such an alternative might be required even when you do want to perform asynchronous method calls. For example, consider that the analysis is performed by an external component (set of Java classes) and the analysis requires multiple Common Base Events. In each cycle, the AME reads new Common Base Events and sends them to the analysis component, which returns immediately. The results of the analysis can be retrieved from the analysis component through another method call. Therefore, in each iteration, the decision tree script must make a call to the analysis component to see if the results are available.

  • Static methods: Static methods can be called by specifying the class name after the class has been imported using the mechanisms described above (it is not necessary to have created objects of these classes). Static members of a Java class can also be accessed provided they are explicitly defined as public (default does not work and throws an exception that stops processing of the decision tree script). main methods can be called and JavaScript arrays can be passed as arguments, but null might also be passed as a parameter, which might lead to some issues if proper exception handling is not built in the main methods.


Modifications to sara.bat

The AME run time needs to know where the JAR files that contain classes referenced from decision tree scripts are. Modify the sara.bat file and add the hlevents.jar, hlcore.jar, and custom.jar to the classpath used by the AME run time. Assume that these jar files are in the c:\autonomic subdirectory.

Open the sara.bat file in any editor and scroll down to the last occurrence of SET CLASSPATH=……. .

Add another line with SET CLASSPATH = %CLASSPATH%; c:\autonomic\hlevents.jar; c:\autonomic\hlcore.jar; c:\autonomic\custom.jar.

Alternately, you can put the JAR files in the lib of the AME run time installation; these JAR files are then automatically picked up. However, note that all the required JAR files must be placed together in this folder. For example, if only the custom.jar file is put in this folder, even if the other location of hlcore.jar and hlevents.jar is specified in the sara.bat file, an exception is thrown because AME will look for the other two JAR files in the same folder as custom.jar. Also, this folder takes priority over any others specified in the sara.bat file. Therefore, if version 1 of custom.jar is present in this folder and version 2 of custom.jar is elsewhere, but specified using SET CLASSPATH in the sara.bat file, version 1 is always used.

The second method suggested above is recommended; some operating systems have problems with long values for environment variables (such as CLASSPATH) and might ignore JAR files specified toward the end (assuming JAR files are appended to the end of the current CLASSPATH). This becomes a very real problem when the JAR files are present in a deeply nested folder structure.


Conclusion

In this article, you have learned how to call Java classes from the decision tree scripts as well as the associated setup. You have also been given some guidance on issues that can potentially cause your decision tree scripts to fail and hints on what you can do to smoothly integrate Java code with the decision tree script.


Download

DescriptionNameSize
Code sampleac-amejava.zip---

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Tivoli (service management) on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Tivoli
ArticleID=10040
ArticleTitle=Calling Java classes from AME
publish-date=06222004