Link to home
Start Free TrialLog in
Avatar of leo layden
leo layden

asked on

is there a way to search the java classpath to find duplicate classes

I suspect that I have a duplicate class somewhere on a long and complicated classpath. Is there any easy way to find it other than by searching manually?
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Is it a path composed of directories or jars, or both?
if your project is in an IDE then you should get multiple choices.
However there could of course be some proprietary jars providers by the environment too.
Avatar of leo layden
leo layden

ASKER

There are directories and jars in the classpath but I know the problem is in the directories. I'm confident about the contents of the jars.
... and I'm using Textpad to do the compile.
you are doing this  because you have a classpath conflict?
How did you come to this conclusion?
I SUSPECT that I MAY have a classpath conflict and am looking for a way to exclude the suspicion. I am using a utility that generates code (Altova Mapforce) and I'm invoking the code using reflection. I suspect that code from an earlier version may have been generated in the wrong place and is now interfering.
Since you think the problem involves classes in directories, you could try a little Powershell

http://powershell.com/cs/blogs/tips/archive/2008/11/17/finding-duplicate-files.aspx
ASKER CERTIFIED SOLUTION
Avatar of leo layden
leo layden

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Here's a better version.

It checks the jars/zips as well, including the ones in the /lib/ext folder

Still OS dependent but not difficult to rectify that

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Enumeration;
import java.util.StringTokenizer;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

public class CheckClasspath
{      public static int count = 0;
      public static PrintStream p = null;
      public static String outfile = "C:/java/classpath.csv";
      // '/'s in paths is OS dependent

      public static void main(String[] args)
      {      if (args.length >0) outfile = args[0].replace("\\","/");
            listClasspath(outfile);
      }

      public static void listClasspath(String ofile)
      {      try { p = new PrintStream(ofile);} catch (Exception e) {e.printStackTrace();}
            p.println("class,package, root, order, error");
            String cp = System.getenv("CLASSPATH");
            StringTokenizer tkzer = new StringTokenizer(cp,";"); // ";" - OS Dependant
            String dotpath = new File(".").getAbsolutePath().replace("\\","/");
            dotpath = dotpath.substring(0,dotpath.length()-2);
            // process extensions directory
            String libext = System.getProperty("java.home").replace("\\","/")+"/lib/ext"; //default location
            String[] filelist = new File(libext).list();
            for (int j = 0; j<filelist.length;j++) processZip(libext+"/"+filelist[j]);
            while (tkzer.hasMoreTokens())
            {      String nextCandidate = tkzer.nextToken().replace("\\","/");
                  if (nextCandidate.equals(".")) nextCandidate = dotpath;
                  File nextFile = new File(nextCandidate);
                  if (nextCandidate != null)
                  {      if (nextFile.isFile()) processZip(nextCandidate);
                        else process(nextCandidate, nextCandidate);
                  }
            }
      }

      private static void process(String root, String directory)
      {      String[] filelist = new File(directory).list();
            for (int j = 0; j<filelist.length; j++)
            {      if (new File(directory+"/"+filelist[j]).isFile())
                        {      if (filelist[j].indexOf(".class")>0)
                              {      try
                                    {      String pckage = directory.replace(root,"").replace("/",".")+".";
                                          if (pckage.indexOf(".")==0) pckage = pckage.substring(1);
                                          String classname = filelist[j].replace(".class","");
                                          Class c = Class.forName(pckage+classname);
                                          count++;
                                          p.println(classname+","+pckage+","+root.toUpperCase()+","+count);
                                          // toUpperCase to make it easire to remove duplicates in Excel - OS Dependant
                                    }
                                    catch (Exception e) {}
                                    catch (Error er) {} ///if no Class object was created, it doesn't work from this root so ignore
                              }
                        }
                  else process(root,directory+"/"+filelist[j]);
            }
      }

      private static void processZip(String zipf)
      {      try
            {      ZipFile zip = new ZipFile(new File(zipf),ZipFile.OPEN_READ);
                  Enumeration<? extends ZipEntry> entries = zip.entries();
                  while (entries.hasMoreElements())
                  {      String ze = entries.nextElement().getName();
                        if (ze.endsWith(".class"))
                        {      ze = ze.substring(0,ze.length()-6);
                              try
                              {      Class.forName(ze.replace("/","."));
                                    count++;
                                    if (ze.indexOf("/")>=0) p.println(ze.substring(ze.lastIndexOf("/")+1)+","+ze.substring(0,ze.lastIndexOf("/"))+","+zipf.toUpperCase()+","+count);
                                    else p.println(ze+",, "+zipf+","+count);
                              }
                              catch (ClassNotFoundException e) {}
                               catch (Error er) // classes in jar files should be instantiable - so report errors to user
                               {      count++;
                                     if (ze.indexOf("/")>=0) p.println(ze.substring(ze.lastIndexOf("/")+1)+","+ze.substring(0,ze.lastIndexOf("/"))+","+zipf.toUpperCase()+","+count+" ,"+er);
                                    else p.println(ze+",, "+zipf+","+count+","+er);
                               }
                        }
                  }
                  zip.close();
            }
            catch (ZipException zexc) {p.println("zz ZipError in jar "+zipf+","+zexc);}
            catch (IOException e) {}
            catch (Error er) {p.println("zz Error in jar " + zipf.toUpperCase()+","+er);}
            // zz to put them at end of sort in Excel
      }
}
Solves the problem but is not elegant.