2008-09-25 6 views
17

Wenn Sie zwei Klassen in Ihrem Klassenpfad haben, die verschiedene Versionen derselben Klasse enthalten, wird die Reihenfolge der Klassenpfade kritisch.Gibt es ein Tool zu entdecken, ob die gleiche Klasse in mehreren Gläsern im Klassenpfad existiert?

Ich bin auf der Suche nach einem Werkzeug, das solche möglichen Konflikte in einem bestimmten Klassenpfad oder Satz von Ordnern erkennen und kennzeichnen kann.

Sicherlich ein Skript, das beginnt:

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

mit einigen cleveren Art/uniq/diff/grep/awk später hat Potenzial, aber ich frage mich, ob jemand von irgendwelchen vorhandenen Lösungen kennt.

Antwort

6

Das Tattletale Tool von JBoss ist ein weiterer Kandidat: „Stelle, wenn eine Klasse/Paket in mehreren JAR-Dateien befindet sich“

+0

Versuchen Sie Jarfish auch (meine andere Antwort); Ich benutzte es erfolgreich –

+0

Yup! Entweder dies oder http://stackoverflow.com/questions/135971/is-there-a-tool-to-discover-if-the-same-class-exists-in-multiple-jars-in-the-clas/4516827 # 4516827 sollte den Trick machen! –

+0

Gibt es ein Tool/einen Weg, der nur verwendete (importierte) Klassen filtert? Wir haben viele Klassen in unserem Klassenpfad, die eigentlich nie benutzt werden –

1
+0

Beide scheinen das Gegenteil von dem zu tun, was ich will: Sie finden eine gegebene Klasse in einer Reihe von Gläsern. Ich möchte widersprüchliche Klassen in einem bestimmten Klassenpfad oder einer Gruppe von Gläsern finden. –

+0

In welcher Weise ist das Gegenteil? Sie listen auf, welche JARs einer bestimmten Klasse gefunden werden können, und wenn es mehrere Übereinstimmungen gibt, listen sie alle auf - das ist Ihre Konfliktliste. – skaffman

+0

Aber ich möchte jede Instanz einer Klasse in mehreren Gläsern entdecken. Ich müsste whichj für jede Klasse in meinem CLASSPATH ausführen und nach Duplikaten suchen (sort | uniq | diff) - nur eine langsamere Version meines Brute-Force-Vorschlags in der Frage. –

4

denke ich, es nicht zu hart wäre, ein Werkzeug für die Sie sich selbst zu schreiben.

Sie können die Klassenpfadeinträge mit System.getProperty ("java.class.path") abrufen;

Und dann gehen Sie durch die Gläser, Reißverschlüsse oder Verzeichnisse aufgelistet und sammeln Sie alle Informationen über die Klassen und finden Sie diejenigen, die Probleme verursachen könnten.

Diese Aufgabe dauert höchstens 1 oder 2 Tage. Dann können Sie diese Klasse direkt in Ihre Anwendung laden und einen Bericht generieren.

Wahrscheinlich werden die Klassen java.class.path nicht alle Klassen anzeigen, wenn Sie in einer Infrastruktur mit komplexen benutzerdefinierten Klassen laden (zum Beispiel habe ich einmal eine App gesehen, die die Klassen aus dem LDAP laden), aber es würde sicherlich für die meisten funktionieren der Fälle.

Heres ein Werkzeug, das Sie nützlich finden könnten, ich habe es nie selbst benutzt, aber versuchen Sie es und lassen Sie uns das Ergebnis wissen.

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

Wenn Sie Ihr eigenes Werkzeug gehen zu schaffen, hier ist der Code, den ich für den gleichen Shell-Skript vor geschrieben verwenden, aber, dass ich auf meinem Windows-Rechner verwenden. Es läuft schneller, wenn es viele JAR-Dateien gibt.

Sie können es verwenden und ändern, anstatt ein Verzeichnis rekursiv zu durchlaufen, den Klassenpfad zu lesen und das Zeitattribut .class zu vergleichen.

Es gibt eine Befehlsklasse Sie können bei Bedarf eine Unterklasse, war ich in der -execute Option „finden“

Dieser meinen eigenen Code zu denken, so war es nicht „Produktion bereit“ soll, nur um mach die Arbeit.

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

Ich hoffe, das hilft.

+2

Warum würden Sie 1 oder 2 Tage verbringen, wenn es wahrscheinlich Tools gibt, die es für Sie tun? Wenn Sie nicht für 1 oder 2 Tage an Ihrem Projekt arbeiten, ist es besser ein Hobby oder Sie machen etwas falsch. – ArtB

+0

Der Link http://www.jgoodies.com/freeware/jpathreport/features.html ist tot. Kannst du es bitte aktualisieren? –

0

jarclassfinder ist eine weitere Eclipse-Plugin Option

+0

Die Produktbeschreibung besagt, dass es ein "Plug-in-Dienstprogramm zum Suchen von Java Archive (JAR) -Dateien ist, die eine bestimmte Klasse für den Java-Build-Pfad eines Projekts enthalten." Das ist das Gegenteil von dem, was ich brauche. Ich muss wissen, ob die gleiche Klasse in zwei Gläsern ist, NICHT, welches Glas eine gegebene Klasse ist. –

+1

Es wird feststellen, dass eine gegebene Klasse in mehreren Gläsern ist, aber es wird nicht alle Fälle von Klassen in mehreren Gläsern finden. –

8

wie jarfish Looks werden tun, was Sie mit dem "Betrogene" Befehl wollen.

+0

Schön! Entweder dies oder http://stackoverflow.com/questions/135971/is-there-a-tool-to-discover-if-the-same-class-exists-in-multiple-jars-in-the-clas/4523559 # 4523559 sollte den Trick machen. –

+0

Das hat funktioniert. Ich glaube nicht, dass Tattletale JAR-Dateien sehr gut verarbeitet. Wenn es so ist, habe ich es nicht herausgefunden. –

0

Wenn Sie nicht mögen das Herunterladen und Sachen zu installieren Sie diese ein Zeilenbefehl verwenden können jar Konflikte mit finden Standard-Gnu-Tools. Es ist rudimentär, aber Sie können es erweitern, wie Sie wollen.

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 

(es ist ein bisschen langsam laufen, wenn Sie eine Menge Gläser haben)

Erläuterung: Es listet alle Dateien in allen Gläsern, greps für Klassendateien, findet Betrogenen, dann greps die Originalgläser, um zu sehen, wo sie erschienen. Es könnte mit einem komplizierteren Skript effizienter gemacht werden.

Verwandte Themen