Dashboard > CruiseControl > ... > IntegratingWithOtherTools > CruiseControlWithJarAnalyzer
CruiseControlWithJarAnalyzer Log In View a printable version of the current page.

Added by vhe , last edited by vhe on Jul 03, 2007  (view change)
Labels: 
(None)

Introduction

JarAnalyzer is a dependency management utility for jar files.

Step 1 - Add JarAnalyzer to your build

For information on adding JarAnalyzer to your Ant build, please refer to the JarAnalyzer website.

Be sure to use an output directory which can later be merged into the CruiseControl log. Also ensure you use the extended XML output, as follows:

build.xml
<target name="analyzer" depends="previous_target">
   <taskdef name="jaranalyzer"
        classname="com.kirkk.analyzer.textui.JarAnalyzerTask">
        <classpath>
           <pathelement path="${buildlib}/JarAnalyzer-0.9.2.jar"/>
           <pathelement path="${buildlib}/lib/bcel-5.1.jar"/>
           <pathelement path="${buildlib}/lib/jakarta-regexp-1.3.jar"/>
           <pathelement path="${buildlib}/lib"/>
        </classpath>
   </taskdef>

   <jaranalyzer srcdir="${bindist}"
       destfile="${buildstats}/dependencies.xml"
       summaryclass="com.kirkk.analyzer.textui.XMLUISummary" packageFilter="java.*;javax.*;" jarFilter="*.jar" />

 <style in="${buildstats}/dependencies.xml" out="${buildstats}/dependencies.html" style="${buildlib}/jaranalyzer.xsl">
 	</style>
</target>

Step 2 - Merge the results into your CC log

Add a merge child element to your project(s)' log element. If you wish, you can filter based on the extension you used above.

<log dir="${logdir}">    .    .    .
    <merge dir="${builddir}/jaranalyzer" pattern="dependencies.xml"/>
    .    .    .
</log>

Step 3 - Add formatting info to cruisecontrol.css

This CSS code is based on stylesheet information supplied with the JarAnalyzer XSL scripts:

