23 votes

Existe-t-il un outil permettant de savoir si la même classe existe dans plusieurs pots dans le chemin d'accès (classpath) ?

Si vous avez deux pots dans votre classpath qui contiennent des versions différentes de la même classe, l'ordre du classpath devient critique.

Je suis à la recherche d'un outil capable de détecter et de signaler de tels conflits potentiels dans un classpath ou un ensemble de dossiers donné.

Certainement un script qui commence :

classes=`mktemp`
for i in `find . -name "*.jar"`
do
    echo "File: $i" > $classes
    jar tf $i > $classes
    ...
done

avec un astucieux sort/uniq/diff/grep/awk par la suite a du potentiel, mais je me demandais si quelqu'un connaissait des solutions existantes.

9voto

Zac Thompson Points 7754

On dirait que poisson-jarre fera ce que vous voulez avec sa commande "dupes".

8voto

Zac Thompson Points 7754

En Tattletale de JBoss est un autre candidat : "Spot if a class/package is located in multiple JAR files" (repérer si une classe/un paquet est situé dans plusieurs fichiers JAR)

3voto

brpaz Points 141

Aide à l'utilisation des chemins d'accès est un plug-in Eclipse qui aide un peu.

3voto

OscarRyz Points 82553

Je pense qu'il ne serait pas trop difficile d'écrire un outil pour soi-même.

Vous pouvez obtenir les entrées du chemin de classe avec System.getProperty("java.class.path") ;

Ensuite, parcourez les jarres, les zips ou les répertoires qui y sont répertoriés et recueillez toutes les informations sur les classes et repérez celles qui pourraient poser problème.

Cette tâche prendrait 1 ou 2 jours au maximum. Vous pouvez ensuite charger cette classe directement dans votre application et générer un rapport.

Il est probable que la propriété java.class.path n'affichera pas toutes les classes si vous utilisez une infrastructure avec un chargement de classe personnalisé complexe ( par exemple, j'ai vu une fois une application qui chargeait les classes à partir du LDAP ), mais cela fonctionnerait certainement dans la plupart des cas.

Voici un outil qui pourrait vous être utile, je ne l'ai jamais utilisé moi-même, mais essayez-le et faites-nous part du résultat.

http://www.jgoodies.com/freeware/jpathreport/features.html

Si vous souhaitez créer votre propre outil, voici le code que j'utilise pour le même script shell que celui posté précédemment, mais que j'utilise sur ma machine Windows. Il fonctionne plus rapidement lorsqu'il y a des tonnes de fichiers jar.

Vous pouvez l'utiliser et le modifier pour qu'au lieu de parcourir récursivement un répertoire, vous lisiez le chemin de la classe et compariez l'attribut temporel .class.

Il existe une classe Command que vous pouvez sous-classer si nécessaire, je pensais à l'option -execute de "find"

Il s'agit de mon propre code, qui n'est donc pas destiné à être "prêt pour la production", mais simplement à faire le travail.

import java.io.*;
import java.util.zip.*;

public class ListZipContent{
    public static void main( String [] args ) throws IOException {
        System.out.println( "start " + new java.util.Date() );
        String pattern = args.length == 1 ? args[0] : "OracleDriver.class";// Guess which class I was looking for :) 
        File file = new File(".");
        FileFilter fileFilter = new FileFilter(){
            public boolean accept( File file ){
                return file.isDirectory() || file.getName().endsWith( "jar" );
            }
        };
        Command command = new Command( pattern );
        executeRecursively( command, file, fileFilter );
        System.out.println( "finish  " + new java.util.Date() );
    }
    private static void executeRecursively( Command command, File dir , FileFilter filter ) throws IOException {
        if( !dir.isDirectory() ){
            System.out.println( "not a directory " + dir );
            return;
        }
        for( File file : dir.listFiles( filter ) ){
            if( file.isDirectory()){
                executeRecursively( command,file , filter );
            }else{
                command.executeOn( file );
            }
        }
    }
}
class Command {

    private String pattern;
    public Command( String pattern ){
        this.pattern = pattern;
    }

    public void executeOn( File file ) throws IOException {
        if( pattern == null ) { 
            System.out.println( "Pattern is null ");
            return;
        }

        String fileName = file.getName();
        boolean jarNameAlreadyPrinted = false;

        ZipInputStream zis = null;
        try{
            zis = new ZipInputStream( new FileInputStream( file ) );

            ZipEntry ze;
            while(( ze = zis.getNextEntry() ) != null ) {
                if( ze.getName().endsWith( pattern )){
                    if( !jarNameAlreadyPrinted ){
                        System.out.println("Contents of: " + file.getCanonicalPath()  );
                        jarNameAlreadyPrinted = true;
                    }
                    System.out.println( "    " + ze.getName() );
                }
                zis.closeEntry();
            }
        }finally{
            if( zis != null ) try {
                zis.close();
            }catch( Throwable t ){}
        }
    }
}

J'espère que cela vous aidera.

3voto

Chris Seline Points 876

Si vous n'aimez pas télécharger et installer des choses, vous pouvez utiliser cette commande en une ligne pour trouver les conflits de jar avec les outils gnu standard. Elle est rudimentaire mais vous pouvez l'étendre à votre guise.

ls *.jar | xargs -n1 -iFILE unzip -l FILE | grep class | sed "s,.* ,," | tr "/" "." | sort | uniq -d | xargs -n1 -iCLASS grep -l CLASS *.jar | sort -u

(il est un peu lent à exécuter si vous avez beaucoup de bocaux)

Explication : Il répertorie tous les fichiers dans tous les pots, recherche les fichiers de classe, trouve les doublons, puis recherche dans les pots d'origine pour voir où ils sont apparus. Il pourrait être plus efficace avec un script plus compliqué.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X