Tag: monitoring

Enabling DataSource Spy Logging in JBoss AS7

Hi,

Some times we face issues while invoking some JDBC statements using the DataSource JDBC Connection. Many times it is not easily identifiable that which part of the JDBC code is actually causing the failure or issue. So it is better to have a Spy logging kind of feature inside the datasource which can tell us all the activities which an application performs on the Jdbc connection & Statements retrieved from the DataSource.

JBoss AS7 uses Jacmar for implementing it’s datasource mechanism. Also JBoss AS7 provides a very effecient way of enabling the spy logging which can log all the informations related to the connection/statements and any method whcih is invoked on the JDBC Objects.

In order to enable the DataSource Spy logging in JBoss AS7 we will need to do the following two things:

Step1). Enable the “jboss.jdbc.spy” to DEBUG inside your “standalone-full.xml” or “domain.xml” file present inside “jboss-as-7.1.0.Beta1/standalone/confguration” directory as following:

        <subsystem xmlns="urn:jboss:domain:logging:1.1">
            <console-handler name="CONSOLE">
                <level name="INFO"/>
                <formatter>
                    <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
                </formatter>
            </console-handler>
            <periodic-rotating-file-handler name="FILE">
                <formatter>
                    <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
                </formatter>
                <file relative-to="jboss.server.log.dir" path="server.log"/>
                <suffix value=".yyyy-MM-dd"/>
                <append value="true"/>
            </periodic-rotating-file-handler>
            <logger category="com.arjuna">
                <level name="WARN"/>
            </logger>
            <logger category="org.apache.tomcat.util.modeler">
                <level name="WARN"/>
            </logger>
            <logger category="sun.rmi">
                <level name="WARN"/>
            </logger>
            <logger category="jacorb">
                <level name="WARN"/>
            </logger>
            <logger category="jacorb.config">
                <level name="ERROR"/>
            </logger>

            <!-- ************* Enabling Spy logging category ************ -->
            <logger category="jboss.jdbc.spy">
                <level name="TRACE"/>
            </logger>
            <!-- *************************************************-->

            <root-logger>
                <level name="INFO"/>
                <handlers>
                    <handler name="CONSOLE"/>
                    <handler name="FILE"/>
                </handlers>
            </root-logger>
        </subsystem>

Step2). Create a DataSource from JBoss Console or using “jboss-admin.sh” utility. You can refer to the following article for more details on creating DataSources:
How to create Oracle DataSource And Install Oracle JDBC Driver in JBoss AS7
OR
How to create MySQL datasource And Install MySQL JDBC driver in JBoss AS7

NOTE: The only thing you need to remember is to add the spy=”true” attribute in your DataSource configuration as following:

        <subsystem xmlns="urn:jboss:domain:datasources:1.0">
            <datasources>
                <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="H2DS" enabled="true">
                    <connection-url>
                        jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
                    </connection-url>
                    <driver>
                        h2
                    </driver>
                    <security>
                        <security-domain>
                            encrypted-ds
                        </security-domain>
                    </security>
                </datasource>


                <!-- ****** Below is MySqlDS with Spy logging enabled ****** -->
                <datasource jndi-name="java:/MySqlDS" pool-name="MySqlDS_Pool" enabled="true" spy="true" jta="false" use-ccm="false">
                    <connection-url>
                        jdbc:mysql://localhost:3306/testDB
                    </connection-url>
                    <driver-class>
                        com.mysql.jdbc.Driver
                    </driver-class>
                    <driver>
                        mysql-connector-java-5.1.13-bin.jar
                    </driver>
                    <security>
                        <security-domain>
                            encrypted-ds
                        </security-domain>
                    </security>
                </datasource>
                <!-- ****** Above is MySqlDS with Spy logging enabled ****** -->


                <drivers>
                    <driver name="h2" module="com.h2database.h2">
                        <xa-datasource-class>
                            org.h2.jdbcx.JdbcDataSource
                        </xa-datasource-class>
                    </driver>
                </drivers>
            </datasources>
        </subsystem>

