JBoss Tattletale

Tattletale signifie « révélateur ». Il s’agit d’un outil qui analyse les dépendances entre les jars. Ce dernier scanne un répertoire contenant l’ensemble des librairies et génère divers rapports HTML. Au même titre que Cobertura, FindBugs, Pmd etc…, JBoss Tattletale risque bien de devenir un outil fort utile dans votre environnement d’intégration.

Ce projet a été démarré en février 2009. La 1.0.0 est sortie en avril 2009 et la version actuelle est la 1.1 sortie en mars 2010.

Il permet :

  • D’identifier les dépendances entre les jars présents dans un répertoire
  • Trouver les classes manquantes du classpath
  • Mettre en évidence des classes utilisées dans de multiples jars
  • Mettre en évidence deux même jars dans de multiples localisations
  • Vérifier le SerialVersionUID d’une classe
  • Mettre en évidence deux même jars avec un numéro de version différent
  • Trouver les jars sans numéro de version
  • Trouver les jars non utilisés
  • Lister les classes d’un jar et les classes dont elles dépendent
  • Obtenir le statut OSGI d’un jar et founir le Manifest
  • De générer des graphes de dépendances en png à l’aide de Graphviz (http://www.graphviz.org)

Cet outil peut-être utile lors de la migration vers Maven d’applications existantes non mavenisées, dont les jars ne sont pas versionnés et dont les dépendances entre les jars se sont pas évidentes.

Mais il peut également mettre en évidence les jars réellement utiles pour les applications mavenisées. En effet Maven 2 et sa gestion des dépendances transitives, a tendance à ramener trop de jars, si on ne précise pas de les exclure explicitement dans le pom.xml ou si la dépendance n’est pas explicitement définie dans ce même fichier.

L’analyse de ses rapports va donc permettre de minimiser le nombre de dépendances, de mettre en évidence la moindre duplication de classes dans le classpath et d’éviter les dépendances circulaires.

Les paramètres de configuration jboss-tattletale.properties

Reports listes de rapports à générer (* pour tous)

dependants, dependson, graphviz, transitivedependants, transitivedependson, circulardependency, classlocation, osgi, sealed,sign, eliminatejars, invalidversion, multiplejars, multiplejarspackage, multiplelocations, unusedjar, blacklisted, noversion, jar

classloader

  • org.jboss.tattletale.reporting.classloader.NoopClassLoaderStructure
  • org.jboss.tattletale.reporting.classloader.JBossAS4ClassLoaderStructure
  • org.jboss.tattletale.reporting.classloader.JBossAS5ClassLoaderStructure

profiles (java5, java6, ee5, ee6, seam22, cdi10, spring25, spring30)

  • Java 5 and Java 6
  • Java Enterprise Edition 5 and Java Enterprise Edition 6
  • Spring 2.5 and Spring 3.0
  • Contexts and Dependency Injection (CDI) 1.0
  • JBoss Seam 2.2

En ajoutant un profile spécifique, toutes ses dépendances seront pris en compte dans votre configuration.

excludes liste des répertoires ou fichier à exclure

blacklisted liste des classes ou package à exclure

scan file extension (.jar par défaut pour l’instant)

graphvizDot=C:\\Java\\Graphviz2.26.3\\bin\\dot.exe

En ligne de commande

java -Xmx512m -jar tattletale.jar [-exclude=<excludes>] <input-directory> <output-directory>

Intégration

Intégré avec Ant

Ajouter les librairies suivantes dans le lib-build : tattletale.jar, tattletale-ant.jar and javassist.jar.

Voici un exemple de build.xml :

<?xml version="1.0" encoding="ISO-8859-1"?>
<project name="JBoss Tattletale" default="jboss-tattletale" basedir=".">

	<property name="lib-build.dir" value="lib-build"/>
	<property name="lib.dir" value="lib"/>
	<property name="dest.dir" value="target/site/tattletale"/>

	<path id="tattletale.class.path">
		<fileset dir="${lib-build.dir}">
			<include name="**/*.jar"/>
		</fileset>
	</path>

	<target name="clean" >
		<delete dir="${dest.dir}" />
	</target>

	<target name="jboss-tattletale" depends="clean" >
		<taskdef name="report"
		         classname="org.jboss.tattletale.ant.ReportTask"
		         classpathref="tattletale.class.path"/>

		<mkdir dir="${dest.dir}"/>
		<echo message ="Running Tattletale from ${lib.dir} to ${dest.dir}"/>

		<!-- run tattletale task-->
		<report source="${lib.dir}" destination="${dest.dir}" />

	</target>
</project>

Intégré avec Maven

Depuis la version Jboss TattleTale 1.1, il s’intègre aisément dans l’environnement d’intégration continue grâce à un plugin Maven. Voici un exemple de pom.xml :

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>fr.ippon.tattletale</groupId>
	<artifactId>JBossTattletale</artifactId>
	<name>JBossTattletale</name>
	<version>1.0</version>
	<url>http://maven.apache.org</url>

	<dependencies>
		<dependency>
			<groupId>javax.mail</groupId>
			<artifactId>mail</artifactId>
			<version>1.4</version>
		</dependency>
		<dependency>
			<groupId>javax.activation</groupId>
			<artifactId>activation</artifactId>
			<version>1.1</version>
		</dependency>
		<dependency>
			<groupId>quartz</groupId>
			<artifactId>quartz</artifactId>
			<version>1.5.2</version>
		</dependency>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.1</version>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.13</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
		</dependency>
	</dependencies>

	<reporting>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-project-info-reports-plugin</artifactId>
				<version>2.1.1</version>
				<reportSets>
					<reportSet>
						<reports>
							<report>index</report>
							<!-- report>cim</report>
							<report>dependencies</report>
							<report>dependencies-convergence</report>
							<report>dependency-management</report>
		              		<report>issue-tracking</report>
							<report>license</report>
		              		<report>mailing-list</report>
							<report>plugins</report>
							<report>project-team</report>
							<report>scm</report>
							<report>summary</report-->
						</reports>
					</reportSet>
				</reportSets>
			</plugin>

			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>cobertura-maven-plugin</artifactId>
				<configuration>
					<formats>
						<format>html</format>
						<format>xml</format>
					</formats>
				</configuration>
			</plugin>
		</plugins>
	</reporting>

	<build>
		<plugins>

			<!--
			  Copy all dependencies in one temporary source folder
			  before running tattletale.
			-->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-dependency-plugin</artifactId>
				<version>2.1</version>
				<executions>
					<execution>
						<id>copy-dependencies-to-source-directory</id>
						<phase>pre-site</phase>
						<goals>
							<goal>copy-dependencies</goal>
						</goals>
						<configuration>
							<outputDirectory>${project.build.directory}/tattletale-source</outputDirectory>
						</configuration>
					</execution>
				</executions>
			</plugin>

			<!--
			  Run tattletale report.
			-->
			<plugin>
				<groupId>org.jboss.tattletale</groupId>
				<artifactId>tattletale-maven</artifactId>
				<version>1.1.0.Final</version>
				<executions>
					<execution>
						<id>run-tattletale-plugin</id>
						<phase>site</phase>
						<goals>
							<goal>report</goal>
						</goals>
						<configuration>
							<source>${project.build.directory}/tattletale-source</source>
							<destination>${project.build.directory}/site/tattletale</destination>
							<profiles>
								<profile>java5</profile>
							</profiles>
						</configuration>
					</execution>
				</executions>
			</plugin>

			<!--
			  Run ant task to delete jars in tattletale-source-directory
			  because it can take lot of space multi-module projects.
			-->
			<plugin>
		        <artifactId>maven-antrun-plugin</artifactId>
		        <version>1.4</version>
		        <executions>
		          <execution>
		            <phase>post-site</phase>
		            <configuration>
		              <tasks>
		              	<echo message="Deleting jars in tattletale-source-directory"/>
						<delete>
							<fileset dir="${project.build.directory}/tattletale-source">
								<include name="**/*.jar"/>
							</fileset>
						</delete>
		              </tasks>
		            </configuration>
		            <goals>
		              <goal>run</goal>
		            </goals>
		          </execution>
		        </executions>
		      </plugin>

		</plugins>
	</build>

	<pluginRepositories>
		<pluginRepository>
			<id>jboss-releases</id>
			<name>JBoss Release Repository</name>
			<url>http://repository.jboss.org/maven2</url>
			<releases>
				<enabled>true</enabled>
			</releases>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</pluginRepository>
	</pluginRepositories>

	<distributionManagement>
		<site>
			<id>mvn-site</id>
			<url>file:///var/html/maven/site</url>
		</site>
	</distributionManagement>

</project>

puis lancer la commande mvn site-deploy. Quelques impressions écrans :

Dans le futur, il est prévu un support pour les EAR, WAR, archives ESB, et le développement d’un plugin pour Hudson.

http://jboss.org/tattletale

Tweet about this on TwitterShare on FacebookGoogle+Share on LinkedIn

3 réflexions au sujet de « JBoss Tattletale »

    1. En effet, nous avons rencontré des soucis avec notre flux RSS. Le problème est normalement réglé, subsiste le difficile problème de cache de Google Reader qui conserve des infos erronées… Nous y travaillons. Merci pour votre retour.

  1. Il m’a l’air sympa cet outil. Utile lors que l’on récupère un projet non encore mavenisé.
    Par contre je ne vois pas comment il peut détecter les jars non utilisés sans executer l’application : la réflexion et l’introspection permettant de charger et d’utiliser des classes non référencées.
    Sais-tu comment il peut réaliser cet exploit ?

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *


*