How to search for a string in JAR files
Asked Answered
T

11

83

My application is built on Java EE.

I have approximately 50 jars in this application.

Is it possible to search for a particular keyword (actually I want to search for a keyword BEGIN REQUEST)?

Tades answered 26/4, 2012 at 9:49 Comment(3)
Hope this helps -> unix.com/unix-dummies-questions-answers/… considering your os is linux. good luck !!Primeval
are you trying to do this at runtime, or as a part of debugging a problem?Aureomycin
What do you mean with "keyword"? Jar files consist of java classes, which contain identifiers and strings (and other content). Do you want to find classes which define or use a string "BEGIN REQUEST "?Rang
A
162

You can use zipgrep on Linux or OSX:

zipgrep "BEGIN REQUEST" file.jar

If you wish to search a number of jars, do

find libdir -name "*.jar" -exec zipgrep "BEGIN REQUEST" '{}' \;

where libdir is a directory containing all jars. The command will recursively search subdirectories too.

For windows, you can download cygwin and install zipgrep under it: http://www.cygwin.com/

Edit 1

To view the name of the file that the expression was found you could do,

find libdir -name "*.jar" | xargs -I{} sh -c 'echo searching in "{}"; zipgrep "BEGIN REQUEST" {}'

Edit 2

Simpler version of Edit 1

find libdir -name "*.jar" -print -exec zipgrep "BEGIN REQUEST" '{}' \;
Aureomycin answered 26/4, 2012 at 9:57 Comment(7)
You can also rockout with zipgrep on OSX and the above works perfectly. Much appreciated fella!Legation
is there a way I can list from which jar each line comes from?Finnie
I get error - invalid option 'c', while executing the last commandIsotron
@catchingUp maybe sh is pointing to some other shell on your machine. Try bash instead of shAureomycin
@Legation added OSX to the answerRoomette
What a lifesaver this is. If you are using windows 10 and above install a Linux distro. You might need to install the unzip package and search for the string.Volley
How do you " install zipgrep under" CygWin??Cindelyn
D
4

Caution: This is not an accurate answer, it's only a quick heuristic approach. If you need to find something like the name of a class (e.g., which jar has class Foo?) or maybe a method name, then this may work.

grep --text 'your string' your.jar

This will search the jar file as if it were text. This is quicker because it doesn't expand the archive, but that is also why it is less accurate. If you need to be exhaustive then this is not the approach you should use, but if you want to try something a little quicker before pulling out zipgrep this is a good approach.


From man grep,

  -a, --text
          Process  a binary file as if it were text; this is equivalent
          to the --binary-files=text option.
Drida answered 9/9, 2016 at 19:3 Comment(2)
I feel that jar tf is better for getting a list of files in a jar file. The file contents are compressed, and so cannot be searched as is. I doubt that grep --text is useful.Verism
@Verism Like I said, this is not a 100% accurate answer, just a quick heuristic.Drida
F
3

in android i had to search both jar and aar files for a certain string i was looking for here is my implementation on mac:

find . -name "*.jar" -o -name "*.aar" | xargs -I{} zipgrep "AssestManager" {}

essentially finds all jars and aar files in current direclty (and find command is recursive by default) pipes the results to zipgrep and applies each file name as a parameter via xargs. the brackets at the end tell xargs where to put the file name you got from the find command. if you want to search the entire home directory just change the find . to find ~

Friulian answered 8/11, 2018 at 9:51 Comment(3)
This works to print the file names, but the jar files path is missing, can we print the jar file paths?Somme
so you want the file name and the jar its contained in to print on the same line. might need to write a script to make ti cleaner.Friulian
@kanaparthikiran, this will print the path of jar file find * -type f -name '*.jar' -exec grep -l 'Expression.class' '{}' \;Grecian
E
2

Searching inside a jar or finding the class name which contains a particular text is very easy with WinRar search. Its efficient and always worked for me atleast.

just open any jar in WinRar, click on ".." until you reach the top folder from where you want to start the search(including subfolders).

Make sure to check the below options:

1.) Provide '*' in fields 'file names to find', 'Archive types'

2.) select check boxes 'find in subfolders', 'find in files', 'find in archives'.

Eulaheulalee answered 5/8, 2016 at 10:32 Comment(0)
T
2

Found the script below on alvinalexander.com. It is simple but useful for searching through all jar files in the current directory

#!/bin/sh