NOTE: In order to enable the spy logging you must follow both the steps “Step-1” and “Step-2” together.

Step3). Now suppose if you have following kind of JSP Page inside your application which uses the JBoss DataSource Jdbc Connection in order to perform some JDBC operations:

<%@page contentType="text/html" import="java.util.*,javax.naming.*,javax.sql.DataSource,java.sql.*"%>

<%
DataSource ds = null;
Connection con = null; 
PreparedStatement pr = null; 
InitialContext ic; 

out.println("<html>");
out.println("<body>");
out.println("<center>");

	try 
	{
		ic = new InitialContext();
		ds = (DataSource)ic.lookup("java:/MySqlDS");
		con = ds.getConnection(); 
		
		out.println("<font color=green>");
		out.println("<b>Got Connection </b> = "+con);
		out.println("<br><br><br><br><br><br><b> This means our DataSource has been configured properly </b> ");
		out.println("</font>");
		System.out.println("==> Got Connection = "+con);

                Statement stmt=con.createStatement();
                ResultSet rs=stmt.executeQuery("SELECT * FROM emp");
                out.println("<TABLE>");
                while(rs.next())
                 {
                     out.println("<TR><TD>"+rs.getString(1)+"</TD><TD>"+rs.getString(2)+"</TD></TR>");
                 }
                out.println("</TABLE>");
	}

	catch (SQLException s)
	{
		out.println("<font color=red>");
		out.println("<b>!!! Did not get the connection </b> = " +s);
		out.println("<br><br><br><br><br><br><b>This means we might have to check our datasource configuration (i.e. URL, Username, Password etc) or might be the database is down </b> ");
		out.println("</font>");
		System.out.println("!!! Did not get the connection = " +s);
	}

	catch(Exception e)
	{
		out.println("<font color=red>");
		out.println("<b>!!! Exception thrown </b> = " +e);
		out.println("<br><br><br><br><br><br><b>This means we might have to check our datasource configuration (i.e. URL, Username, Password etc) or might be the database is down </b> ");
		out.println("</font>");
		System.out.println("!!! Exception thrown = "+e);
	}

	finally
	{
		if(con != null)
		{
			con.close();
		}      
	} 

out.println("</center>");
out.println("</body>");
out.println("</html>");
%>

Step4). Restart your JBoss after enabling the Spy Logging and then access the application which performs some activity on the JDBC Connection retrieved from the JBoss AS7 DataSource. The you will notice in your “server.log” file following kind of DEBUG messages:

23:01:14,744 DEBUG [jboss.jdbc.spy] (http-localhost-127.0.0.1-8080-1) java:/MySqlDS [Connection] createStatement()
23:01:14,748 DEBUG [jboss.jdbc.spy] (http-localhost-127.0.0.1-8080-1) java:/MySqlDS [Statement] executeQuery(SELECT * FROM emp)
23:01:14,756 DEBUG [jboss.jdbc.spy] (http-localhost-127.0.0.1-8080-1) java:/MySqlDS [ResultSet] next()
23:01:14,756 DEBUG [jboss.jdbc.spy] (http-localhost-127.0.0.1-8080-1) java:/MySqlDS [ResultSet] getString(1)
23:01:14,757 DEBUG [jboss.jdbc.spy] (http-localhost-127.0.0.1-8080-1) java:/MySqlDS [ResultSet] getString(2)
23:01:14,757 DEBUG [jboss.jdbc.spy] (http-localhost-127.0.0.1-8080-1) java:/MySqlDS [ResultSet] next()
23:01:14,757 DEBUG [jboss.jdbc.spy] (http-localhost-127.0.0.1-8080-1) java:/MySqlDS [Connection] close()

Means whatever operations our application is performing on the JDBC Connection/Statement…etc objects everything is being logged. This can be very helpful in debugging/troubleshooting many JDBC Related issues.

Following is not part of Spy Logging but Useful

If you are running in Development environment and if it’s OK to have more logging then you can also enable the following category “org.jboss.jca” in your “standalone-full.xml” or “domain.xml” file to get more informations related to your DataSource:

            <logger category="org.jboss.jca">
                <level name="TRACE"/>
            </logger>
