During Java development for PI, relatively common requirement is to use some classes of the library that has already been deployed to J2EE stack of the PI system. Few common examples here are adapter modules, Java mapping programs and user-defined functions development. In some cases, it is unclear which resource file (e.g. JAR file) contains the required class and the question that the developer faces is how to find out the respective resource file. This is also one of questions that are asked from time to time on SCN forums with respect to various (mostly SAP standard) Java classes in PI area.
Recently William Li has described on of solutions for this problem in his blog ( http://scn.sap.com/community/pi-and-soa-middleware/blog/2012/10/11/how-to-find-java-library-during-pi-development ). The approach that was described in that blog is to automatically generate a map of JAR files and classes that are available in each of these files using the prepared batch file. As a result, usage of lookup function over this locally available map/list can help in solving the original problem.
Yet another alternative to this solution is usage of information available from Java classloaders – and it will be briefly discussed in this blog.
Advantages of this approach are:
- No preliminary actions (e.g. copying files from PI application server, executing scripts) are required;
- Received result is up-to-date and there is no need to periodically update source list that is used for lookups after PI system updates that can potentially bring new classes (e.g. after applying Support Package).
Together with advantages, there are some disadvantages that should be mentioned here and taken into account:
- Connection to the PI system is required – thus, the approach will not work offline (e.g. if the PI system isn’t reachable);
- AS Java Telnet access to the PI system is required.
As a part of AS Java Telnet commands set, SAP provides a standard command named LLR. The primary goal of this command is to provide information about classloaders, loaded resources, parent-child relations. The command LLR has already been described by Emil Dinchev in his blog ( http://scn.sap.com/people/emil.dinchev/blog/2011/10/19/troubleshooting-noclassdeffounderror-on-netweaver-730 ). That time, focus was on analyzing exception java.lang.NoClassDefFoundError and the command LLR was used as a part of root cause analysis activities for this exception.
For the particular enquiry that it discussed in the bounds of this blog, following command parameters can be used to achieve the looked outcome:
llr –all –f <fully qualified class name>
Parameter –all instructs that search will be conducted in both system classloaders and classloaders that were registered in SAP J2EE Class Loader Manager.
Parameter –f instructs that the resource of the loaded class should be attempted to be reached.
<fully qualified class name> is the name of the searched class supplemented with package name and extension ‘.class’. Please note that sub-package names should be delimited with slash (/) and not dot (.) here.
For example, we would like to figure out which JAR file we should import to the Java project in order to be able to perform operations over trace of the message (e.g. insert trace entries) from the custom developed mapping program. The respective class reflecting trace object is com.sap.aii.mapping.api.AbstractTrace. Knowing this, we execute command LLR with following parameters:
llr -all -f com/sap/aii/mapping/api/AbstractTrace.class
As a result, following response will be received in a Telnet session:
As it can be seen, JAR file name and full path to it (highlighted in the listing below) are indicated in the output:
Another example: let’s say we are developing a custom adapter module and would like to implement functions that will enrich audit log of the processed message with adapter module specific data (add custom audit log entries with information/warnings about adapter module execution). The class used for these purposes is com.sap.aii.af.service.auditlog.Audit – thus we execute the command:
llr -all -f com/sap/aii/af/service/auditlog/Audit.class
… and receive the resource JAR file containing this class:
Besides SAP standard classes, the described approach can be used to search for any other (e.g. 3rd party or custom developed) classes that have been loaded into AS Java of PI.
Example: retrieve location of JMS library (e.g. looking for connection factory class) of the deployed Apache ActiveMQ JMS Provider that is used in some JMS scenario.
llr -all -f org/apache/activemq/ActiveMQConnectionFactory.class
One more example: retrieve location of JAR file containing custom developed adapter module AdapterModuleGenericTest (contained in the package vadim.adapter.module) that has been developed and deployed earlier.
llr -all -f vadim/adapter/module/AdapterModuleGenericTest.class