Trainologic

How to make the most out of Sonar when working with legacy code

by AviNJuly 11, 2011

You have a legacy codebase, possibly with hundreds of thousands of lines of code, you have set up Sonar - the widely adopted Java Static Code Analysis tool - hoping to use the tool in order to detect and monitor code quality issues and trends.

Alas, when you examine the Sonar dashboard you find you have hundreds or thousands of rule violations…  great, now what??

Following are a few ideas as to how you can tackle the situation:

  • Begin by reviewing the Blocking and Severe violations.  These might impact your system at runtime and thus should be fixed with no delay.  If you maintain a backlog, put an item there to represent this technical debt, so the situation will be visible to the Product Owner (i.e. transparency).
  • Use Sonar’s Alerts mechnism in order to detect and highlight new violations.
  • Share the situation with the rest of the team, and educate (or remind) them of the Boy Scout Rule.  This should lead to improved code quality in exactly those areas of the code that are most painful (as they are the ones that are being analyzed and maintained most often).

In addition, a new version of Sonar is expected to be released later this year (2011). One of the key features of this version is the ability to spot, highlight and track new violations that occured since the last execution of Sonar.  This feature should allow to distingush new violations from pre-exiting violations.

This way or another, don’t give up on using static code analysis - using it effectively can have strong positive impact on your code quality in the long run.

Managing WebSphere 6 Resources with JMX - How to (part 2)

by rankJune 16, 2009

This is the second part that deals with WebSphere 6 and JMX. The first part can be found in yesterday’s blog post.

Here I will give a small code sample of creating a JMS connection factory using the WebSphere JMX API. This example can give you a general idea of how things should look like when trying to administrate WAS from Java. There are of course more resources that you can generate (basically, everything that can be generated from the admin console) but I have decided to concentrate on one example that is not available in the InfoCenter.

Here is the method:

private void createJMSConnectionFactory(String name,String jndiName,String busName) throws Exception {
  ObjectName sibJmsAdapter = findSIBJMSResourceAdapter();
  
  ObjectName pattern = new ObjectName("*:_Websphere_Config_Data_Type=Node");
  ObjectName[] targets = configService.queryConfigObjects(null,pattern,null);
  ObjectName node = targets[0];
  // Find the connection definition
  pattern = new ObjectName("*:_Websphere_Config_Data_Type=ConnectionDefinition");
  ObjectName[] conDefs = configService.queryConfigObjects(node,pattern,null);
  ObjectName curConDef = null;
  if (conDefs != null) {
   for (ObjectName conDef : conDefs) {
    if (configService.getAttribute(conDef,"connectionFactoryInterface").equals("javax.jms.ConnectionFactory")) {
     curConDef = conDef;
     break;
    }
   }
  } else {
   System.out.println("No connection definitions");
  }
  
  
  AttributeList attrs = new AttributeList();
  attrs.add(new Attribute("name", name));
  attrs.add(new Attribute("jndiName", jndiName));
  attrs.add(new Attribute("connectionDefinition", curConDef));
  ObjectName conFactory = configService.createConfigData(sibJmsAdapter,"J2CConnectionFactory","J2CConnectionFactory",attrs);
  
  attrs.clear();
  ObjectName propertySet = configService.createConfigData(conFactory, "propertySet", "",attrs);
  attrs.clear();
  attrs.add(new Attribute("name", "BusName"));
  attrs.add(new Attribute("type", "java.lang.String"));
  attrs.add(new Attribute("value", busName));
  configService.addElement(propertySet, "resourceProperties", attrs, -1);
  
  System.out.println("SIB JMS connection factory created");
}

Let me go over the major parts: 

  • First thing you should do is to locate the “SIB JMS Resource Adapter” ObjectName in the WAS configuration. This config object is available by default, when you install WAS. To do that (here it’s a private method), just get all the “J2CResourceAdapter” objects and find the one with the correct name.
  • Next thing we get the node, assuming there is a single node configured. If you have multiple nodes, you should add some code that selects the correct one or work with a cell.
  • Next, locate the “ConnectionDefintion” object. There are several connection definitions, one for each type of JMS resource (check them out in the resources.xml file). We need the one that is defined for javax.jms.ConnectionFactory.
  • Next thing is to build the attributes list, with 3 needed attributes: name, jndiName and the connectionDefinition reference. There might be more attributes but those are the mandatory.
  • And now, createConfigData for the J2CConnectionFactory (which is the type that is used for JMS connection factories in WAS 6).
  • The J2CConnectionFactory must have a property set as a child element, with some more configurations, so we create the property set with createConfigData. As you can see, the AttributeList can be reused after it is cleared.
  • For each “resourceProperties“, we must use addElement with an AttributeList that contains 3 attributes: name, type and value. Here we add one resourceProperties element that points to the bus used with this ConnectionFactory (in WAS 6, the whole JMS infrastructure was changed to use a Service Information Bus. Read about that in the InfoCenter).
  • And we are done, a lot of lines but at the end you should get the ConnectionFactory configured and ready to work.

