5

I really like the javap command line program to decompile and inspect classes however most of the time I can't recollect the fully qualified package name of a class:

javap java.nio.file.Files

If I don't know the package name then I resort to using Google. Is there a built-in java program or slick Linux command that could search and list all the matching packages of a given class name?

szxnyc
  • 2,495
  • 5
  • 35
  • 46
  • Many IDE(s) (like NetBeans, IntelliJ and Eclipse) can do that; I'm not aware of an easy way to do it from the command line. But it is possible or the IDE(s) couldn't do it. – Elliott Frisch Jan 19 '14 at 01:21
  • "Questions asking us to **recommend or find a tool, library or favorite off-site resource** are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it. " – gparyani Jan 19 '14 at 01:33
  • gparyani, sorry I thought it was clear that my solution thus far has been Google. – szxnyc Jan 21 '14 at 21:41

1 Answers1

7

Searches all jars:

find <path> -name "*.jar" -exec jar -tf {} \; | grep "/<classname>\.class\$"

example:

find ~/.ivy2/ -name "*.jar" -exec jar -tf {} \; | grep "/Filter\.class\$"

output:

javax/servlet/Filter.class
javax/servlet/Filter.class
javax/servlet/Filter.class
org/scalatest/Filter.class
org/scalatest/Filter.class
org/fusesource/scalate/filter/Filter.class
org/fusesource/scalate/filter/Filter.class
scala/tools/scalap/scalax/rules/Filter.class
org/apache/ivy/util/filter/Filter.class
com/foursquare/fongo/impl/Filter.class
com/foursquare/fongo/impl/Filter.class
com/foursquare/fongo/impl/Filter.class
shapeless/Filter.class

I'm not personally in love with this solution.

To search all class files just use find:

find <path> -name "*.class"
yǝsʞǝla
  • 16,272
  • 2
  • 44
  • 65
  • Although it does the job, I agree definitely not an elegant enough solution to this problem. I'll be using this in combination with Google for now. Thanks – szxnyc Jan 21 '14 at 21:45
  • Wish there was a way to refine this even further to only list the classes which have a main method. – Craig Nov 27 '15 at 10:30
  • 1
    You can get `main` and other class info from `javap`, but unfortunately you can't pipe unzipped jar output to `javap`. You can instead `mkdir /tmp/d`, then `find` and `unzip -d /tmp/d` and run `javap ` and grep for `public static void main(java.lang.String[]);`. Afterwards `rm -rf /tmp/d/*` and proceed to next found jar. Additionally a jar can have nested jars in it, so once you unzip the main jar you can unzip other jars recursively in-place. If I have time I'll write a script for it but it's not a oneliner. – yǝsʞǝla Nov 28 '15 at 02:10
  • I wanted to try another approach like loading classes/jars from a Java program and using reflection instead. Maybe it's possible to leverage some libraries from Java IDEs for that. – yǝsʞǝla Nov 28 '15 at 02:13
  • 1
    Actually I noticed that `javap` takes a classpath, so no need to create temp dirs. Something like this would work in combination with find: http://stackoverflow.com/questions/1171549/how-do-i-print-the-class-structures-in-a-jar-file-using-the-javap-tool – yǝsʞǝla Nov 28 '15 at 02:54
  • I liked this method but it didn't show the jar file that contained the class. So I found this solution that did show the jar file: https://stackoverflow.com/a/19261547/7634896 – ktbos May 29 '18 at 19:30