23:58:12,112 TRACE [org.jboss.jca.core.connectionmanager.NoTxConnectionManager] (http-localhost-127.0.0.1-8080-1) Subject: Subject:
	Principal: root
	Private Credential: javax.resource.spi.security.PasswordCredential@dd9c93cc

23:58:12,122 DEBUG [org.jboss.jca.core.connectionmanager.pool.idle.IdleRemover] (http-localhost-127.0.0.1-8080-1) internalRegisterPool: about to notify thread: old next: 1322937792121, new next: 1322937792121
23:58:12,123 TRACE [org.jboss.jca.core.connectionmanager.pool.strategy.PoolBySubject] (http-localhost-127.0.0.1-8080-1) ManagedConnectionPool: 52e0cdc9
Method: getConnection(Subject:
	Principal: root
	Private Credential: javax.resource.spi.security.PasswordCredential@dd9c93cc
, null)
ManagedConnectionFactory:
  Class: org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory
  Object: 4200309
ConnectionListenerFactory:
  Class: org.jboss.jca.core.connectionmanager.notx.NoTxConnectionManagerImpl
  Object: 51a745fc
Pool:
  Name: MySqlDS_Pool
PoolConfiguration:
  MinSize: 0
  MaxSize: 20
  BlockingTimeout: 30000
  IdleTimeout: 1800000
  BackgroundValidation: false
  BackgroundValidationMillis: 0
  StrictMin: false
  UseFastFail: false
Available:
InUse:
Statistics:
  ActiveCount: 0
  AvailableCount: 20
  AverageBlockingTime: 0
  AverageCreationTime: 0
  CreatedCount: 0
  DestroyedCount: 0
  MaxCreationTime: 0
  MaxUsedCount: 0
  MaxWaitCount: 0
  MaxWaitTime: 0
  TimedOut: 0
  TotalBlockingTime: 0
  TotalCreationTime: 0
