Lightweight Application Monitoring with Hawtio and JMX.

In my previous life developing solutions for a biometrics company, we invested quite a bit in monitoring tools to know the status and performance of the cluster of servers on which our application was deployed. The tool of choice was RHQ 4.x, and I must say it served us well in many places. But it came with it’s own complexity, and having discovered the simple but quite efficient HawtIO, I think I have a new permanent member of my arsenal for software delivery and monitoring.

Hawtio is a modular web console that enables you to monitor any JVM based application via JMX, with the use of the Jolokia, a tool for exposing JMX via JSON to enable REST like invocation of JMX beans. All you need to do to get Hawtio working on Jboss7/Wildfly is to follow the instructions here.

My main interest was in profiling the performance of Hibernate within my JavaEE application deployed in JBoss 7, and Markus Eisele’s post on using HawtIO to display Hibernate statistics was just on point. Basically you can follow his instructions and make the following modifications for Jboss7/Wildfly.

1. Include these 2 files from Makus’s post in your project StatisticsService and DelegatingStatisticsService
2. Add a @Singleton @Startup EJB which does the following

@Startup
@Singleton
public class HibernateMBeanRegistrar {
    private static final Logger logger = LoggerFactory.getLogger(HibernateMBeanRegistrar.class);
  
    @javax.annotation.Resource(lookup = "java:jboss/MySessionFactory")
    private SessionFactory sessionFactory;
    
    @Inject 
    public void register() {
        try {
            try {
                MBeanServer mbeanServer
                        = ManagementFactory.getPlatformMBeanServer();
                ObjectName on
                        = new ObjectName("Hibernate:type=statistics,application=hibernatestatistics");

                StatisticsService mBean = new DelegatingStatisticsService(sessionFactory.getStatistics());
                mbeanServer.registerMBean(mBean, on);
                logger.info("Hibernate Statistics MBean registered successfully ...");
            } catch (MalformedObjectNameException ex) {
                logger.error("", ex);
            } catch (InstanceAlreadyExistsException ex) {
                logger.error("", ex);
            } catch (MBeanRegistrationException ex) {
                logger.error("", ex);
            } catch (NotCompliantMBeanException ex) {
                logger.error("", ex);
            }
        } catch (Exception e) {
            logger.error("Failure obtaining SessionFactory from EMF: "+e.getLocalizedMessage());
        }

    }
}

3. Add these to your persistence.xml

<property name="hibernate.generate_statistics" value="true"/>
<property name="hibernate.session_factory_name" value="java:jboss/MySessionFactory" /> 

4. Deploy your application alongside the hawtio-no-slf4j-x.x.x.war as stated in the instructions on installing hawtio for JBoss7/Wildfly. I renamed the file to hawtio to make life easier.
5. Once both hawtio and your application are deployed, navigate to http://localhost:8080/hawtio. Click on JMX and you should see a Hibernate–>statistics–>hibernatestatistics node. Clicking on that node should show you something like Markus’s view here. You can even add it to the dasboard if you wish so you get up to the minute figures as your application runs.

 

HIbernate Statistics

For me it did show that although my entities were being cached in the 2nd level cache, it seemed somehow that query caching was not working. So I’ve got work to do.

Hawtio does have a lot of plugins to display content from other sources, from Elasticsearch to log files. You should definitely give it a shot. Thanks Markus for the Hawtio intro.

Advertisements

Using Eclipse Dali with Hibernate as Persistence Provider

Eclipse Ganymede comes with in built support for the EclipseLink JPA implementation. However, we’ll want to explore how to use Hibernate’s JPA implementation with Eclipse Dali for JPA operations

To begin with, please make sure you have the following

  1. Eclipse Ganymede for JavaEE

  2. Hibernate EntityManager

  3. Hibernate Tools

  4. MySQL connector (or a jdbc connector of your choice if you are not using MySQL)

