Trouvez une part de classe à l'intérieur des dizaines de fichiers JAR?
-
20-09-2019 - |
Question
Comment voulez-vous trouver un nom de classe particulier à l'intérieur de nombreux fichiers jar?
(Vous recherchez le nom de la classe réelle, pas les classes qui y font référence.)
La solution
Eclipse peut le faire, il suffit de créer un projet (temporaire) et de mettre vos bibliothèques sur les projets classpath. Ensuite, vous pouvez facilement trouver les classes.
Un autre outil, qui vient à l'esprit, est Java Decompiler. Il peut ouvrir beaucoup de pots à la fois et aide à trouver des cours aussi bien.
Autres conseils
Unix
Utilisez la jar
(ou unzip -v
), grep
, et les commandes de find
.
Par exemple, ce qui suit la liste de tous les fichiers de classe qui correspondent à un nom donné:
for i in *.jar; do jar -tvf "$i" | grep -Hsi ClassName && echo "$i"; done
Si vous connaissez la liste complète des archives Java que vous souhaitez rechercher, vous pouvez placer tous dans le même répertoire en utilisant des liens (symboliques).
Ou utilisez find
(sensible à la casse) pour trouver le fichier JAR qui contient un nom de classe donnée:
find path/to/libs -name '*.jar' -exec grep -Hls ClassName {} \;
Par exemple, pour trouver le nom de l'archive contenant IdentityHashingStrategy
:
$ find . -name "*.jar" -exec grep -Hsli IdentityHashingStrategy {} \;
./trove-3.0.3.jar
Si le JAR pourrait être où dans le système et le locate
commande est disponible:
for i in $(locate "*.jar");
do echo $i; jar -tvf $i | grep -Hsi ClassName;
done
de Windows
Ouvrir un commande rapide, changer le répertoire (ou le répertoire ancêtre) contenant les fichiers JAR, puis:
for /R %G in (*.jar) do @jar -tvf "%G" | find "ClassName" > NUL && echo %G
Voilà comment cela fonctionne:
-
for /R %G in (*.jar) do
- boucle sur tous les fichiers JAR, traversant récursive répertoires; stocker le nom du fichier en% G. -
@jar -tvf "%G" |
- exécutez la commande Java Archive pour lister tous les noms de fichiers dans l'archive donnée, et écrire les résultats à la sortie standard; le symbole@
supprime l'impression invocation de la commande. -
find "ClassName" > NUL
- recherche entrée standard, canalisé depuis la sortie de la commande jar, le nom de classe donnée; cela misERRORLEVEL
à 1 ssi il y a un match (sinon 0). -
&& echo %G
- IFFERRORLEVEL
est non nul, écrire le nom du fichier archive Java sortie standard (la console) .
Web
Utilisez un qui scanne fichiers JAR
.il y a quelque temps, je l'ai écrit un programme juste pour que: https://github.com/javalite/ pot-explorateur
grep -l "classname" *.jar
vous donne le nom du pot
find . -name "*.jar" -exec jar -t -f {} \; | grep "classname"
vous donne le paquet de la classe
#!/bin/bash
pattern=$1
shift
for jar in $(find $* -type f -name "*.jar")
do
match=`jar -tvf $jar | grep $pattern`
if [ ! -z "$match" ]
then
echo "Found in: $jar"
echo "$match"
fi
done
Je ne savais pas d'un utilitaire pour le faire quand je suis tombé sur ce problème, donc j'écrit ce qui suit:
public class Main {
/**
*
*/
private static String CLASS_FILE_TO_FIND =
"class.to.find.Here";
private static List<String> foundIn = new LinkedList<String>();
/**
* @param args the first argument is the path of the file to search in. The second may be the
* class file to find.
*/
public static void main(String[] args) {
if (!CLASS_FILE_TO_FIND.endsWith(".class")) {
CLASS_FILE_TO_FIND = CLASS_FILE_TO_FIND.replace('.', '/') + ".class";
}
File start = new File(args[0]);
if (args.length > 1) {
CLASS_FILE_TO_FIND = args[1];
}
search(start);
System.out.println("------RESULTS------");
for (String s : foundIn) {
System.out.println(s);
}
}
private static void search(File start) {
try {
final FileFilter filter = new FileFilter() {
public boolean accept(File pathname) {
return pathname.getName().endsWith(".jar") || pathname.isDirectory();
}
};
for (File f : start.listFiles(filter)) {
if (f.isDirectory()) {
search(f);
} else {
searchJar(f);
}
}
} catch (Exception e) {
System.err.println("Error at: " + start.getPath() + " " + e.getMessage());
}
}
private static void searchJar(File f) {
try {
System.out.println("Searching: " + f.getPath());
JarFile jar = new JarFile(f);
ZipEntry e = jar.getEntry(CLASS_FILE_TO_FIND);
if (e == null) {
e = jar.getJarEntry(CLASS_FILE_TO_FIND);
if (e != null) {
foundIn.add(f.getPath());
}
} else {
foundIn.add(f.getPath());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Pour trouver des pots qui correspondent à une chaîne donnée:
find . -name \*.jar -exec grep -l YOUR_CLASSNAME {} \;
Il y a aussi deux utilitaires différents appelés à la fois « JarScan » qui font exactement ce que vous demandez: JarScan (inetfeedback.com) et JarScan ( java.net)
script de user1207523 fonctionne bien pour moi. Voici une variante qui recherche les fichiers JAR à l'aide recusively trouver au lieu de la simple expansion;
#!/bin/bash
for i in `find . -name '*.jar'`; do jar -tf "$i" | grep $1 | xargs -I{} echo -e "$i : {}" ; done
Je l'ai toujours utilisé ce sous Windows et son travaillé exceptionnellement bien.
findstr /s /m /c:"package/classname" *.jar, where
findstr.exe est livré en standard avec Windows et les params:
- / s = récursive
- / m = imprimer uniquement le nom il y a une correspondance
- / c = chaîne de caractères (dans ce cas, vos noms de nom + classe package séparés par '/')
Espérons que cela aide quelqu'un.
Une solution de bash script
utilisant unzip (zipinfo)
. Testé sur Ubuntu 12
.
#!/bin/bash
# ./jarwalker.sh "/a/Starting/Path" "aClassName"
IFS=$'\n'
jars=( $( find -P "$1" -type f -name "*.jar" ) )
for jar in ${jars[*]}
do
classes=( $( zipinfo -1 ${jar} | awk -F '/' '{print $NF}' | grep .class | awk -F '.' '{print $1}' ) )
if [ ${#classes[*]} -ge 0 ]; then
for class in ${classes[*]}
do
if [ ${class} == "$2" ]; then
echo "Found in ${jar}"
fi
done
fi
done
J'ai trouvé cette nouvelle façon
bash $ ls -1 | xargs -i -t jar -tvf '{}'| grep Abstract
jar -tvf activation-1.1.jar
jar -tvf antisamy-1.4.3.jar
2263 Thu Jan 13 21:38:10 IST 2011 org/owasp/validator/html/scan/AbstractAntiSamyScanner.class
...
Donc, ce indique le pot et la classe se trouve, si vous voulez, vous pouvez donner ls -1 * .jar ou entrée xargs avec commande find HTH Quelqu'un.
Il suffit d'utiliser FindClassInJars util, il est un programme simple de swing, mais utile. Vous pouvez vérifier le code source ou télécharger le fichier jar http://code.google. com / p / trouver classe en pots /
Je ne sais pas pourquoi les scripts ici ont jamais vraiment travaillé pour moi. Cela fonctionne:
#!/bin/bash
for i in *.jar; do jar -tf "$i" | grep $1 | xargs -I{} echo -e "$i : {}" ; done
Pour rechercher tous les fichiers jar dans un répertoire donné pour une classe particulière, vous pouvez faire ceci:
ls *.jar | xargs grep -F MyClass
ou, encore plus simple,
grep -F MyClass *.jar
Sortie ressemble à ceci:
Binary file foo.jar matches
Il est très rapide parce que l'option -F signifie recherche de chaîne fixe, il ne charge pas le moteur de regex pour chaque invocation grep. Si vous avez besoin, vous pouvez toujours omettre l'option -F et utiliser des expressions rationnelles.
Script pour trouver le fichier jar: find_jar.sh
IFS=$(echo -en "\n\b") # Set the field separator newline
for f in `find ${1} -iname *.jar`; do
jar -tf ${f}| grep --color $2
if [ $? == 0 ]; then
echo -n "Match found: "
echo -e "${f}\n"
fi
done
unset IFS
Utilisation: ./find_jar.sh
Ceci est similaire à la plupart des réponses ici. Mais il ne sort que le nom du fichier, si grep trouve quelque chose. Si vous voulez supprimer la sortie de grep vous pouvez rediriger que vers / dev / null, mais je préfère voir la sortie de grep et pour que je puisse utiliser des noms de classe partielle et trouver le bon dans une liste de sortie indiqué.
Le nom de la classe peut être à la fois simple nom de classe comme « String » ou nom qualifié comme « java.lang.String »
Pour ajouter encore un autre outil ... c'est un outil très simple et utile pour les fenêtres. Un fichier exe simple, vous cliquez sur, donner un répertoire pour rechercher, un nom de classe et il trouvera le fichier jar qui contient cette classe. Oui, il est récursive.
Vous pouvez trouver une classe dans un répertoire complet des pots avec un peu de shell:
Vous recherchez la classe "foobar":
LIB_DIR=/some/dir/full/of/jarfiles
for jarfile in $(find $LIBDIR -name "*.jar"); do
echo "--------$jarfile---------------"
jar -tvf $jarfile | grep FooBar
done
Une chose à ajouter à tous ce qui précède: si vous n'avez pas l'exécutable jar disponible (il est livré avec le JDK, mais pas avec le JRE), vous pouvez utiliser unzip (ou WinZip, ou autre) pour accomplir la même chose.
auto promotion éhontée, mais vous pouvez essayer un utilitaire je l'ai écrit: http://sourceforge.net/projects/zfind
Il prend en charge les archives les plus communs / fichiers compressés (pot, zip, tar, tar.gz, etc.) et, contrairement à beaucoup d'autres trouveurs pot / zip, prend en charge les fichiers zip imbriqués (zip dans les zip, pot à l'intérieur de pot, etc.) jusqu'à la profondeur illimitée.
Un peu en retard à la fête, mais quand même ...
Je me sers JarBrowser pour trouver où jar une classe particulière est présente. Il est a une interface graphique facile à utiliser qui vous permet de parcourir le contenu de tous les pots dans le chemin sélectionné.
Après script vous aider
for file in *.jar
do
# do something on "$file"
echo "$file"
/usr/local/jdk/bin/jar -tvf "$file" | grep '$CLASSNAME'
done
Celui-ci fonctionne bien dans MinGW (fenêtres d'environnement bash) ~ gitbash
Mettez cette fonction dans votre fichier .bashrc dans votre répertoire:
# this function helps you to find a jar file for the class
function find_jar_of_class() {
OLD_IFS=$IFS
IFS=$'\n'
jars=( $( find -type f -name "*.jar" ) )
for i in ${jars[*]} ; do
if [ ! -z "$(jar -tvf "$i" | grep -Hsi $1)" ] ; then
echo "$i"
fi
done
IFS=$OLD_IFS
}
Grepj est un utilitaire de ligne de commande pour rechercher les classes dans les fichiers jar. Je suis l'auteur de l'utilitaire.
Vous pouvez exécuter l'utilitaire comme grepj package.Class my1.jar my2.war my3.ear
jar multiples, l'oreille, les fichiers de guerre peuvent être fournis. Pour une utilisation d'utilisation avancée pour fournir une liste des bocaux à rechercher.
Vérifier ce plugin pour Eclipse qui peut faire le travail que vous recherchez.
Dans un environnement Linux, vous pouvez faire ce qui suit:
$ find <base_dir> -name *.jar -print0 | xargs -0 -l jar tf | grep <name>
Où nom est le nom du fichier de classe que vous êtes à la recherche à l'intérieur des pots répartis dans la hiérarchie des répertoires ancrés au base_dir .
Vous pouvez utiliser locate
et grep
:
locate jar | xargs grep 'my.class'
Assurez-vous que vous exécutez updatedb
avant d'utiliser locate
.
Cette .. vous pouvez trouver tout fichier classpath .. .. garantie
import java.net.URL;
import java.net.URLClassLoader;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class FileFinder {
public static void main(String[] args) throws Exception {
String file = <your file name>;
ClassLoader cl = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader)cl).getURLs();
for(URL url: urls){
listFiles(file, url);
}
}
private static void listFiles(String file, URL url) throws Exception{
ZipInputStream zip = new ZipInputStream(url.openStream());
while(true) {
ZipEntry e = zip.getNextEntry();
if (e == null)
break;
String name = e.getName();
if (name.endsWith(file)) {
System.out.println(url.toString() + " -> " + name);
}
}
}
}
Dans Eclipse, vous pouvez utiliser l'ancienne mais toujours utile plug-in jarsearch