You are here

Detect java archive a class is loaded from

While playing around with Apaches Axis2 project recently, I found a cool code snippet that helps a lot in debugging classpath issues in your web application. I will post this snippet here in the hope to help anybody out there with similar issues.
A common source of problems when deploying web applications to an app server is the effective classpath. When instantiating a class in your code, you never know where the app server is loading the .class file from. This can be the WEB-INF/classes or WEB-INF/lib folder of your application, the lib folder of the app server itself or the JVM installation on the local machine.
The following code snippet helps you to debug these situations. It tries to load a class by name and then inspects the jar file and class loader of that class. The following code snippet should be used in a JSP page:

    <%!
    private Class loadClass(String className)
    {
        try
        {
            return(Class.forName(className));
        }
        catch(ClassNotFoundException e)
        {
            return(null);
        }
    }
 
    private Class checkClass(JspWriter out, String className, String notFoundErrorMessage)
    {
        boolean hasBeenReported = false;
        Class testClass = null;
        try
        {
            testClass = loadClass(className);
            if(testClass == null)
            {
                out.write("<b>" + notFoundErrorMessage + "</b>");
            }
            else
            {
                String location = "an unknown location.";
                try
                {
                    java.net.URL url = testClass.getProtectionDomain().getCodeSource().getLocation();
                    location = url.toString();
                    if(location.startsWith("jar"))
                    {
                        url = ((java.net.JarURLConnection) url.openConnection()).getJarFileURL();
                        location = url.toString();
                    }
                    if (location.startsWith("file"))
                    {
                        java.io.File file = new java.io.File(url.getFile());
                        location = file.getAbsolutePath();
                    }
                }
                catch(Throwable t)
                {
                }
                out.write("Found at ");
                out.write(location);
                out.write("<br>\n");
                java.lang.Package docPackage = testClass.getPackage();
                if(docPackage == null)
                {
                    out.print("Class is not located in a package. Can not verify version.<br>\n");
                }
                else
                {
                    out.print("Product: "+docPackage.getImplementationTitle()+"&nbsp;&nbsp;");
                    out.print("Vendor: "+docPackage.getImplementationVendor()+"&nbsp;&nbsp;");
                    out.print("Version: "+docPackage.getImplementationVersion()+"&nbsp;&nbsp;");
                    out.print("ClassLoader: "+(testClass.getClassLoader()==null?"null":testClass.getClassLoader().toString())+"&nbsp;&nbsp;");
                }
            }
        }
        catch(NoClassDefFoundError e)
        {
            try
            {
                out.write("Is present but failed loading due to a missing dependency.<br>\n");
                out.write("Error Message: "+e.getMessage());
                out.write("<br>\n");
                StackTraceElement[] trace = e.getStackTrace();
                for(int i=0; i < trace.length; i++)
                {
                    out.write(trace[i].toString()+"<br>\n");
                }
            }
            catch(Exception ioe){}
            hasBeenReported = true;
        }
        catch(Throwable t)
        {
            if(!hasBeenReported)
            {
                try
                {
                    out.write("Might be present but failed loading due to an unknown error.<br>\n");
                    out.write("Error Message: "+t.getMessage());
                    out.write("<br>\n");
                    StackTraceElement[] trace = t.getStackTrace();
                    for(int i=0; i < trace.length; i++)
                    {
                        out.write(trace[i].toString()+"<br>\n");
                    }
                }
                catch(Exception ioe){}
            }
        }
        return(testClass);
    }
    %>
<b>XML API:</b><br>
<%
   checkClass(out,"org.w3c.dom.Document","Can not be found. Please make sure this webapp is able to load the file xml-apis.jar or similar.<br>");
%>
Tags: