Here it is: I've made this tool which is only one java class. I am also bundling the ant build file so that you do not have to spend too much time figuring out how to run this thing.
How to run this tool:
1. Pick one folder as a base folder for this tool. Make a folder structure src->com->gp. Copy the source code of the JavaDependencyWalker.java in a file with the same name in the gp folder.
2. Now, copy the code of build.xml into a file of the same name in the base folder.
3. If you already do not have an ant install please download it from here http://ant.apache.org and install it.
4. Edit the build.xml file and modify the three proerties mentioned at the top with the following guidelines:
- scolon.separated.folders.ofjars = For the value of this property put a semi-colon separated absolute paths where the program can find all the jar files required for the class to run. For example, if the main class is a web service client that uses axis2 APIs then put the path to the lib folder of the axis2 install here. Also, do not forget to put paths to jar files of the custom classes you have built here. For example, you must put the path to the jar that contains the main class to run!
- main.class = This is the main class to run, for which you are finding the exact jars requirements.
- args.to.class = Here give all the arguments that will be required for the main class to run.
Below is the source code:
JavaDependencyWalker:
package com.gp;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class JavaDependencyWalker {
private Hashtable m_jarsHash = new Hashtable();
public JavaDependencyWalker(String jarPaths) {
StringTokenizer stTok = new StringTokenizer(jarPaths, ";");
while (stTok.hasMoreTokens()) {
File f = new File(stTok.nextToken());
if (f.exists() && f.isDirectory()) {
addAllJars(f);
} else {
System.err.println(f.getName() +
" :: Cannot find this folder.");
}
}
}
private void addAllJars(File f) {
if (f.isDirectory()) {
File[] files = f.listFiles();
for (int i = 0; i < files.length; i++) {
addAllJars(files[i]);
}
} else {
if (f.getName().toLowerCase().endsWith(".jar") ||
f.getName().toLowerCase().endsWith(".zip")) {
try {
JarFile jf = new JarFile(f);
Enumeration entries = jf.entries();
while (entries.hasMoreElements()) {
String entryName =
((JarEntry)entries.nextElement()).getName();
if (entryName.endsWith(".class")) {
entryName =
entryName.substring(0, entryName.indexOf("."));
StringTokenizer stTok =
new StringTokenizer(entryName, "/");
String str = "";
while (stTok.hasMoreTokens()) {
str += stTok.nextToken() + ".";
}
str = str.substring(0, str.length() - 1);
m_jarsHash.put(str, f.getCanonicalPath());
} else {
// skip it
}
}
jf.close();
} catch (IOException e) {
System.err.println(f.getName() + " :: " + e.getMessage());
}
} else {
// skip this file
}
}
}
public String getJarFilepath(String classname) {
return (String)m_jarsHash.get(classname);
}
public static void usage() {
System.out.println("java -Ddeps=<semi-colon seperated paths where all jars/zips may be found> -DclassToRun=<fully qualified classname to run> JavaDependencyWalker <all arguments to give to the class to run>");
}
public static void main(String[] args) {
String dependencies = System.getProperty("deps");
String classname = System.getProperty("classToRun");
if (dependencies == null || classname == null) {
usage();
System.exit(1);
}
JavaDependencyWalker javaDependencyWalker =
new JavaDependencyWalker(dependencies);
try {
String cp = "";
boolean noFound = true;
do {
Runtime rt = Runtime.getRuntime();
String cmdArr[] = null;
if (cp.equals("")) {
cmdArr = new String[args.length+2];
cmdArr[0] = "java";
cmdArr[1] = classname;
for (int i=0; i < args.length; i++) {
cmdArr[i+2] = args[i];
}
// cmd =
//"java " + args[1] + " ";
}
else {
cmdArr = new String[args.length+4];
cmdArr[0] = "java";
cmdArr[1] = "-classpath";
cmdArr[2] = cp;
cmdArr[3] = classname;
for (int i=0; i < args.length; i++) {
cmdArr[i+4] = args[i];
}
}
System.out.println("Command:" + cmdArr);
Process proc = rt.exec(cmdArr);
DataInputStream in =
new DataInputStream(proc.getErrorStream());
String line;
noFound = false;
while ((line = in.readLine()) != null) {
//System.out.println(line);
if (line.indexOf("ClassNotFoundException") != -1) {
String classNF =
line.substring(line.lastIndexOf(":") + 1).trim();
String cnfPackage = classNF.replace('/', '.');
if (javaDependencyWalker.getJarFilepath(cnfPackage) ==
null)
throw new Exception("No jar found for class " +
cnfPackage);
System.out.println("cnf: " + classNF + " found in " +
javaDependencyWalker.getJarFilepath(classNF));
noFound = true;
cp += javaDependencyWalker.getJarFilepath(cnfPackage) + ";";
} else if (line.indexOf("NoClassDef") != -1) {
String classNF =
line.substring(line.lastIndexOf(":") + 1).trim();
String ncdfPackage = classNF.replace('/', '.');
if (javaDependencyWalker.getJarFilepath(ncdfPackage) ==
null)
throw new Exception("No jar found for class " +
classNF);
System.out.println("NCDF: " + classNF + " found in " +
javaDependencyWalker.getJarFilepath(ncdfPackage) +
" " + ncdfPackage);
noFound = true;
cp += javaDependencyWalker.getJarFilepath(ncdfPackage) + ";";
}
}
} while (noFound);
StringTokenizer st = new StringTokenizer(cp, ";");
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
}
}
}
ant build.xml:
<project name="JavaDependencyWalker" default="compile">
<property name="scolon.separated.folders.ofjars" value="c:/FUPv5/lib;c:/FUPv5/DeleteFile/classes;c:/FUPv5/WSClient/classes;c:/FUPv5/common/classes"/>
<property name="main.class" value="com.oracle.orion.fupv5.ws.client.SRWSClient"/>
<property name="args.to.class" value="-sr sdfds34 -user sldkfjd -password sdlfkjd -endpoint http://wd2088.us.oracle.com:7778/gateway/services/SID0003321 -type ddf -comm sdfd -stat Done"/>
<path id="classpath">
<pathelement location="classes"/>
</path>
<target name="compile">
<mkdir dir="classes"/>
<javac destdir="classes" classpathref="classpath" source="1.5" target="1.5" >
<src path="src"/>
</javac>
</target>
<target name="run" depends="compile">
<java classname="com.gp.JavaDependencyWalker" classpathref="classpath" fork="yes">
<jvmarg line="-Ddeps=${scolon.separated.folders.ofjars} -DclassToRun=${main.class}"/>
<arg line="${args.to.class}"/>
</java>
</target>
</project>