As I said before, this is only one example but you should get the sense of how to do other resource as well. The easiest way to knoq what config objects to use, is to look in the resources.xml files and find the declarations of different resources.

For any comments, questions or more examples, feel free to drop a comment.

Ran.

Java 6 Split Verifier

by Gal MarderJune 15, 2009

Several weeks ago, me and my partner, Shimi Bandiel, were asked by one of the largest global software companies to help them with a strange performance problem.

The problem was indeed strange, they had a fairly simple web application which was running perfectly well. The programmers working on this project have read that migrating to from Java 5 to Java 6 will result in better performance without any additional effort. The strange thing was that as soon as they have moved to version 6, JSP pages were awfully slow the first time they were accessed, and when I say slow I mean it, it was about 60 seconds per page to load.

Shimi and me rolled up our sleeves and started to work. Soon enough, we have discovered that the loading of the Servlet class generated from the JSP was the time consuming operation. A short thinking made us assume the problem is with the new class version of Java 6, we have made sure that the JSP is compiling the classes to Java 6 and that everything is set correctly. Everything seems to be fine. Then Shimi came up with a new idea, maybe it is a problem with the new verifier introduced in Java 6, the Split Verifier. In Java 6 the verification process is split to two phases: type inferencing (off-line) and type checking (on-line). This means the off-line part is done by the compiler which inserts data to the class file. This new verification process should speed up the class-loading process significantly. Unfortunately for some mysterious reason, this verification process failed when loading the JSP classes, when fails, this process falls back to the old verification and the result was a VERY long verification.

Since that project had to go online quickly, we had to find a fast solution, again, Shimi pooled something out of his sleeve, two flags that control the new verifier:

-XX:+UseSplitVerifier

-XX:+FailOverToOldVerifier

By using these flags we have manged to disable the split verifier and solve the problem.

Following are my conclusions from this experience:

  1. When trying to figure why systems act diferently on Java 6, keep in mind the Split Verfier.
  2. When you have performance problems, call Shimi ;)

Managing WebSphere 6 Resources with JMX - How to (part 1)

by rankJune 15, 2009

WebSphere 6, like all modern application servers, comes with a JMX framework that enables the developer to create cusotm Java applications that manage the server. Basically the idea is that you can perform all the administration tasks (that are available through the admin console) using a Java application locally or remotly.

The problem is that every applicaton server has a different solution, which makes it hard to create a management application that deals with multiple servers. The Management API (JSR-77) should solve this problem, but I found that it’s capabilities are not enough when you want to change the configuration and not only read it.

On WebSphere 6, there are a few things you should understand before going into writing a JMX client:

  1. WebSphere 6 is based on the latest JMX 1.2 spec so JDK 1.4 and 5 will work great. Remember that in JDK 5 the JMX classes are bundled with the rt.jar.
  2. The entire configuration domain is divided into two sections: runtime data and configuration data. On the runtime data section, you will find registered MBeans that can be read. To get those, you just need to query the MBeanServer and get the managed objects.On the configuration data section you will find managed objects that construct the configuration of the server but cannot be found using the MBeanServer query methods (since they are not registered there).

The main API you should use is found in the com.ibm.websphere.management.configservice package. The interesting interface is ConfigService, and two interesting classes ConfigServiceProxy and ConfigServiceHelper. Here is a direct link to the API docs: http://publib.boulder.ibm.com/infocenter/wasinfo/v6r0/index.jsp?topic=/com.ibm.websphere.javadoc.doc/public_html/api/index.html

The basic idea behind working with the WebSphere configuration, is that you can use the ConfigService methods to construct, edit and delete configuration objects, that will later can be saved to the main configuration repository and used in runtime. Some configuration changes require server restart, and some can be used instantly. Unfortunally, the ConfigService API is very low-level, and the high-level API is not available to external applications, so you should know what you are doing when manipulating the configuration. The ConfigService will let you change the configuration XML files for Server / Node / Cell / Cluster, but you should be familiar with the structure and elements used in those configuration files.