23:58:12,124 TRACE [org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory] (http-localhost-127.0.0.1-8080-1) Using properties: {user=root, password=--hidden--}
23:58:12,124 TRACE [org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory] (http-localhost-127.0.0.1-8080-1) Checking driver for URL: jdbc:mysql://localhost:3306/testDB
23:58:12,125 TRACE [org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory] (http-localhost-127.0.0.1-8080-1) Driver not yet registered for url: jdbc:mysql://localhost:3306/testDB
23:58:12,125 DEBUG [org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory] (http-localhost-127.0.0.1-8080-1) Driver loaded and instance created:com.mysql.jdbc.Driver@75589559
23:58:12,180 DEBUG [org.jboss.jca.core.tx.jbossts.XAResourceRecoveryImpl] (Periodic Recovery) RecoverySecurityDomain was empty
23:58:12,180 DEBUG [org.jboss.jca.core.tx.jbossts.XAResourceRecoveryImpl] (Periodic Recovery) Subject for recovery was null
23:58:12,338 TRACE [org.jboss.jca.core.connectionmanager.pool.strategy.PoolBySubject] (http-localhost-127.0.0.1-8080-1) supplying new ManagedConnection: org.jboss.jca.core.connectionmanager.listener.NoTxConnectionListener@4b7d94f8[state=NORMAL managed connection=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@21bf4c80 connection handles=0 lastUse=1322936892337 trackByTx=false pool=org.jboss.jca.core.connectionmanager.pool.strategy.PoolBySubject@163778cf pool internal context=org.jboss.jca.core.connectionmanager.pool.mcp.SemaphoreArrayListManagedConnectionPool@52e0cdc9]
23:58:12,338 TRACE [org.jboss.jca.core.connectionmanager.pool.strategy.PoolBySubject] (http-localhost-127.0.0.1-8080-1) Got connection from pool: org.jboss.jca.core.connectionmanager.listener.NoTxConnectionListener@4b7d94f8[state=NORMAL managed connection=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@21bf4c80 connection handles=0 lastUse=1322936892337 trackByTx=false pool=org.jboss.jca.core.connectionmanager.pool.strategy.PoolBySubject@163778cf pool internal context=org.jboss.jca.core.connectionmanager.pool.mcp.SemaphoreArrayListManagedConnectionPool@52e0cdc9]
23:58:12,347 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) ==> Got Connection = org.jboss.jca.adapters.jdbc.jdk6.WrappedConnectionJDK6@28892a87
23:58:12,350 DEBUG [jboss.jdbc.spy] (http-localhost-127.0.0.1-8080-1) java:/MySqlDS [Connection] createStatement()
23:58:12,355 DEBUG [jboss.jdbc.spy] (http-localhost-127.0.0.1-8080-1) java:/MySqlDS [Statement] executeQuery(SELECT * FROM emp)
23:58:12,362 DEBUG [jboss.jdbc.spy] (http-localhost-127.0.0.1-8080-1) java:/MySqlDS [ResultSet] next()
23:58:12,363 DEBUG [jboss.jdbc.spy] (http-localhost-127.0.0.1-8080-1) java:/MySqlDS [ResultSet] getString(1)
23:58:12,363 DEBUG [jboss.jdbc.spy] (http-localhost-127.0.0.1-8080-1) java:/MySqlDS [ResultSet] getString(2)
23:58:12,363 DEBUG [jboss.jdbc.spy] (http-localhost-127.0.0.1-8080-1) java:/MySqlDS [ResultSet] next()
23:58:12,363 DEBUG [jboss.jdbc.spy] (http-localhost-127.0.0.1-8080-1) java:/MySqlDS [Connection] close()
23:58:12,365 TRACE [org.jboss.jca.core.connectionmanager.listener.NoTxConnectionListener] (http-localhost-127.0.0.1-8080-1) unregisterConnection: 0 handles left
23:58:12,365 TRACE [org.jboss.jca.core.connectionmanager.pool.strategy.PoolBySubject] (http-localhost-127.0.0.1-8080-1) ManagedConnectionPool: 52e0cdc9
Method: returnConnection(4b7d94f8, false)
ManagedConnectionFactory:
  Class: org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory
  Object: 4200309
ConnectionListenerFactory:
  Class: org.jboss.jca.core.connectionmanager.notx.NoTxConnectionManagerImpl
  Object: 51a745fc
Pool:
  Name: MySqlDS_Pool
PoolConfiguration:
  MinSize: 0
  MaxSize: 20
  BlockingTimeout: 30000
  IdleTimeout: 1800000
  BackgroundValidation: false
  BackgroundValidationMillis: 0
  StrictMin: false
  UseFastFail: false
Available:
InUse:
  4b7d94f8 (NORMAL)
Statistics:
  ActiveCount: 1
  AvailableCount: 19
  AverageBlockingTime: 0
  AverageCreationTime: 212
  CreatedCount: 1
  DestroyedCount: 0
  MaxCreationTime: 212
  MaxUsedCount: 1
  MaxWaitCount: 0
  MaxWaitTime: 0
  TimedOut: 0
  TotalBlockingTime: 0
  TotalCreationTime: 212
23:58:12,366 TRACE [org.jboss.jca.core.connectionmanager.pool.strategy.PoolBySubject] (http-localhost-127.0.0.1-8080-1) Returning connection to pool org.jboss.jca.core.connectionmanager.listener.NoTxConnectionListener@4b7d94f8[state=NORMAL managed connection=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@21bf4c80 connection handles=0 lastUse=1322936892366 trackByTx=false pool=org.jboss.jca.core.connectionmanager.pool.strategy.PoolBySubject@163778cf pool internal context=org.jboss.jca.core.connectionmanager.pool.mcp.SemaphoreArrayListManagedConnectionPool@52e0cdc9]

.
.
Thanks
MiddlewareMagic Team


Getting WebService Statistics using JMX in JBoss AS7

Hi,