You will need to install Hibernate Tools as an Eclipse plugin. Next, you’ll have to add MySQL to your list of driver definitions. This you do by going to the “Window” → “Preferences”. On the left tree, navigate to “Data Management” → “Connectivity” → “Driver Definitions”. Click on the “Add” button. You now have a “New Driver Definition” window with three tabs – Name/Type, Jar List and Properties.


In the Name/Type tab, select MySQL. A list of choices now appears of “MySQL JDBC Driver”. Select System Version 5.0, click on the “Jar List” tab and delete the default MySQL driver file specified there. Click on “Add Jar/Zip” and add your MySQL connector. Please ensure that there are no spaces in the path to your MySQL connector, or you may have trouble later on. Click “Ok” to finish the driver definition.

Next is to add the Hibernate EntityManager libraries as your JPA implementation. First, extract the Hibernate EntityManager zip that you downloaded into a location without spaces in the path. Still in the “Preferences” window, click on “JPA” on the left tree. In the “Default JPA Implementation Library”, click the “Configure user libraries” link. Click on the “New” button and give this a good name e.g. HibernateJPA. Click on “Add JARs” and add the “hibernate-entitymanager.jar” that is available in your extracted Hibernate EntityManager folder. Next, add all the jars in the lib folder of the extracted folder. These should be

  • slf4j-api.jar
  • dom4j.jar
  • ejb3-persistence.jar
  • hibernate-annotations.jar
  • hibernate-commons-annotations.jar
  • hibernate-core.jar
  • javassist.jar
  • jta.jar


Click on “Ok” to complete adding the JPA implementation.

Now, create a Java Project called “jpaproject”. In the project explorer view, right-click the project and select “JPA Tools” → “Convert To JPA Project”. Click on “Next” on the “Project Facets” screen that shows up. On the “Configure JPA Settings” window, select “Hibernate” as your platform. You will now add your connection to the database by clicking on “Add connection” link. In the “Connection Profile” window, type MySQL in the filter. Select MySQL and enter the name “jpaprojectDB” in the “Name” field. Click “Next”, and specify your database connection details. Click “Test connection” to be sure, and then “Finish” when completed.

You should now have something like below


Remember to uncheck the “Create orm.xml” option. Its useless overhead we don’t need now. You now have a project that supports JPA, with a META-INF/persistence.xml file generated in your src folder. Funny enough, after all this information provided, Dali still refuses to populate your persistence.xml file with these details. You will have to do them yourself (talk about DRY).

Double-click on your persistence.xml. On the “General” tab, specify “org.hibernate.ejb.HibernatePersistence” as your Persistence Provider. In the “Connection” tab, choose “Resource Local” from the Transaction Type drop down list. Under “Hibernate” tab, select “MySQL” as Database dialect, “com.mysql.jdbc.Driver” as Driver class, “jdbc:mysql://localhost:3306/jaccra” as your connection URL, and then provided the username and password fields for the database connection. Click on “Source” and you should something close to the ff.


<?xml
version=“1.0”
encoding=“UTF-8”?>

<persistence version=“1.0” xmlns=http://java.sun.com/xml/ns/persistence&#8221;
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance&#8221;
xsi:schemaLocation=http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd&#8221;
>

<persistence-unit name=“jpaproject” transaction-type=“RESOURCE_LOCAL”>

<provider>org.hibernate.ejb.HibernatePersistence</provider>

<properties>

<property name=“hibernate.dialect” value=“org.hibernate.dialect.MySQLDialect”/>

<property name=“hibernate.connection.driver_class” value=“com.mysql.jdbc.Driver”/>

<property name=“hibernate.connection.url” value=“jdbc:mysql://localhost:3306/jaccra”/>

<property name=“hibernate.connection.username” value=“edem”/>

<property name=“hibernate.connection.password” value=“edem”/>

</properties>

</persistence-unit>

</persistence>

Now you are all set up for your JPA machinations. One last and very important thing to do is to add the MySQL connect jar to your build path. Now when you right-click on your project in the project explorer, you should see an option “JPA Tools”, under which there are a couple of other options. Explore them and see what you get.

Book Release : JBoss Tools 3 Developers Guide

