PUBLIC OBJECT

Stupid Bash Tricks: Find a file in a pile of jars

My latest code depends on ServiceMBeanSupport.class from JBoss. The problem is that JBoss is composed of dozens of .jar files and I'm not sure which one contains the file I'm interested in.

Tools

  • find this command will list all the files that meet the specified metadata. It can also execute a command for each file found, using that filename as a parameter. For example, to remove all the CVS folders in a directory tree, type find . -name CVS -exec rm -rf {} \; . Find will substitute {} for the file that's found and it needs ; to designate the end of the command.
  • grep give input text, grep prints only the lines that match my regular expression.
  • bash -c executes the bash shell. This can be used with find -exec to run multiple commands in sequence
  • jar tvf print all the files in a .jar file

Find my file in a jar

jar tvf _jarfile_ | grep _ServiceMBeanSupport.class_

This will tell me if the file is in the jar file or not. Its a start.

Find my file in all the .jar files in the current directory or deeper

find . -name *.jar -exec jar tvf _{}_ | grep _ServiceMBeanSupport.class_ \;

This will tell me if the file is in any of the jarfiles. Unfortunately it doesn't tell me which jarfile it is in, since it just prints the contents of the jarfiles and not their names.

The Command

find . -name *.jar -exec bash -c "echo {} && jar tvf {} | grep ServiceMBean " \;

This writes the name of the jar file, followed by any matching file's that are in it. So if I search for ServiceMBean, I get a list like this:

./client/jboss-iiop-client.jar
...
./client/jboss-net-client.jar
./client/jboss-system-client.jar
./client/jboss-transaction-client.jar
./client/jbossall-client.jar
   795 Fri Jun 25 19:55:16 EDT 2004 org/jboss/jmx/adaptor/rmi/RMIAdaptorServiceMBean.class
  1331 Fri Jun 25 19:55:16 EDT 2004 org/jboss/jmx/connector/ConnectorFactoryServiceMBean.class
./lib/jboss-system.jar
   603 Fri Jun 25 19:54:38 EDT 2004 org/jboss/system/ListenerServiceMBean.class
  1745 Fri Jun 25 19:54:38 EDT 2004 org/jboss/system/ListenerServiceMBeanSupport$MBeanInfo.class
 10950 Fri Jun 25 19:54:38 EDT 2004 org/jboss/system/ListenerServiceMBeanSupport.class
  1309 Fri Jun 25 19:54:38 EDT 2004 org/jboss/system/ServiceMBean.class
  9523 Fri Jun 25 19:54:38 EDT 2004 org/jboss/system/ServiceMBeanSupport.class
...

And my work is done for the day. Cool, eh?