The easiest way to do that is to create the configuration you need with the admin console and then check the changes in the files, later trying to do the same with the ConfigService API. The config files help is also available at: http://publib.boulder.ibm.com/infocenter/wasinfo/v6r0/topic/com.ibm.websphere.javadoc.doc/configdoc/index.html

Let’s go over the main methods that should be used when creating configuration objects, I will concentrate on changing the configuration and not reading it, since reading is pure standard JMX work. Hopefully in part 2 I will give some code examples.

ConfigService interface main methods:

  • queryConfigObjects - This method is used when you want to look up a config objects in the configuration. Remember that config objects are not registered in the MBeanServer so the standard query methods will not work, and you should use this one. The method let you select the scope and pattern, and return an array of ObjectNames. Note the special keys: _WEBSPHERE_CONFIG_DATA_TYPE and _WEBSPHERE_CONFIG_DATA_ID that are used here to identify config objects.
  • createConfigData - This one is used to create new configuration data. Every config object has a parent config object, an attributeName that is used as the child element name in the parent element scope, a type and a list of attributes.You should know the type names, the attributeName and the supported attributes for each config object you add (remember looking at the XML files for the correct values here…)
  • addElement - used when the configuration data includes a collection of objects (like properties). Just select the attribute name and value, and where you want to put it in the collection (or just use -1).
  • getAttribute - can be used to get an attribute value form a config object.
  • getRelationship - get child config objects by the relationship name. This is useful when you know the structure of the configuration file, and want to browse the tree.
  • save / discard - control saving or discarding the changes made.

Apart from those, there are other methods available, the complete reference can be found in the API docs.

A session concept is also available (but not mandatory, you can use null for the session arguments), it is explained in the API docs quite good.

On the next part, I will give some code samples to a JMX client that works with WebSphere, and will talk about the requirments for working with WAS 6 from Sun’s JVM.

Ran.

Virtual directories in WebSphere

by rankMay 21, 2009

The idea of using virtual directories for web applications, is to enable content serving from several locations, using some specified url. This is very useful for example for static content that is shared between several web applications inside the application server.

The servlet spec defines the ServletContext idea, which means that all the resources (dynamic and static) must be packed with the web application. So there is no standard thet defines how to achieve access to outside resources. Usually application servers support this by using a special extension.

To do that with WebSphere, we have to go into almost undocumented territory (don’t you love when WebSphere people do that..) and check the ibm-web-ext.xmi file.

What you should do is enable file serving and then set some attributes that will control it.
Here is an example of a ibm-web-ext.xmi:

<webappext:WebAppExtension xmi:version=”2.0″ xmlns:xmi=”http://www.omg.org/XMI” xmlns:webappext=”webappext.xmi”
xmlns:webapplication=”webapplication.xmi” xmi:id=”WebApp_ID_Ext” reloadInterval=”3″ reloadingEnabled=”true”
fileServingEnabled=”true” directoryBrowsingEnabled=”false” serveServletsByClassnameEnabled=”false”
preCompileJSPs=”false” autoRequestEncoding=”false” autoResponseEncoding=”false”>
  <webApp href=”WEB-INF/web.xml#WebApp_ID”/>
  <fileServingAttributes xmi:id=”FSA_1″ name=”extendedDocumentRoot” value=”C:/static_content”/>
  <fileServingAttributes xmi:id=”FSA_2″ name=”file.serving.patterns.allow” value=”images/*”/>
</webappext:WebAppExtension>

as you can see, I have added two file serving attributes:

  1. extendedDocumentRoot attribute - this one allows you to put a comma delimited list of locations or jar files to look in. those locations can be outside the war file, anywhere on the file system.
  2. file.serving.patterns.allow attribute - control which resources should be served by using URL patterns. You can use a space delimited list of patterns.

Now you can access your static resources with the following URL:
http://yourserver:9080/yourContextRoot/images/myimage.gif

Other available attributes can be found in http://publib.boulder.ibm.com/infocenter/wasinfo/v6r0/index.jsp?topic=/com.ibm.websphere.base.doc/info/aes/ae/cweb_flserv.html

Ran.

Welcome

by Gal MarderMay 7, 2009

Welcome to Trainologic’s Blog.

In this blog you will find various posts about software development, consulting and training.

All posts Are written by Trainologic’s experts, community members and business partners.

Enjoy!!!