JBoss Tools is an impressive set of open source Eclipse plugins that allow rapid development of enterprise and SOA based applications. It is developed by the JBoss group under the leadership of Max Rhydal Anderson.

It include support for rapid Hibernate, Seam, JSF and Richfaces, jBPM, JBoss ESB development and a lot more.There is no doubt that with such a compelling toolset, JBoss Tools stands out as the best set of tools for Ajax based JavaEE development that you can get for free and compares very well with those for pay.

To quickly point out how to harness the power of JBoss Tools for rapid application development, Packt Publishing has just announced their book JBoss Tools 3 Developers Guide by Anghel Leonard, scheduled to be released in April 2009. I believe this is the first book on JBoss Tools, and it has come at the right time for us developers.

Taking a hands on step by step approach to the 11 Chapters detailing each of the plugins at the time of writing, a developer is immediately delved into productive use of JBoss Tools in their project through a small project developed per chapter.

Of course, you will not expect to learn everything about Seam, Hibernate, Richfaces, JBoss-WS etc from the book simply because that is not the aim of it. However pointers are given to the right resources that will get you up to speed on them.

It has been fun being a technical reviewer of this book and I have to congratulate Leonard and the staff at Packt Publishing (Sarah and Leena) for their hardwork. I eagerly look forward to the release in April.

Don’t say I didn’t tell you how good it is, because this post is evidence that I have.

Seam PDF Rendering and JPA Native Queries

< Seam Portlet Bridge … | RichFaces Plugin Released >

One of the reasons why I’ve come to love Seam is that it really lives up to its appellation as a programming and integration model – because of its ability to let me use technologies which are complex in their own right without the need to learn the nitty gritty of them. One example is the use of facelets for email, something which if I had to do programmatically using the JavaMail API will be quite a hell. With Seam all I have to learn are new facelets tags related to email. I still have access to my Business Process, Application, Session,Conversation etc contexts and can use resources from these contexts just like a normal facelet which generates a web page. Another one is pdf rendering, and that is what we’ll be talking of today.

I’ll use the shopper application that I developed for my previous post on AJAX, DataTables and Seam. Before we go on though, let’s not forget to mention the need for the following jar files in your classpath as per Chapter 16 of the Seam reference manual.

  • itex.jar
  • jboss-seam-pdf.jar

Next add these declarations to your web.xml file

<servlet>
        <servlet-name>Document Store Servlet</servlet-name>
        <servlet-class>org.jboss.seam.pdf.DocumentStoreServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Document Store Servlet</servlet-name>
        <url-pattern>*.pdf</url-pattern>
    </servlet-mapping>

And these to your components.xml file, making sure the namespace is properly declared

<pdf:document-store use-extensions="true" />

Since we will be using charting from JFreeChart, we need to add these additional jars.

  •  jcommon.jar
  •  jfreechart.jar

I’ve decided to add two links that render pdf documents. One provides a pie chart of the products held in my database and their stock levels. Very simple use case, since all I have to do is to select the products I’m interested in into an ArrayList and display them.

public List<Product> getProductView(){
return entityManager.createQuery("Select p from Product p").getResultList();
}

Here is the section of the facelet that displays the contents of the resulting ArrayList.

    <p:image alignment="right" wrap="true" value="/jboss.jpg" />
    <p:font id="test" size="24"><p:paragraph spacingAfter="50">Chart</p:paragraph></p:font>
    <p:piechart title="Product Stock Levels" width="500" height="350" legend="true" is3D="true" plotForegroundAlpha=".25">
    <ui:repeat value="#{shopList.productView}" var="item">
          <p:data key="#{item.name}" value="#{item.stock}" />
    </ui:repeat>
    </p:piechart>

Products chart

Now that the easy one is out of the way, lets look at the second link. This is to render a table telling us the date a cart was created, the total cost and the number of products in that cart. Well, date and cost fields are already declared on the Cart entity we created and we could do cart.getCartItems().size and get the number of products in each cart. But I decided to use a less talked about feature of JPA – native queries. Native queries enable us write SQL statements to retrieve records in our database that may not have been captured, modelled or contained in an existing entity. These allow us to write very complex queries and apply aggregation functions and so on on data.