In this demonstration we will see how we can query the Statistics of a WebService deployed on JBoss using standard MBean code. In this example we will see that we need not to add any JAVA_OPTS in our JBoss configuration files in order to access these MBeans.

Here we will use a Sample webservice which will be deployed on JBoss AS7, for example you can refer to the following article to know how to deploy the WebService in JBoss: “http://middlewaremagic.com/jboss/?p=980” We will try to access the statistics of this webservice using our Standard JMX code. The statistics will include the following useful informations: “StartTime”, “StopTime”, “MinProcessingTime”, “AverageProcessingTime”, “MaxProcessingTime”, “RequestCount”..etc

JBoss side Configuration ( jboss-as-7.1.0.Beta1 )

Step1). Open the “/home/userone/jboss-as-7.1.0.Beta1/standalone/configuration/standalone-full.xml” file and edit the subsystem “urn:jboss:domain:jmx:1.1” as following:

        <subsystem xmlns="urn:jboss:domain:jmx:1.1" show-model="true">
            <jmx-connector registry-binding="jmx-connector-registry" server-binding="jmx-connector-server"/>
        </subsystem>

Step2). Restart your JBoss Profile from “/home/userone/jboss-as-7.1.0.Beta1/bin” directory like following:

[userone@localhost bin]$ ./standalone.sh -c standalone-full.xml

Step3). Deploy your WebService on JBoss. For Testing you can use the webService mentioned in the following link:
http://middlewaremagic.com/jboss/?p=980

Step4). Now Somewhere in your filesystem write a Java Program “WebServiceMonitor.java” as following:

import java.util.Date;
import java.util.Hashtable;
import java.io.IOException;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.lang.management.MemoryMXBean;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import javax.management.*;
import javax.management.openmbean.CompositeDataSupport;
 
public class WebServiceMonitor
{
    private static MBeanServerConnection connection;
    private static JMXConnector connector;
    public static void Connection(String hostname, String port) throws IOException
    {
        Integer portInteger = Integer.valueOf(port);
        Hashtable h = new Hashtable();
        JMXServiceURL address = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://"+hostname+":"+port+"/jmxrmi");
        connector = JMXConnectorFactory.connect(address,null);
        connection = connector.getMBeanServerConnection();
        System.out.println("GOT THE MBeanServerConnection---SUCCESSFULLY");
    }
 
    private static void getServiceDetail(String contextRoot,String endPointName) throws Exception
    {
        ObjectName serviceRef=new ObjectName("jboss.ws:context="+contextRoot+",endpoint="+endPointName);
        String address=(String)connection.getAttribute(serviceRef, "Address");
        System.out.println("t Address : "+address);
        Date startTime=(Date)connection.getAttribute(serviceRef, "StartTime");
        System.out.println("t StartTime : "+startTime);
        Long minProcessingTime=(Long)connection.getAttribute(serviceRef, "MinProcessingTime");
        System.out.println("t MinProcessingTime : "+minProcessingTime);
        Long maxProcessingTime=(Long)connection.getAttribute(serviceRef, "MaxProcessingTime");
        System.out.println("t MaxProcessingTime : "+maxProcessingTime);
        Long totalProcessingTime=(Long)connection.getAttribute(serviceRef, "TotalProcessingTime");
        System.out.println("t TotalProcessingTime : "+totalProcessingTime);
        Long requestCount=(Long)connection.getAttribute(serviceRef, "RequestCount");
        System.out.println("t RequestCount : "+requestCount);
        Long responseCount=(Long)connection.getAttribute(serviceRef, "ResponseCount");
        System.out.println("t ResponseCount : "+responseCount);
        Long faultCount=(Long)connection.getAttribute(serviceRef, "FaultCount");
        System.out.println("t FaultCount : "+faultCount);
        Date stopTime=(Date)connection.getAttribute(serviceRef, "StopTime");
        System.out.println("t StopTime : "+stopTime);
        Long averageProcessingTime=(Long)connection.getAttribute(serviceRef, "AverageProcessingTime");
        System.out.println("t AverageProcessingTime : "+averageProcessingTime);
    }
 
