This Insight article presents the basic
and straight forward steps to integrating JXInsight
with
Spring based applications. One of the key features
of the Spring framework is its AOP support which
allows users to implement custom aspects, complementing
their use of OOP with AOP. The JXInsight Spring
trace extension provides a plug-in replacement
for the basic performance and debugging interceptors
distributed with the Spring libraries. The JXInsight
TraceInterceptor (
com.jinspired.jxinsight.trace.ext.spring.TraceInterceptor)
provides high resolution clock counters, JVM
statistics including GC time, CPU time, object
allocations, thread blocking and waiting per
trace interval as well as call stack inspection
and classification and integration into the
award winning JXInsight console.
Sample Application
I have chosen the Spring JPetStore sample application
for the basis of this article. The following
is an extract from readme.txt file within the
sample application which is shipped with the
Spring Framework distribution.
"The Spring JPetStore is an adapted
version of Clinton Begin's JPetStore.
It leverages Spring's support for the iBATIS
SQL Maps to improve the original JPetStore in
terms of internal structure and wiring. On top
of a Spring-managed middle tier, it offers two
alternative web tier implementations: one using
Spring's web MVC plus JSTL, and one using Struts
1.1 plus JSTL."
| IMPORTANT
NOTE
Before
integrating JXInsight the JPetStore application
should have already being deployed and
tested to ensure that everything is
configured, built and running correctly.
In this article the database back end
used is Hypersonic SQL DB.
|
Integration Steps
Step 1 - Integrate JXInsight JDBInsight
Transaction Analysis. This is an
optional step.
Change the jdbc.properties file located in samples/jpetstore/war/WEB-INF.
Before
jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://localhost:9002
jdbc.username=sa
jdbc.password=
After
jdbc.driverClassName=
com.jinspired.jdbinsight.drivers.jdbc1x.Driver
jdbc.url=jdbc
:jdbinsight:hsqldb:hsql://localhost:9002
jdbc.username=sa
jdbc.password=
Step 2 - Integrate JXInsight
Spring TraceInterceptor
Change the applicationContext.xml file located
in samples/jpetstore/war/WEB-INF.
Before
<!-- Transactional proxy for the JPetStore
primary business object -->
<bean id="petStore" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref
bean="transactionManager"/></property>
<property name="target"><ref
local="petStoreTarget"/></property>
<property name="transactionAttributes">
<props>
<prop
key="insert*">PROPAGATION_REQUIRED</prop>
<prop
key="update*">PROPAGATION_REQUIRED</prop>
<prop
key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
...
</bean>
After
<bean
id="jxinsight" class="com.jinspired.jxinsight.trace.ext.spring.TraceInterceptor"/>
<!-- Transactional proxy for the JPetStore
primary business object -->
<bean id="petStore" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref
bean="transactionManager"/></property>
<property name="target"><ref
local="petStoreTarget"/></property>
<property name="transactionAttributes">
<props>
<prop
key="insert*">PROPAGATION_REQUIRED</prop>
<prop
key="update*">PROPAGATION_REQUIRED</prop>
<prop
key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
<property
name="preInterceptors">
<list>
<ref
bean="jxinsight"/>
</list>
</property>
...
</bean>
Step 3 - Integrate JXInsight
Servlet Trace Extension (ServletFilter)
The following was inserted into the Spring JPetStore
web.xml file before the first servlet entry.
<filter>
<filter-name>jxinsight</filter-name>
<filter-class>com.jinspired.jdbinsight.trace.ext.servlet.TraceFilter</filter-class>
<init-param>
<param-name>trace.identifiers</param-name>
<param-value>${servlet.protocol},${servlet.method},${servlet.url}</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>jxinsight</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
| IMPORTANT
NOTE
Some
web containers support a global web.xml file where the above changes can be
inserted and applied to all deployed
web applications. |
Step 4 - Add JXInsight
Spring Trace Extension Library To WEB-INF/lib
distribution
If you are rebuilding the JPetStore web archive
with the supplied build.xml then insert the
following fileset element into the
copy task within the
build target. The jxinsight-ext-spring.jar
must be placed in the WEB-INF/lib directory
within the generated war file.
<fileset dir="${jxinsight.root}/lib">
<include name="jxinsight-ext-spring.jar"/>
</fileset>
The ant build scripts can now be executed.
Note: It is also possible to apply the previous
steps post the building of the web archive by
manually updating the web archive itself making
sure to add the jxinsight trace extension library
into the WEB-INF/lib directory within the file.
Step 5 - Add JXInsight
JVMPI Agent, Core Libraries and J2EE/JDBC Extensions
to Application Server Classpath
| IMPORTANT
NOTE
The Borland Enterprise Server platform was used to deploy the web
application. The installation steps
are similar across most J2EE platforms.
Please consult the install guide and
the various integration guides for additional
platform specific instructions.
|
There are 3 additional Java libraries which
must be added to the application server's classpath.
These are
jxinsight-core.jar,
jxinsight-jdbc-drivers.jar and
jxinsight-ext-j2ee.jar.
For BES the jxinsight-ext-vbj.jar was also added.
To place them on partition's classpath the libraries
where placed in the directory:
<BES-INSTALL-ROOT>\var\servers\<HOSTNAME>\partitions\standard\lib\system
The following JVM startup parameter
was added to the partitions server configuration
file. The v=t is a required Borland VisiBroker
flag.
vmparam -Xrunjdbinsight:v=t
Step 6 - Startup the
Database Server, Application Server and Browser
The HSQLDB server database engine process
should be started configured with the JPetStore
DB files. The Borland Application should be
restarted after deploying the jpetstore.war
file. Navigate to the url
http://localhost:8080/jpetstore/index.html.
The following front page should now be displayed.
Perform some operations within the application
to warm up the application creating traces and
transaction paths.
| IMPORTANT
NOTE
The
JXInsight embedded profile server will
intially incurr a larger overhead than
normal (5%) during its JVM model building
phase. After most entry points have
been visited the JXInsight server will
utilize its internal fast access cached
data structures.
|
Step 7- The JXInsight Console
Start the JXInsight Management Console.
Mount a JXInsight server (monitored JVM process)
via the console menu command sequence: File->Mount
Server. Enter the host name
(localhost) and port number (default
1515). The console should automatically
connect and retrieve the metric snapshot.
Switch the analysis mode to Profile.
The Transactions perspective is activated within the console's
view system. The blue icon in the callstack
column represents a web bean (Servlets/JSP).
The green (olive) icon in the trace stack
column represents a Spring bean trace.
Switching to the Traces perspective presents the following analysis
view.
In both tables views time values are
reported in microseconds for clock time, cpu
time, thread monitoring waiting/blocking,
and GC. Object allocations are reported in
byte sizes (GB, MB, KB, Bytes).
Advanced Configuration
JXInsight's Spring Trace extension can
be configured to separate a single trace event
into multiple trace stack entries. By default
the extension creates the following trace
stack entries, ${type}=value, for each traced
method invocations.
${spring.bean.classname}=<classname without
package>
${spring.bean.operation}=<method.name>
This can be changed globally via the system
property with trace identifiers delimited
by a comma:
-Djxinsight.server.tracer.ext.spring.bean.trace.identifiers=${spring.bean.classname},${spring.bean.operation}
${spring.bean.codesource}
${spring.bean.package}
${spring.bean.classname}
${spring.bean.fullclassname}
${spring.bean.operation}
${spring.bean.method}
${spring.bean.signature}
${trace.timestamp}
The TraceInterceptor bean allows supports
instance level configuration via the Java
bean property "identifiers". The
property takes a string with valid trace identifiers
delimited by a comma.
William Louth, JXInsight's Product
Architect