We begin by first examining our query

select cart.date_created as date,cart.cost as cost, count(cart_item.product_id) as products from cart left join cart_item on cart_item.cart_id=cart.id group by date

Hmm. We have three aliases/fields being fetched from the database. JPA requires the declaration of an @SqlResultSetMapping which assigns a name to a native query and the fields that will be fetched from that native query. I decided to declare mine on the Cart entity, though I could have declared it on any entity.

@SqlResultSetMappings({
    @SqlResultSetMapping(
    name = "productStock",
            columns = {
        @ColumnResult(name = "date"),
        @ColumnResult(name = "cost"),
        @ColumnResult(name = "products")
    })}

Having sorted out what I want to fetch and meeting JPA’s requirements on declaring a @SqlResultSetMapping, I now go on to fetch the data using the entityManager.

public List<Map> getCartView(){
        List<Object[]> results = entityManager.createNativeQuery(
"select cart.date_created as date,cart.cost as cost, count(cart_item.product_id) as products from cart left join cart_item on cart_item.cart_id=cart.id group by date","productStock").getResultList();
List data = new ArrayList<HashMap>();
        if (!results.isEmpty()) {
            for (Object[] result : results) {
                HashMap resultMap = new HashMap();
                resultMap.put("date", (Date)result[0]);
                resultMap.put("cost", result[1]);
                resultMap.put("products", result[2]);
                data.add(resultMap);
}
        }
return data;
}

There are lot of things to note here.

  1. We use entityManager.createNativeQuery(), not entityManager.createQuery().

  2. After stating the query, you must also give the name of the named query which you defined in the SqlResutSetMapping. Ours is “productStock”.

  3. Each row/record of data fetched from the database is assigned to an Object array. In this case “date” is in the 0th index, “cost” is in the 1st and so on. Since I’m fetching more than one, I use entityManager.getResultSet() and assign to a List.

Expression Language( EL) allows us to refer to data in a Map by its key, and that feels more natural to me on my facelet than referring to indexes of an array, so I rather iterate through my “results” List, creating a HashMap for each row/record from the database and using appropriate names to refer to the fetched data.

Now here’s the facelet that renders the table containing our records.

  <p:image alignment="right" wrap="true" value="/jboss.jpg" />
  <p:font id="test" size="24"><p:paragraph spacingAfter="50">Table</p:paragraph></p:font>
  <p:table  columns="3" headerRows="1">
  <p:cell ><p:paragraph alignment="center">Date</p:paragraph></p:cell>
  <p:cell><p:paragraph>Cost</p:paragraph></p:cell>
  <p:cell><p:paragraph>No. of products</p:paragraph></p:cell>
  <ui:repeat value="#{shopList.cartView}" var="data">
   <p:cell><p:paragraph><p:text  value="#{data.date}"><f:convertDateTime dateStyle="medium" type="both"/>
</p:text></p:paragraph></p:cell>
<p:cell><p:paragraph>#{data.cost}</p:paragraph></p:cell>
<p:cell><p:paragraph>#{data.products}</p:paragraph></p:cell>
</ui:repeat>
    </p:table>

Cart table

Explaining each of the individual tags on this facelet is out of the coverage area of this post and further details can be gleaned from the Seam Reference Manual. However using EL, I can just refer to the date field as #{data.date} and so on and we will all be none the wiser. Of particular interest is the use of the <p:text/> tag. It allows us to apply JSF formatting/conversion etc on data being rendered in a PDF, and here we needed to format the date using the f:convertDateTime. Another use of this is to determine if some data will be rendered using the standard “rendered” JSF component attribute.

The combination of bijection and contexts means that Seam can always find whatever I’m referencing in its appropriate context and display it for me, whether on a facelets web page, PDF, email or in an asynchronous process.


Added on 7th April 2008

Give the code a spin and see.