    public static void main(String[] args) throws Exception
    {
    String hostname = args[0];
    String port = args[1];
    String contextRoot=args[2];
    String endPointName=args[3];
    Connection(hostname, port);
    System.out.println("------------------Getting Service Details------------------");
    System.out.println("jboss.ws:context=CXFTimeoutClientDemo,endpoint=Test_CXF_WS");
    System.out.println("-----------------------------------------------------------");
    getServiceDetail(contextRoot,endPointName);

    // ObjectName will be in the following format
    // "jboss.ws:context="+contextRoot+",endpoint="+endPointName
    //       Example:
    //       jboss.ws:context=CXFTimeoutClientDemo,endpoint=Test_CXF_WS
    }
}

Step5). Now we will write a simple Ant build script to build and execute the above program. So write an Ant build script “build.xml” file in the same directory where the above program is placed.

<project name="JBoss_Monitor" default="run">
<property name="jboss.home" value="/NotBackedUp/JBoss_All/jboss-as-7.1.0.Beta1" />
<property name="jboss.module.dir" value="${jboss.home}/modules" />
<property name="base.dir" value="." />
 
   <path id="jboss.classpath">
     <fileset dir="${jboss.module.dir}">
        <include name="**/*.jar"/>
     </fileset>  
   </path>

   <target name="run">
       <javac srcdir="${base.dir}" destdir="${base.dir}"  includes="WebServiceMonitor.java" classpathref="jboss.classpath"/>
       <java classname="WebServiceMonitor">
           <classpath>
              <pathelement location="${base.dir}"/>
              <path refid="jboss.classpath"/>
           </classpath>
           <arg line="localhost 1090  CXFTimeoutClientDemo Test_CXF_WS"/>
       </java>
   </target>  
</project>

NOTE: The only change in the above file you need to do is to change the “jboss.home” directory path in the second line of the above script is to point to your own JBoss AS7 directory home directory.

Step6). Now before running your ANT script to build and deploy the above webapplication you should have the ANT as well as JAVA set in the $PATH variable of the Shell / command prompt as following:

For Unix Based OS:
export PATH=/home/userone/jdk1.6.0_21/bin:/home/userone/org.apache.ant_1.6.5/bin:$PATH

For Windows Based OS:
set PATH=C:/jdk1.6.0_21/bin;C:/org.apache.ant_1.6.5/bin;%PATH%

Step7). Run the command “ant” or “ant run” which will internally build the WebService and deploy it inside the JBoss AS7 standalone profile.

[userone@localhost Monitoring]$ ant run
Buildfile: /home/userone/Monitoring/build.xml

run:
      GOT THE MBeanServerConnection---SUCCESSFULLY
      ------------------Getting Service Details------------------
      jboss.ws:context=CXFTimeoutClientDemo,endpoint=Test_CXF_WS
      -----------------------------------------------------------
      	 Address : http://localhost:8080/CXFTimeoutClientDemo
      	 StartTime : Tue Nov 29 01:17:23 BTT 2011
      	 MinProcessingTime : 8
      	 MaxProcessingTime : 15191
      	 TotalProcessingTime : 15310
      	 RequestCount : 3
      	 ResponseCount : 3
      	 FaultCount : 0
      	 StopTime : null
      	 AverageProcessingTime : 5103

BUILD SUCCESSFUL
Total time: 2 seconds

Step8). If you want to run the above program manually then you will need to run the following command

.
java WebServiceMonitor localhost 1090 CXFTimeoutClientDemo Test_CXF_WS
.

NOTE: Here we are passing 4 Arguments
“localhost” (Here our JBoss is running),
“1090” (This is the jmx-connector-registry connector port of JBoss which is enabled in the step1),
“CXFTimeoutClientDemo” (This is the Context Root of our WebService Application)
“Test_CXF_WS” (This is the Endpoint Name of our WebService)
.
.
.
Thanks
MiddlewareMagic Team


Generating HeapDump while running JBoss as a Windows Service

Hi,