cruisecontrol.css
.jaranalyzer-data { font-family:arial,helvetica,sans-serif; font-size:8pt; color:#000000; }
.jaranalyzer-sectionheader { background-color:#000066; font-family:arial,helvetica,sans-serif; font-size:10pt; color:#FFFFFF; }
.jaranalyzer-tableheader { font-family:arial,helvetica,sans-serif; font-size:9pt; font-weight: bold; color:#000080; background-color:#CCDDDD; }


Step 4 - Add a new tab in main.jsp

The next three steps add a new tab to CruiseControl, which gives a detailed report of the JarAnalyzer results.

main.jsp
.
.
.
    <cruisecontrol:tabsheet>
      <tr>
        <td bgcolor="white" >
          <cruisecontrol:tab name="buildResults" label="Build Results" >
            <%@ include file="buildresults.jsp" %>
          </cruisecontrol:tab>

          <cruisecontrol:tab name="jaranalyzer" label="JarAnalyzer" >
            <%@ include file="jaranalyzer.jsp" %>
          </cruisecontrol:tab>
.
.
.


Step 5 - Create jaranalyzer.jsp

jaranalyzer.jsp
<%@page errorPage="/error.jsp"%>
<%@ taglib uri="/WEB-INF/cruisecontrol-jsp11.tld" prefix="cruisecontrol"%>
<cruisecontrol:xsl xslFile="/xsl/jaranalyzer-details.xsl"/>

Step 6 - Create jaranalyzer-details.xsl in the xsl directory

The following script is based on the jaranalyzer.xsl file supplied with JarAnalyzer:

jaranalyzer-details.xsl
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:param name="today" select="today"/>

<!--
    Copyright  2002,2004 The Apache Software Foundation

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.

-->

<xsl:output method="html" indent="yes"  encoding="US-ASCII"/>




<xsl:template match="/">
	<xsl:apply-templates select="." mode="JarAnalyzer"/>
</xsl:template>


<xsl:template match="/" mode="JarAnalyzer">
	<xsl:variable name="unique-catkey" select="/cruisecontrol/JarAnalyzer/Jars/Jar"/>

	<script type="text/javascript">
		function toggleRow(elid) {
			if (document.getElementById) {
				element = document.getElementById(elid);
				if (element) {
					if (element.style.display == 'none') {
						element.style.display = 'block';
						//window.status = 'Toggle on!';
					} else {
						element.style.display = 'none';
						//window.status = 'Toggle off!';
					}
				}
			}
		}
	</script>

	<xsl:if test="count(cruisecontrol/JarAnalyzer) = 0">
		JarAnalyzer was not run against this project.
	</xsl:if>


  <xsl:if test="count(cruisecontrol/JarAnalyzer) &gt; 0">
    <html>
    <head>
        <title>JarAnalyzer Analysis</title>

    <style type="text/css">
      body {
        font:normal 68% verdana,arial,helvetica;
        color:#000000;
      }

     table.gray {
		  background:#eeeeee
      }
      table tr td, tr th {
          font-size: 68%;
      }
      table.details tr th{
        font-weight: bold;
        text-align:left;
        background:#a6caf0;
      }
      table.details tr td{
        background:#eeeee0;
      }

      p {
        line-height:1.5em;
        margin-top:0.5em; margin-bottom:1.0em;
        margin-left:2em;
        margin-right:2em;
      }
      h1 {
        margin: 0px 0px 5px; font: 165% verdana,arial,helvetica
      }
      h2 {
        margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica
      }
      h3 {
        margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica
      }
      h4 {
        margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
      }
      h5 {
        margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
      }
      h6 {
        margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
      }
      .Error {
        font-weight:bold; color:red;
      }
      .Failure {
        font-weight:bold; color:purple;
      }
      .Properties {
        text-align:right;
      }
      </style>


    </head>
    <body>

    <h1><a name="top">JarAnalyzer Analysis</a></h1>
	<p align="right">Run with <a href="http://www.kirkk.com/main/Main/JarAnalyzer">JarAnalyzer</a> on <xsl:value-of select="$today"/></p>
    <hr size="2" />

    <table width="100%"><tr><td>
    <a name="NVsummary"><h2>Summary</h2></a>
    </td><td align="right">
    [<a href="#NVsummary">summary</a>]
    [<a href="#NVjars">jars</a>]
    [<a href="#NVcycles">cycles</a>]
    [<a href="#NVexplanations">explanations</a>]
    </td></tr></table>
      <table width="100%" class="details">
        <tr>
            <th>Jar Name</th>
            <th>Total Classes</th>
            <th><a href="#EXclassnumber">Abstract Classes</a></th>
            <th><a href="#EXpackagenumber">Packages</a></th>
            <th><a href="#EXabstractness">Abstractness</a></th>
            <th><a href="#EXefferent">Efferent</a></th>
            <th><a href="#EXafferent">Afferent</a></th>
            <th><a href="#EXinstability">Instability</a></th>
            <th><a href="#EXdistance">Distance</a></th>

        </tr>
    <xsl:for-each select="$unique-catkey">
        <xsl:if test="count(error) = 0">
            <tr>
                <td align="left">
                    <a>
                    <xsl:attribute name="href">#PK<xsl:value-of select="@name"/>
                    </xsl:attribute>
                    <xsl:value-of select="@name"/>
                    </a>
                </td>
                <td align="right"><xsl:value-of select="Summary/Statistics/ClassCount"/></td>
                <td align="right"><xsl:value-of select="Summary/Statistics/AbstractClassCount"/></td>
                <td align="right"><xsl:value-of select="Summary/Statistics/PackageCount"/></td>
                <td align="right"><xsl:value-of select="Summary/Metrics/Abstractness"/></td>
                <td align="right"><xsl:value-of select="Summary/Metrics/Efferent"/></td>
                <td align="right"><xsl:value-of select="Summary/Metrics/Afferent"/></td>
                <td align="right"><xsl:value-of select="Summary/Metrics/Instability"/></td>
                <td align="right"><xsl:value-of select="Summary/Metrics/Distance"/></td>


            </tr>
        </xsl:if>
    </xsl:for-each>
    <xsl:for-each select="$unique-catkey">
        <xsl:if test="count(error) &gt; 0">
            <tr>
                <td align="left">
                    <xsl:value-of select="@name"/>
                </td>
                <td align="left" colspan="8"><xsl:value-of select="error"/></td>
            </tr>
        </xsl:if>
    </xsl:for-each>
    </table>

     <table width="100%"><tr><td>
    <a name="NVjars"><h2>Jars</h2></a>
    </td><td align="right">
    [<a href="#NVsummary">summary</a>]
    [<a href="#NVjars">jars</a>]
    [<a href="#NVcycles">cycles</a>]
    [<a href="#NVexplanations">explanations</a>]
    </td></tr></table>

    <xsl:for-each select="$unique-catkey">
        <xsl:if test="count(error) = 0">
            <h3><a><xsl:attribute name="name">PK<xsl:value-of select="@name"/></xsl:attribute>
            <xsl:value-of select="@name"/></a></h3>

            <table width="100%" class="gray"><tr>
                <td><a href="#EXafferent">Afferent Couplings</a>: <xsl:value-of select="Summary/Metrics/Afferent"/></td>
                <td><a href="#EXefferent">Efferent Couplings</a>: <xsl:value-of select="Summary/Metrics/Efferent"/></td>
                <td><a href="#EXabstractness">Abstractness</a>: <xsl:value-of select="Summary/Metrics/Abstractness"/></td>
                <td><a href="#EXinstability">Instability</a>: <xsl:value-of select="Summary/Metrics/Instability"/></td>
                <td><a href="#EXdistance">Distance</a>: <xsl:value-of select="Summary/Metrics/Distance"/></td>
            </tr></table>

            <table width="100%" class="details">
                <tr>
                    <th>Uses Jars</th>
                    <th>Used by Jars</th>
                    <th>Cycles With</th>
                </tr>
                <tr>
                    <td valign="top" width="33%">
                        <xsl:if test="count(Summary/OutgoingDependencies/Jar)=0">
                            <i>None</i>
                        </xsl:if>
                        <xsl:for-each select="Summary/OutgoingDependencies/Jar">
                             <a>
								<xsl:attribute name="href">#PK<xsl:value-of select="node()"/>
								</xsl:attribute>
								<xsl:value-of select="node()"/><br/>
							</a>
                        </xsl:for-each>
                    </td>
                     <td valign="top" width="33%">
                        <xsl:if test="count(Summary/IncomingDependencies/Jar)=0">
                            <i>None</i>
                        </xsl:if>
                        <xsl:for-each select="Summary/IncomingDependencies/Jar">
                            <a>
								<xsl:attribute name="href">#PK<xsl:value-of select="node()"/>
								</xsl:attribute>
								<xsl:value-of select="node()"/><br/>
							</a>
                        </xsl:for-each>
                    </td>
                    <td valign="top" width="33%">
                        <xsl:if test="count(Summary/Cycles/Cycle)=0">
                            <i>None</i>
                        </xsl:if>
                        <xsl:for-each select="Summary/Cycles/Cycle">
                            <a>
								<xsl:attribute name="href">#PK<xsl:value-of select="node()"/>
								</xsl:attribute>
								<xsl:value-of select="node()"/><br/>
							</a>
                            <br/>
                        </xsl:for-each>
                    </td>
                </tr>
            </table>

            <table width="100%" class="details">
                 <tr>
                    <th>Packages within jar</th>
                    <th><a href="#EXunresolved">Unresolved Packages</a></th>
                </tr>
                <tr>
                <td valign="top" width="26%">
                    <xsl:if test="count(Summary/Packages/Package)=0">
                            <i>None</i>
                        </xsl:if>
                        <xsl:for-each select="Summary/Packages/Package">
                            <xsl:value-of select="node()"/><br/>
                        </xsl:for-each>
                    </td>
                <td valign="top" width="26%">
                        <xsl:if test="count(Summary/UnresolvedDependencies/Package)=0">
                            <i>None</i>
                        </xsl:if>
                        <xsl:for-each select="Summary/UnresolvedDependencies/Package">
                            <a>
                                <xsl:value-of select="node()"/>
                            </a><br/>
                        </xsl:for-each>
                    </td>
                </tr>

              </table>
        </xsl:if>
    </xsl:for-each>

    <table width="100%"><tr><td>
    <a name="NVcycles"><h2>Cycles</h2></a>
    </td><td align="right">
    [<a href="#NVsummary">summary</a>]
    [<a href="#NVjars">jars</a>]
    [<a href="#NVcycles">cycles</a>]
    [<a href="#NVexplanations">explanations</a>]
    </td></tr></table>

    <xsl:for-each select="$unique-catkey">
        <h3><xsl:value-of select="@name"/> has cycles with</h3><p>
         <xsl:if test="count(Summary/Cycles/Cycle)=0">
			 <i>None</i>
         </xsl:if>
        <xsl:for-each select="Summary/Cycles/Cycle">
               <xsl:value-of select="node()"/>
              <br/>
        </xsl:for-each></p>
    </xsl:for-each>

 <hr size="2" />
    <table width="100%"><tr><td>
    <a name="NVexplanations"><h2>Explanations</h2></a>
    </td><td align="right">
    [<a href="#NVsummary">summary</a>]
    [<a href="#NVjars">jars</a>]
    [<a href="#NVcycles">cycles</a>]
    [<a href="#NVexplanations">explanations</a>]
    </td></tr></table>

    <p>The following explanations are for quick reference. More detailed information can be found in the <a href="http://www.kirkk.com/main/Main/JarAnalyzer">JarAnalyzer documentation</a>.</p>

    <h3><a name="EXclassnumber">Number of Classes</a></h3>
        <p>The number of concrete and abstract classes (and interfaces) in the jar is an indicator of the extensibility of the jar.</p>
       <h3><a name="EXpackagenumber">Number of Packages</a></h3>
        <p>The number of packages in the jar.</p>
         <h3><a name="EXafferent">Afferent Couplings</a></h3>
        <p>The number of other jars that depend upon classes within the jar is an indicator of the jar's responsibility. </p>
    <h3><a name="EXefferent">Efferent Couplings</a></h3>
        <p>The number of other jars that the classes in the jar depend upon is an indicator of the jar's independence. </p>
    <h3><a name="EXabstractness">Abstractness</a></h3>
        <p>The ratio of the number of abstract classes (and interfaces) in the analyzed jar to the total number of classes in the analyzed jar. </p>
        <p>The range for this metric is 0 to 1, with A=0 indicating a completely concrete jar and A=1 indicating a completely abstract jar. </p>
    <h3><a name="EXinstability">Instability</a></h3>
        <p>The ratio of efferent coupling (Ce) to total coupling (Ce / (Ce + Ca)). This metric is an indicator of the jar's resilience to change. </p>
        <p>The range for this metric is 0 to 1, with I=0 indicating a completely stable jar and I=1 indicating a completely instable jar. </p>
    <h3><a name="EXdistance">Distance</a></h3>
        <p>The perpendicular distance of a jar from the idealized line A + I = 1. This metric is an indicator of the jar's balance between abstractness and stability. </p>
        <p>A jar squarely on the main sequence is optimally balanced with respect to its abstractness and stability. Ideal jars are either completely abstract and stable (x=0, y=1) or completely concrete and instable (x=1, y=0). </p>
        <p>The range for this metric is 0 to 1, with D=0 indicating a jar that is coincident with the main sequence and D=1 indicating a jar that is as far from the main sequence as possible. </p>
         <h3><a name="EXunresolved">Unresolved Packages</a></h3>
         <p>Packages not found in any of the jars analyzed. These can be filtered from output by specifying the packages to exlude in the Filter.properties file. Conversely, you can include jars containing these packages in the directory being analyzed.</p>
         <p>These packages are excluded from all calculations and adding the jars containing these packages will result in modified metrics.</p>
    </body>
    </html>
  </xsl:if>
</xsl:template>
</xsl:stylesheet>


Step 7 - Add a new section in buildresults.xsl

The next two steps add a JarAnalyzer summary report to the build results tab.

buildresults.xsl
.
.
.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:import href="maven.xsl"/>
  <xsl:import href="nant.xsl"/>
  <xsl:import href="checkstyle.xsl"/>
  <xsl:import href="pmd.xsl"/>
  <xsl:import href="jaranalyzer.xsl"/>
.
.
.
  <xsl:template match="/">
    <p><xsl:apply-templates select="$cruisecontrol.list" mode="maven"/></p>
    <p><xsl:apply-templates select="$cruisecontrol.list" mode="nant"/></p>
    <p><xsl:apply-templates select="$cruisecontrol.list" mode="checkstyle"/></p>
    <p><xsl:apply-templates select="$cruisecontrol.list" mode="pmd"/></p>
    <p><xsl:apply-templates select="$cruisecontrol.list" mode="jaranalyzer"/></p>
.
.
.

Step 8 - Create jaranalyzer.xsl in the xsl directory

Again, there are many possibilities here. This is a simple example:

jaranalyzer.xsl
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html"/>

    <!-- Any JarAnalyzer found jar dependency cycle is displayed.
    -->
    <xsl:template match="/" mode="jaranalyzer">
            <xsl:apply-templates select="/cruisecontrol/JarAnalyzer/Jars" mode="jaranalyzer"/>
    </xsl:template>

    <xsl:template match="Jars" mode="jaranalyzer">
        <xsl:variable name="total.jar.count" select="count(Jar)" />
        <table align="center" cellpadding="2" cellspacing="0" border="0" width="98%">
          <colgroup>
            <col width="50%"></col>
            <col width="50%"></col>
          </colgroup>
          <tr>
            <td class="jaranalyzer-sectionheader" colspan="4">
                JarAnalyzer cycles for jars: (<xsl:value-of select="$total.jar.count"/>)
            </td>
          </tr>

          <xsl:for-each select="Jar">
            <tr>
              <td class="jaranalyzer-data">
                <xsl:value-of select="@name"/>
              </td>
              <td class="jaranalyzer-data">
                <xsl:if test="count(Summary/Cycles/Cycle)=0">
                  None
                </xsl:if>
                <xsl:for-each select="Summary/Cycles/Cycle">
                  <xsl:value-of select="node()"/>
                  <br/>
                </xsl:for-each>
              </td>
            </tr>
          </xsl:for-each>
        </table>
    </xsl:template>

    <xsl:template match="*" mode="jaranalyzer"/>

    <xsl:template match="/">
        <xsl:apply-templates select="." mode="jaranalyzer"/>
    </xsl:template>
</xsl:stylesheet>

Step 9 - Add a warning count to metrics.jsp

Edit the metric.jsp page to add the JarAnalyzer dependencies cycle count to the coding violations chart:

metrics.jsp
.
.
.
<jsp:useBean id="xpathData" class="net.sourceforge.cruisecontrol.chart.XPathChartData" />
<%
    xpathData.add("CheckStyle", "count(/cruisecontrol/checkstyle/file/error)");
    xpathData.add("JarAnalyzer", "count(/cruisecontrol/JarAnalyzer/Jar/Cycles/Cycle) div 2");
    xpathData.add("PMD", "count(/cruisecontrol/pmd/file/violation)");
    xpathData.add("Javadoc", "count(/cruisecontrol/build//target/task[@name='javadoc'])");
%>
.
.
.


Screenshots


The JarAnalyzer added to the build results of CruiseControl.



The JarAnalyzer tab added to CruiseControl.



JarAnalyzer added to the coding metrics of CruiseControl.

Powered by a free Atlassian Confluence Open Source Project / Non-profit License granted to ThoughtWorks, Inc.. Evaluate Confluence today.
Powered by Atlassian Confluence 2.7.1, the Enterprise Wiki. Bug/feature request - Atlassian news - Contact administrators