Existe-t-il un outil permettant de déterminer si la même classe existe dans plusieurs fichiers JAR du chemin de classe?

StackOverflow https://stackoverflow.com/questions/135971

  •  02-07-2019
  •  | 
  •  

Question

Si votre chemin de classe contient deux fichiers JAR contenant des versions différentes de la même classe, l'ordre du chemin de classe devient critique.

Je recherche un outil capable de détecter et de signaler de tels conflits potentiels dans un chemin de classe ou un ensemble de dossiers donné.

Certainement un script qui démarre:

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

avec un tri intelligent / uniq / diff / grep / awk a plus tard, un potentiel, mais je me demandais si quelqu'un connaissait des solutions existantes.

Était-ce utile?

La solution

L’outil Tattletale de JBoss est un autre candidat: "Indiquez si un cours / package est situé dans plusieurs fichiers JAR "

Autres conseils

On dirait que jarfish fera ce que vous voulez avec son " dupes " commande.

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

Vous pouvez obtenir les entrées du chemin d'accès aux classes avec System.getProperty ("java.class.path");

Ensuite, parcourez les bocaux, les zips ou les répertoires qui y figurent et collectez toutes les informations sur les classes et repérez celles qui pourraient poser problème.

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

Probablement la propriété java.class.path ne montrera pas toutes les classes si vous courez dans une infrastructure avec un chargement complexe de classes personnalisées (par exemple, j’ai vu une application charger les classes depuis le LDAP), mais cela fonctionnerait certainement pour la plupart des projets. les cas.

Voici un outil qui pourrait vous être utile, je ne l’utilise jamais moi-même, mais essayez-le et laissez-nous savoir le résultat.

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

Si vous allez créer votre propre outil, voici le code que j'utilise pour le même script shell posté auparavant, mais que j'utilise sur ma machine Windows. Il est plus rapide quand il y a des tonnes de fichiers jar.

Vous pouvez l'utiliser et le modifier. Ainsi, au lieu de parcourir récursivement un répertoire, lisez le chemin de la classe et comparez l'attribut time .class.

Il existe une classe de commande que vous pouvez sous-classer si nécessaire. Je pensais à l'option -execute de "rechercher".

Ceci est mon propre code, il n'était donc pas destiné à être "prêt pour la production", juste pour effectuer 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.

Helper Classpath est un plug-in Eclipse qui aide un peu.

Si vous n'aimez pas télécharger et installer des fichiers, vous pouvez utiliser cette commande d'une ligne pour rechercher les conflits de fichiers jar avec les outils gnu standard. C’est rudimentaire, mais vous pouvez l’agrandir à 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

(l'exécution est un peu lente si vous avez beaucoup de bocaux)

Explication: Il répertorie tous les fichiers de tous les fichiers jars, greps pour les fichiers de classe, trouve les doublons, puis insère les fichiers jar originaux pour voir où ils sont apparus. Cela pourrait être rendu plus efficace avec un script plus compliqué.

jarclassfinder est une autre option du plug-in eclipse

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top