This article is very important in case of JBoss running as a Windows Service, Because if we run any Server JBoss or any other application server as a Windows Service then NONE of the JVM utilities like “jmap”, “jconsole” , “jps” or “VisualVM”… etc will work. So it becomes very difficult to collect the Thread Dump or Heap Dump of the Running Service.

We wrote an article based on JMX to collect the JVM’s memory related statistics using JMX code “Monitoring Heap & NonHeap Memory of JBoss using MBean code. Here we are extending the same program to make the JMX program to even collect the HeapDump whenever we want.

To connect to the actual JConsole remotely also we need to provide the following JAVA_OPTS inside our “$JBOSS_HOME/bin/run.bat” (run.conf.bat) file the connection url format should be:

service:jmx:rmi:///jndi/rmi://"+hostname+":"+port+"/jmxrmi

Step1). Edit the “%JBOSS_HOME%/bin/run.conf.bat” or “%JBOSS_HOME%/bin/run.bat” (Server StartScript configuration file) and then set the following JAVA_OPTS there.

set JAVA_OPTS="%JAVA_OPTS% -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=4545 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djavax.management.builder.initial=org.jboss.system.server.jmx.MBeanServerBuilderImpl -Djboss.platform.mbeanserver"

Make sure that the 4545 is not being used by any other process. Or define any other port in above parameter which is free.

Step2). Now from any other box or from the same Box you can run the Following JMX code to generate the HeapDump of the JVM process:
“GenerateHeapDump.java”

import java.util.Hashtable;
import java.io.*;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.naming.Context;
import java.lang.management.MemoryMXBean;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import javax.management.*;
import javax.management.openmbean.CompositeDataSupport;

public class GenerateHeapDump
{
	private static MBeanServerConnection connection;
	private static JMXConnector connector;
	public static void Connection(String hostname, String port) throws IOException
	{
		Integer portInteger = Integer.valueOf(port);
		Hashtable h = new Hashtable();
		JMXServiceURL address = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://"+hostname+":"+port+"/jmxrmi");
		connector = JMXConnectorFactory.connect(address,null);
		connection = connector.getMBeanServerConnection();
		System.out.println("GOT THE MBeanServerConnection---SUCCESSFULLY");
	}

	private static void doGarbageCollection() throws Exception
	{
		ObjectName memoryMXBean=new ObjectName("java.lang:type=Memory");
		connection.invoke(memoryMXBean,"gc", null, null);
		System.out.println("nnt------Garbage Collection Done Successfully-----");
	}

	private static void getHeapDump(String fileName) throws Exception
	{
		ObjectName memoryMXBean=new ObjectName("com.sun.management:type=HotSpotDiagnostic");
		Object[] params = new Object[] { "C:/WindowsService_Script/"+fileName, Boolean.TRUE };
		String[] signature = new String[] { String.class.getName(), boolean.class.getName() };
		Object result = connection.invoke(memoryMXBean, "dumpHeap" , params, signature);
		System.out.println("nt Heap Dump Generated to " +fileName);
	}

	public static void main(String[] args) throws Exception
	{
	String hostname = args[0];
	String port = args[1];
	Connection(hostname, port);
	System.out.println("nt----------Generating Heap Dump---------");
	getHeapDump("HeapDump.hprof");
	connector.close();
	}
}

Step3). Run your JBoss Windows Service and then compile and run your Program to generate the HeapDump

C:WindowsService_Script>set PATH=c:jdk160_05bin;%PATH%;
C:WindowsService_Script>javac GenerateHeapDump.java

C:WindowsService_Script>java GenerateHeapDump 10.10.10.10 4545
GOT THE MBeanServerConnection---SUCCESSFULLY

        ----------Generating Heap Dump---------
         Heap Dump Generated to HeapDump.hpro

NOTE: you will find the generated HeapDump in the "C:/WindowsService_Script/" directory in the Box where the JBoss is running as a Service which is defined in line -39 in above code.

.
.
Thanks
Middleware Magic Team


Copyright © 2010-2012 Middleware Magic. All rights reserved. |