By Oracle ACE Director Wilfred van der Deijl and Oracle ACE Richard Orlichs
- Write your own Audit Rule Tutorial
- Introduction to QA
- The JDeveloper Audit Framework
- Creating Custom Audit Rules
- Creating Custom Fixes
- Suppress Violations
- ADF EMG Audit Rules
- Automated QA with SonarQube
Write your own Audit Rule Tutorial
In this article we explain the process behind creating Oracle JDeveloper and Application Development Framework (ADF) code audit rules, and why we think this is a powerful tool for developers. We also created a step-by-step tutorial that details how to create an extension project, how to create audit rules, and custom fixes for these rules. That tutorial will also give you an insight in how to distribute your extension through a JDeveloper Update Center within your organization.
The tutorial focuses on creating audit rules for the Oracle ADF. That said, this is a JDeveloper feature and in the same way, you can write audit rules for Oracle Service-Oriented Architecture (SOA) Suite or any other JDeveloper project.
Introduction to QA
In a software development process, quality assurance (QA) is usually postponed until the very end, when there is little to no time left. After functional testing, bug fixing and—optimally—performance testing your application, there might be some time left for writing documentation. With that, the project ends.
In our experience, one of the main reasons for this (bad) habit is that QA tools usually are not embedded into the development process and, if they are, they are time consuming and cumbersome, with little perceived benefits to the developer.
Take SonarQube, for example, one of the most powerful QA tools. It typically operates on committed code from the source repository, and might report major issues, forcing the developer to take a second look at the code. This takes place after the code has been committed to the repository and, in most cases, the developer will have moved on to implementing the next functional requirement. And might experience the SonarQube report as a time-consuming nuisance, instead of enjoying the quality of the code going up.
Luckily, JDeveloper offers a solution. JDeveloper continuously checks your code and reports QA issues to you as you are developing. Issues will show as yellow or red indicators in your source code. This auditing framework is very powerful to begin with, and can be extended further with your own company- or project-specific rules.
The JDeveloper Audit Framework
JDeveloper comes with a standard framework to report quality issues and possible solutions to the developer. This is where the “light bulbs” come from that you see in the editor gutter when JDeveloper is trying to tell you something. It is also where the underlined warnings and errors come from inside your code. This works both for Java and XML files, covering nearly all files in a typical JDeveloper project.
You can modify the behavior of this framework in the Audit page of JDeveloper's preferences dialog. This includes a Profiles page where you can configure different audit profiles. You can share them using export and import. You can also select which profile should be used for the continuous auditing while you are coding.
Once you've set up a profile to your liking, you can use the Build menu in JDeveloper to run this profile against a workspace or a specific subset of files within this workspace. JDeveloper gives you a quick report of the violations within these files; you can export this report to XML or HTML to share or use in other tooling.
Creating Custom Audit Rules
If the rules provided by JDeveloper or one of its extensions are not of your liking, you can create your own JDeveloper extension and write your own custom audit rules.
Setting up an extension project in JDeveloper is relatively simple. Start by downloading the Extension SDK through JDeveloper to check for updates and then create an Extension Application. In this application, you must focus on three main files during the creation of a custom audit rule.
- Res.properties is the resource bundle where all your labels and messages are.
- extension.xml is where you declaratively define your audit rules.
- Analyzer class(es) are where the actual magic happens.
The resource bundle is a straightforward property file that uses key value pairs to define your resource keys and the assigned value. Refer to these keys in extension.xml so that at run time JDeveloper can look up the value (label) for the assigned key.
The extension.xml is a file where you define a so-called audit-hook, which is a hook in the framework to declaratively define your audit rule and its properties. These are properties such as the ID, the default severity and the category it is in.
You also define one or more triggers and one or more analyzers for this audit hook in extension.xml. The triggers do as the name suggests, and trigger the audit-hook when a certain technology is used in a project. For example, a trigger with technology ADFbc will fire Analyzers for an ADF Business Components project, while a trigger with technology JSF will fire Analyzers for a Java Server Faces project. You can define multiple triggers and analyzers for each audit-hook you are creating.
The analyzer is where the actual checks happen and is programmed in Java. This java class is a subclass of
oracle.jdeveloper.audit.analyzer.Analyzer. This Analyzer class provides
exit methods on constructs both for Java and XML files.
In the Analyzer class, you program your rule logic. The Extension SDK API gives a pretty good idea of what an Analyzer does:
"The Audit framework traverses the constructs of the object models corresponding to the nodes being audited and at each construct invokes the applicable enter and exit methods of each registered analyzer."
The traversal is done depth-first, resulting in the child construct
enter method being called after its parents'
enter method on the way down ,and the child construct
exit method called before its parents'
exit method on the way up. The best practice is to collect information in the enter methods, while reporting violations during traversal back up through the exit methods, when all information on children has been collected.
The method signature of the enter and exit methods accept two parameters: the AuditContext (more on this later) and the construct being analyzed. For each construct, the most specifically-typed method that accepts the construct will be called; for example, a method accepting a java.lang.Object will be invoked for each construct while one accepting org.w3c.dom.Attr will be invoked only for xml attributes. For performance reasons, be as specific as possible with your method signature to prevent too many invocations.
The AuditContext (which is an instance of
oracle.jdeveloper.audit.analyzer.AuditContext) is used to report violations and/or measurements to the framework. However, AuditContext can also be used in the enter and exit methods to provide information about the current state of the traversal. You can use this to set attributes on the context for later use in child constructs. You can even use the AuditContext to share attributes between different analyzers if you're required to do so.
Creating Custom Fixes
Once you have set up your audit rule and thrown a violation to report to the user what is wrong with the code, you can also program a fix for this rule, as signified by the light bulbs that JDeveloper shows in the editor gutter. Clicking the light bulb will give you one or more solutions to choose from. Once you pick an option, your code is reformatted and rewritten into a suggested solution by the framework. This behavior is what we call a "fix" and, just as for custom rules, you can create your custom fixes to implement this behavior.
In your extension project, you need to edit the extension.xml file to register your transform class in the audit-hook and add a transform binding to your audit rule to register this transform as a fixer for that rule. As with the Analyzer, the transform class is where the actual magic happens to write a fix in java code.
This transform class need to be a subclass of the
oracle.jdeveloper.audit.transform.Transform class, and has a single
apply method that makes the necessary changes to the source object. For advanced scenarios, the transform can even ask the user for additional input before applying the fix.
After happily coding all your rules into a great extension project, you start to deliver this useful extension to your coworkers, family and friends, because we all want to benefit from this amazing tool. If so, it won't take long before you will start hearing people complain about all the violations they have and how in some cases this shouldn't be reported because they deliberately chose to program their code this way. There might be times when you want to ignore the reported violation.
One of the great things about JDeveloper 12c is that the framework has a new feature called Suppression Schemes. You might be familiar with @SuppressWarnings annotations to suppress java compiler warnings; as of JDeveloper 12c, the auditing framework understands these annotations as well. You can suppress a violation using the lightbulb in the line gutter in the code editor. That will add the java annotation to your code and the violation won't be reported for this specific instance anymore .
This is a great out-of-the-box feature and a good helping hand—but most of our coding is not in Java anymore, and we configure metadata in XML files. As we've seen in the previous sections, the audit rule framework supports creating rules on XML files, so, as you can imagine, the XML files get a lot of errors and warning reported to them. Some of these violations are false positives and a developer can lose track of what is important to look at and what is not. This might result in the developer ignoring all the rules altogether. Luckily, the Suppression Schemes in JDeveloper's auditing framework are also extensible by creating an Analyzer similar to what we've seen before; but instead of it reporting violations, it can suppress them. Even luckier, this work has already been done for you. If you go to Check for Updates in JDeveloper 12c, you'll see between the "open source and partner extensions" a "Suppress Audit Warnings" extension. After installing this extension, you'll have the same functionality for your XML files as you have for your Java code.
After activating the suppression from the line gutter light bulb, an XML comment is added and the violation is suppressed:
Application Development Framework Enterprise Methodology Group (ADF EMG) Audit Rules
Now that we've taken a look at the open source and partner extensions, there is another extension that might be worth looking at (if you're an ADF developer, that is). There is an initiative going on to create an open source audit rule extension project for ADF developers, by ADF developers. We're creating rules based on the ADF coding guidelines to prevent developers from making common mistakes, to point them to best practices, and to help them avoid the main pitfalls in ADF development.
This extension includes the feature of Suppressing Violations, so you don't need to get the suppression extension.
You can find the ADF Audit Rules extension in the Check for Update menu. Versions exist for both JDeveloper 11g R1 and JDeveloper 12c. However, be aware of the fact that suppressing violations within JDeveloper is supported only since JDeveloper 12c, so there might be an overload of violations reported to you in JDeveloper 11g.
Automated QA with SonarQube
We have shown you the great benefits of creating rules and seeing violation at design time, rather than after the fact in a review process. To get the best out of both worlds, you also want to embed code quality checks in an continuous delivery process.
There are a lot of powerful benefits of tools like SonarQube, so it is wise to keep using them. However, one of the main disadvantage we noticed is that there is no support for ADF- or SOA-specific violations—in other words, the XML audit rules that we were talking about before.
But as with JDeveloper, SonarQube is also a framework that allows you to extend it. Recently, a plugin was released that integrates ojaudit into SonarQube, which means that now you can see your specific violations for your chosen technology, as well as your custom created audit rules integrated into your continuous code quality tool.
In this article, you have read about using the JDeveloper Auditing Framework and how to extend it. While traditionally, QA checks are done at the end of development, you now have the tools to do QA at design time. This empowers the developer to think about the quality of code while writing it.
If you have followed the accompanying step-by-step tutorial, you will now be able to code your company or project code guidelines in audit rules.
Don't forget to check out the community effort—ADF EMG Audit Rules—in which the Oracle code guidelines are coded into Audit Rules and which includes the suppression scheme for XML violations. It is also a good example of how to implement different rules. Since this is an open source project, you could use this as a starting point for further creating your company or project rules.
About the Authors
Oracle ACE Director Wilfred van der Deijl has been working with Oracle's development tools and database ever since getting his degree in Computer Science in 1995. An active member of the Oracle community, Wilfred is a blogger, author, Oracle customer advisory board member, and a frequent presenter at international conferences, including ODTUG and Oracle OpenWorld
Oracle ACE Richard Olrichs is an Oracle Developer at MN, a techology company based in the Netherlands. Richard Olrichs has extensive expertise in Oracle Fusion Middleware with deep specialization in the Oracle Application Development Framework. Richard initiated an open source project creating an ADF EMG Audit Rules extension for both JDeveloper 11g and JDeveloper12c, and was also one of the initiators of ADF EMG XML DataControl, an open source project for both JDeveloper ADF 11g and JDeveloper ADF 12c. Richard is has spoken at Tech 13, Tech 14, and Oracle Open World 2014.
Note: This article has been reviewed by the relevant Oracle product team and found to be in compliance with standards and practices for the use of Oracle products.