Linux cmd to search for a class file among jars irrespective of jar path

LinuxCommand

Linux Problem Overview


I want to search for a particular class file among many jar files without giving the location of each jar file.

Is this possible with a simple command?

I tried this command:

grep Hello.class *.jar

Which did not return a list of jars containing the class. Then I ran the command:

grep Hello.class /full/path/of/jar/file/*.jar

Which did return the relevant jar file. Is there a better way?

Linux Solutions


Solution 1 - Linux

Where are you jar files? Is there a pattern to find where they are?

1. Are they all in one directory?

For example, foo/a/a.jar and foo/b/b.jar are all under the folder foo/, in this case, you could use find with grep:

find foo/ -name "*.jar" | xargs grep Hello.class

Sure, at least you can search them under the root directory /, but it will be slow.

As @loganaayahee said, you could also use the command locate. locate search the files with an index, so it will be faster. But the command should be:

locate "*.jar" | xargs grep Hello.class

Since you want to search the content of the jar files.

2. Are the paths stored in an environment variable?

Typically, Java will store the paths to find jar files in an environment variable like CLASS_PATH, I don't know if this is what you want. But if your variable is just like this:CLASS_PATH=/lib:/usr/lib:/bin, which use a : to separate the paths, then you could use this commend to search the class:

for P in `echo $CLASS_PATH | sed 's/:/ /g'`; do grep Hello.calss $P/*.jar; done

Solution 2 - Linux

Most of the solutions are directly using grep command to find the class. However, it would not give you the package name of the class. Also if the jar is compressed, grep will not work.

This solution is using jar command to list the contents of the file and grep the class you are looking for.

It will print out the class with package name and also the jar file name.

find . -type f -name '*.jar' -print0 |  xargs -0 -I '{}' sh -c 'jar tf {} | grep Hello.class &&  echo {}'

You can also search with your package name like below:

find . -type f -name '*.jar' -print0 |  xargs -0 -I '{}' sh -c 'jar tf {} | grep com/mypackage/Hello.class &&  echo {}'

Solution 3 - Linux

Just go to the directory which contains jars and insert below command:

find *.jar | xargs grep className.class

Hope this helps!

Solution 4 - Linux

   locate *.jar | grep Hello.class.jar

The locate command to search the all path of the particular file and display full path of the file.

example

locate *.jar | grep classic.jar

/opt/ltsp/i386/usr/share/firefox/chrome/classic.jar

/opt/ltsp/i386/usr/share/thunderbird/chrome/classic.jar

/root/.wine/drive_c/windows/gecko/0.1.0/wine_gecko/chrome/classic.jar

/usr/lib/firefox-3.0.14/chrome/classic.jar

/usr/lib/firefox-3.5.2/chrome/classic.jar

/usr/lib/xulrunner-1.9.1.2/chrome/classic.jar

/usr/share/firefox/chrome/classic.jar

/usr/share/thunderbird/chrome/classic.jar

Solution 5 - Linux

Linux, Walkthrough to find a class file among many jars.

Go to the directory that contains the jars underneath.

eric@dev /home/el/kafka_2.10-0.8.1.1/libs $ ls
blah.txt                             metrics-core-2.2.0.jar
jopt-simple-3.2.jar                  scala-library-2.10.1.jar
kafka_2.10-0.8.1.1-sources.jar       zkclient-0.3.jar
kafka_2.10-0.8.1.1-sources.jar.asc   zookeeper-3.3.4.jar
log4j-1.2.15.jar

I'm looking for which jar provides for the Producer class.

Understand how the for loop works:

eric@dev /home/el/kafka_2.10-0.8.1.1/libs $ for i in `seq 1 3`; do
> echo $i
> done
1
2
3

Understand why find this works:

eric@dev /home/el/kafka_2.10-0.8.1.1/libs $ find . -name "*.jar"
./slf4j-api-1.7.2.jar
./zookeeper-3.3.4.jar
./kafka_2.10-0.8.1.1-javadoc.jar
./slf4j-1.7.7/osgi-over-slf4j-1.7.7-sources.jar

You can pump all the jars underneath into the for loop:

eric@dev /home/el/kafka_2.10-0.8.1.1/libs $ for i in `find . -name "*.jar"`; do
> echo $i
> done

./slf4j-api-1.7.2.jar
./zookeeper-3.3.4.jar
./kafka_2.10-0.8.1.1-javadoc.jar
./kafka_2.10-0.8.1.1-sources.jar

Now we can operate on each one:

Do a jar tf on every jar and cram it into blah.txt:

for i in `find . -name "*.jar"`; do echo $i; jar tf $i; done > blah.txt

Inspect blah.txt, it's a list of all the classes in all the jars. You can search that file for the class you want, then look for the jar that came before it, that's the one you want.

Solution 6 - Linux

I have used this small snippet. Might be slower but works every time.

for i in 'find . -type f -name "*.jar"'; do
    jar tvf $i | grep "com.foo.bar.MyClass.clss";
    if [ $? -eq 0 ]; then echo $i; fi;
done

Solution 7 - Linux

Use deepgrep and deepfind. On debian-based systems you can install them by:

sudo apt-get install strigi-utils

Both commands search for nested archives as well. In your case the command would look like:

find . -name "*.jar" | xargs -I {} deepfind {} | grep Hello.class

Solution 8 - Linux

eric@dev /home/el/kafka_2.10-0.8.1.1/libs $ for i in `find . -name "*.jar"`; do
> echo $i
> done

./slf4j-api-1.7.2.jar
./zookeeper-3.3.4.jar
./kafka_2.10-0.8.1.1-javadoc.jar
./kafka_2.10-0.8.1.1-sources.jar

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlwaysALearnerView Question on Stackoverflow
Solution 1 - LinuxBin WangView Answer on Stackoverflow
Solution 2 - LinuxWenbing LiView Answer on Stackoverflow
Solution 3 - Linuxtk_View Answer on Stackoverflow
Solution 4 - LinuxloganaayaheeView Answer on Stackoverflow
Solution 5 - LinuxEric LeschinskiView Answer on Stackoverflow
Solution 6 - Linuxaayush singhalView Answer on Stackoverflow
Solution 7 - LinuxmeliniakView Answer on Stackoverflow
Solution 8 - Linuxuser6319683View Answer on Stackoverflow