Esiste uno strumento per scoprire se esiste la stessa classe in più vasetti nel percorso di classe?

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

  •  02-07-2019
  •  | 
  •  

Domanda

Se nel tuo percorso di classe sono presenti due vasetti che contengono versioni diverse della stessa classe, l'ordine del percorso di classe diventa critico.

Sto cercando uno strumento in grado di rilevare e contrassegnare tali potenziali conflitti in un determinato percorso di classe o set di cartelle.

Certamente uno script che inizia:

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

con qualche ordinamento intelligente / uniq / diff / grep / awk in seguito ha delle potenzialità, ma mi chiedevo se qualcuno fosse a conoscenza di soluzioni esistenti.

È stato utile?

Soluzione

Lo strumento Tattletale di JBoss è un altro candidato: " Spot se una classe / pacchetto si trova in più file JAR "

Altri suggerimenti

Sembra che jarfish farà quello che vuoi con i suoi " dupes " comando.

Penso che non sarebbe troppo difficile scrivere uno strumento per te stesso.

Puoi ottenere le voci del percorso di classe con System.getProperty (" java.class.path ");

E poi cammina attraverso i barattoli, le zip o le directory elencate lì e raccogli tutte le informazioni sulle classi e scopri quelle che potrebbero causare problemi.

Questa attività richiede al massimo 1 o 2 giorni. Quindi puoi caricare questa classe direttamente nella tua applicazione e generare un rapporto.

Probabilmente la proprietà java.class.path non mostrerà tutte le classi se si esegue in qualche infrastruttura con caricamento di classi personalizzato complesso (ad esempio una volta ho visto un'app che carica le classi dal LDAP) ma funzionerebbe sicuramente per la maggior parte di i casi.

Ecco uno strumento che potresti trovare utile, non l'ho mai usato da solo, ma provalo e facci sapere il risultato.

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

Se hai intenzione di creare il tuo strumento, ecco il codice che uso per lo stesso script di shell pubblicato in precedenza, ma che utilizzo sul mio computer Windows. Funziona più velocemente quando ci sono tonnellate di file jar.

Puoi usarlo e modificarlo in modo che invece di ricorrere in modo ricorsivo a una directory, leggi il percorso della classe e confronta l'attributo time.

Esiste una classe Command che puoi sottoclassare se necessario, stavo pensando nell'opzione -execute di " find "

Questo è il mio codice, quindi non è stato pensato per essere "pronto per la produzione", solo per fare il lavoro.

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 ){}
        }
    }
}

Spero che questo aiuti.

Classpath Helper è un plug-in Eclipse che aiuta un po '.

Se non ti piace scaricare e installare roba, puoi usare questo comando a una riga per trovare conflitti jar con gli strumenti gnu standard. È rudimentale ma puoi espanderlo come vuoi.

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

(è un po 'lento da eseguire se hai molti barattoli)

Spiegazione: Elenca tutti i file in tutti i vasetti, greps per i file di classe, trova duplicati, quindi greps i vasetti originali per vedere dove sono apparsi. Potrebbe essere reso più efficiente con uno script più complicato.

jarclassfinder è un'altra opzione di plug-in eclipse

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top