LOOK_FOR="codehaus/xfire/spring"

for i in `find . -name "*jar"`
do
  echo "Looking in $i ..."
  jar tvf $i | grep $LOOK_FOR > /dev/null
  if [ $? == 0 ]
  then
    echo "==> Found \"$LOOK_FOR\" in $i"
  fi
done

Replace "codehaus..." with your query, i.e. a class name.

Sample output:

$ ./searchjars.sh

Looking in ./activation-1.1.jar ...
Looking in ./commons-beanutils-1.7.0.jar ...
Looking in ./commons-codec-1.3.jar ...
Looking in ./commons-pool.jar ...
Looking in ./jaxen-1.1-beta-9.jar ...
Looking in ./jdom-1.0.jar ...
Looking in ./mail-1.4.jar ...
Looking in ./xbean-2.2.0.jar ...
Looking in ./xbean-spring-2.8.jar ...
Looking in ./xfire-aegis-1.2.6.jar ...
Looking in ./xfire-annotations-1.2.6.jar ...
Looking in ./xfire-core-1.2.6.jar ...
Looking in ./xfire-java5-1.2.6.jar ...
Looking in ./xfire-jaxws-1.2.6.jar ...
Looking in ./xfire-jsr181-api-1.0-M1.jar ...
Looking in ./xfire-spring-1.2.6.jar ...
==> Found "codehaus/xfire/spring" in ./xfire-spring-1.2.6.jar
Looking in ./XmlSchema-1.1.jar ...
Thanh answered 9/10, 2019 at 13:2 Comment(0)
W
2

One-liner solution that prints file names for which the search string is found, it doesn't jam your console with unnecessary "searching in" logs::

find libdir -wholename "*.jar" | xargs --replace={} bash -c 'zipgrep "BEGIN REQUEST" {} &>/dev/null; [ $? -eq 0 ] && echo "{}";'

Edit:: Removing unnecessary if statement, and using -name instead of -wholename (actually, I used wholename, but it depends on your scenario and preferences)::

find libdir -name "*.jar" | xargs --replace={} bash -c 'zipgrep "BEGIN REQUEST" {} &>/dev/null && echo "{}";'

You can also use sh instead of bash. One last thing, --replace={} is just equivalent to -I{} (I usually use long option formats, to avoid having to go into the manual again later).

Wraith answered 12/1, 2020 at 20:5 Comment(0)
M
1

Fastjar - very old, but fit your needs. Fastjar contains tool called jargrep (or grepjar). Used the same way as grep:

>  locate .jar | grep hibernate | xargs grepjar -n 'objectToSQLString'

org/hibernate/type/EnumType.class:646:objectToSQLString
org/hibernate/sql/Update.class:576:objectToSQLString
org/hibernate/sql/Insert.class:410:objectToSQLString
org/hibernate/usertype/EnhancedUserType.class:22:objectToSQLString
org/hibernate/persister/entity/SingleTableEntityPersister.class:2713:objectToSQLString
org/hibernate/hql/classic/WhereParser.class:1910:objectToSQLString
org/hibernate/hql/ast/tree/JavaConstantNode.class:344:objectToSQLString
org/hibernate/hql/ast/tree/BooleanLiteralNode.class:240:objectToSQLString
org/hibernate/hql/ast/util/LiteralProcessor.class:1363:objectToSQLString
org/hibernate/type/BigIntegerType.class:114:objectToSQLString
org/hibernate/type/ShortType.class:189:objectToSQLString
org/hibernate/type/TimeType.class:307:objectToSQLString
org/hibernate/type/CharacterType.class:210:objectToSQLString
org/hibernate/type/BooleanType.class:180:objectToSQLString
org/hibernate/type/StringType.class:166:objectToSQLString
org/hibernate/type/NumericBooleanType.class:128:objectToSQLString
org/hibernate/type/CustomType.class:543:objectToSQLString
org/hibernate/type/TimeZoneType.class:204:objectToSQLString
org/hibernate/type/DateType.class:343:objectToSQLString
org/hibernate/type/LiteralType.class:18:objectToSQLString
org/hibernate/type/ByteType.class:189:objectToSQLString
org/hibernate/type/LocaleType.class:259:objectToSQLString
org/hibernate/type/CharBooleanType.class:171:objectToSQLString
org/hibernate/type/TimestampType.class:409:objectToSQLString
org/hibernate/type/CurrencyType.class:256:objectToSQLString
org/hibernate/type/AbstractCharArrayType.class:219:objectToSQLString
org/hibernate/type/FloatType.class:177:objectToSQLString
org/hibernate/type/DoubleType.class:173:objectToSQLString
org/hibernate/type/LongType.class:223:objectToSQLString
org/hibernate/type/IntegerType.class:188:objectToSQLString
Matti answered 1/3, 2017 at 12:18 Comment(0)
B
1

