Tuesday, April 13, 2010

Using PMD Extension and Custom Rule Sets with JDeveloper 11g


Recently I’ve worked with a customer that was evaluating the use of PMD code quality tool integrated with JDeveloper 11g and their custom build process (using Maven/ANT) to improve their code quality and enforce their standards. They were specifically interested in custom ADF Business Components rules.

Although I knew that PMD it provides an extension for JDeveloper 11g I’ve never done any work with PMD before. So I dug into its documentation and found out that you can actually create rules based on both XPath expressions and Java.

Without any previous knowledge of PMD or XPath it took me less than an hour to quickly right some basic XPath rules; and believe me, I’m just your average developer! :^)

I’ve created 5 simple XPath-based rules:

  • Avoid using ViewObjectImpl.getRowCount();
  • Avoid calling transaction methods from ADF BC (commit/rollback/potChanges);
  • Avoid using DBTransaction class;
  • Avoid using direct JDBC calls to the Database;
  • Use of wrong super class for your Application Module.

I won’t go into the PMD implementation details. You can check the excellent PMD documentation for that. And just to make it crystal-clear: I’m not a PMD or XPath expert, so the XPath expression can still be wrong or raise false positives; the objective is just to give an idea of what can quickly be done using PMD and XPath no matter which framework you’re using.

So, here is the step by step process:

1. Fire up JDeveloper, go to Help->Check for Updates and download the PMD Extension. If you cannot find it through the Update Center, download it here and install it.

2. After installing, shutdown JDev. We will need to do some refactoring on the extension jar files due to the way the extension reads the rulesets properties.

3. Open your preferred file browser or command line and go to <JDEV_HOME>\jdeveloper\jdev\extensions\net.sourceforge.pmd.jdeveloper.\lib

4. Open the pmd-4.2.5.jar file with your preferred tool. You’ll see that there is a rulesets directory in it. Extract this directory to your file system and remove the rulesets directory from the jar file. We need to do this to modify the rulesets/rulesets.properties config file that is bundled within the jar file.

5. Open the rulesets.properties file and at the end of the rulesets.filenames append rulesets/adfbc.xml . It should look like this:


6. Download the adfbc.xml ruleset file to the rulesets folder. Now create a new jar called rulesets.jar with the rulesets directory. You can download the one I’ve prepared from here. Just remember that you still need to remove the original rulesets directory from pmd-4.2.5.jar as explained above.

7. Back on the pmd-4.2.5.jar, open its META-INF/MANIFEST.MF and add a reference to rulesets.jar:

Manifest-Version: 1.0

Ant-Version: Apache Ant 1.7.1

Created-By: 11.2-b01 (Sun Microsystems Inc.)

Main-Class: net.sourceforge.pmd.PMD

Class-Path: jaxen-1.1.1.jar asm-3.1.jar rulesets.jar

What we did was to remove the rulesets dependency from the original jar to an external jar that we can modify at will. Unfortunately the import rules feature of the extension does not work as one would expect.

8. Launch JDev and go to Preferences->PMD. You should see the following rule entries at the bottom of the rules list:


9. I’ve created a Bad Practice ADF BC Project and added some offending code in my ApplicationModuleImpl class to test the rules. If I right click on my AM java source and pick PMD at the bottom of the context menu this is the the output generated:


Here it is also a call for action: if you want to tackle the task of creating new XPath expressions for ADF, or to improve the existing PMD extension, please get in contact with me. I will try my best to help you.

I won’t go into the details of writing a custom Java-based rule; the documentation at the PMD site is pretty good. The only drawback is that PMD is not able to analyze XML files, which is an essential feature for a good ADF analysis. For that, I will be unleashing the full power of ojaudit and how to write custom audit rules to it. Stay tuned!

Thursday, April 1, 2010

Quick ADF Faces af:table / af:column tip: case insentive QBE


Alright, so today I was playing with the out of the box af:table QBE feature, and I noticed that the inputText filters displayed at the top of the table header were case sensitive. I was intrigued and started to debug some internal classes only to be snapped by my fellow colleagues from the ADF Faces team that this is actually a built-in feature of the af:column tag:

   1: <af:column sortProperty="FirstName" filterable="true"

   2:            sortable="true"

   3:            headerText="#{bindings.Employees.hints.FirstName.label}"

   4:            id="resId1c2" width="300"

   5:            filterFeatures="caseInsensitive">

This is correctly documented in the af:column tag documentation.

So, lesson learned: read the fraking doc before annoying your developer friends! >_<