Try ugrep -z

ugrep can do this and is available for many operating systems.

PS C:\temp\mywebapp> ugrep -z "Entity Resolver"
WEB-INF\lib\jaxws-rt-2.3.5.jar{com/sun/xml/ws/util/resources/Messages_en.properties}:P-065 = Entity Resolver did not provide SYSTEM id; may affect relative URIs
WEB-INF\lib\jaxws-rt-2.3.5.jar{com/sun/xml/ws/util/resources/Messages_en_de.properties}:P-065 = Entity Resolver hat keine SYSTEM-ID angegeben. Dies kann sich auf relative URIs auswirken
WEB-INF\lib\jaxb-xjc-2.3.5.jar{com/sun/xml/dtdparser/resources/Messages.properties}:P-065 = Entity Resolver did not provide SYSTEM id; may affect relative URIs
WEB-INF\lib\woodstox-core-6.2.8.jar{com/ctc/wstx/shaded/msv_core/scanner/dtd/resources/Messages_en.properties}:P-065 = Entity Resolver did not provide SYSTEM id; may affect relative URIs

PS C:\temp\mywebapp>

Needs '-z'

Note: you will need the "-z" parameter. Otherwise ZIPs (and other archive types) won't be won't be searched:

PS C:\temp\mywebapp> ugrep "Entity Resolver"

PS C:\temp\mywebapp>

More options

There are a bunch of other advanced options for archives:

https://ugrep.com/#commands:~:text=and%20its%20argument-,Archives%20and%20compressed%20files,-%2Dz

Archives and compressed files
-z
also search zip/7z/tar/pax/cpio archives, tarballs and gz/Z/bz/bz2/lzma/xz/lz4/zstd/brotli compressed files

-z --zmax=2
also search archives, tarballs and compressed files stored within archives (max 2 levels)

-z -I --zmax=2
same as above, but ignore binary files and also those in (nested) archives and compressed files

-z -tc,cpp
search C and C++ source code files and also those in archives, see also ug -tlist for a list of file types

-z -g"*.txt,*.md"
search files matching the globs *.txt and *.md and also those in archives, see also ug --help globs

-z -g"^bak/"
exclude all bak directories from the search and skip those in archives, see also ug --help globs
Brahear answered 24/4 at 9:53 Comment(0)
R
0

The below command shows the results with the file name and jar file name.

  1. To find the string in the list of jar file.

    find <%PATH of the Folder where you need to search%> -name "*.jar" -print -exec zipgrep "jar$|<%STRING THAT YOU NEED TO FIND>" '{}' \;
    
  2. To find the class name in the list of jar file.

    find . -name "*.jar" -print -exec jar tvf {} \; |grep -E "jar$|<%CLASS NAME THAT YOU NEED TO FIND>\.class"
    
Reuben answered 26/2, 2013 at 0:57 Comment(0)
E
0

Using jfind jar

JFind can find a Java class file anywhere on the filesystem, even if it is hidden many levels deep in a jar within an ear within a zip!

http://jfind.sourceforge.net/

Erdmann answered 1/2, 2018 at 9:45 Comment(1)
He's looking for strings, not class files. Read the question.Collocation
T
0

Although there are ways of doing it using a decomplier or eclipse , but it gets tricky when those jars are not part of your project , or its particularly painful when using decompiler and you have 100s or 1000s of jars placed in several folders.

I found this CMD command useful , which helps in finding the class names in list of jars present in directory .

forfiles /S /M *.jar /C "cmd /c jar -tvf @file | findstr "classname" && echo @path

You can either navigate to your desired path , and open cmd from there and run this command OR give the path directly in command itself , like this

forfiles /S /M *.jar /C "cmd /c jar -tvf @file | findstr /C:"classname" && echo @path

My use case was to find a particular class in Glassfish , so command will look something like this :

enter image description here

Tailpiece answered 20/8, 2020 at 10:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.