Description

The below code searches through the classpath of a groovy script or a running groovy application and prints out classes which match the given regular expression. This is useful when you hit some variation of JAR hell and want to figure out which files contribute a specific class to your groovy classpath, be it a standalone script, a compiled joint java/groovy project, a grails project or something else. 

Credits for the recursive classpath code go to 'blindgaenger' at:  

 http://blog.blindgaenger.net/print_groovys_classpath_for_debugging.html

The code has been modified to do a regex search as per below.

Code

import java.util.zip.*

def printClassPath(classLoader, pattern) {
  println "$classLoader"

  classLoader.URLs.findAll { 
    it.toExternalForm().endsWith(".jar")
  }.each { url ->
    def f = new File(url.toURI())
    try {
      boolean firstTime = true
      // Iterate through all zip entries matching our regular expression
      // print out the jar url and the entry name as we go
      new ZipFile(f).entries().findAll { it.name =~ pattern }.each { ZipEntry entry -> 
        if (firstTime) {
          println "  > $url"
          firstTime = false
        }
        println "    > ${entry.name}"  
      }
    } catch (Throwable e) {
      println "Error opening jar file ${f}, message: ${e.message}"
    }
  }

  // if we have a parent, make a recursive call to search for the class there also
  if (classLoader.parent) printClassPath(classLoader.parent, pattern)
}

// call the method with the current classpath, look for classes matching 'http'
// (?i) switches on case insensitive regex matching
// the / .. / is a groovy string syntax suitable for regex handling
printClassPath this.class.classLoader, /(?i)http/
 

To try this out, paste the above code into 'test.groovy' and execute as follows: 

$ groovy test.groovy
groovy.lang.GroovyClassLoader$InnerLoader@6d79953c
groovy.lang.GroovyClassLoader@7f033a6f
org.codehaus.groovy.tools.RootLoader@2352544e
  > file:/usr/local/Cellar/groovy/2.1.1/libexec/lib/ant-1.8.4.jar
    > org/apache/tools/ant/taskdefs/condition/Http.class
  > file:/usr/local/Cellar/groovy/2.1.1/libexec/lib/groovy-servlet-2.1.1.jar
    > groovy/servlet/AbstractHttpServlet.class
  > file:/usr/local/Cellar/groovy/2.1.1/libexec/lib/ivy-2.2.0.jar
    > org/apache/ivy/plugins/resolver/util/ApacheHttpURLLister.class
    > org/apache/ivy/util/url/BasicURLHandler$HttpStatus.class
    > org/apache/ivy/util/url/HttpClientHandler$1.class
    > org/apache/ivy/util/url/HttpClientHandler$HttpClientHelper.class
    > org/apache/ivy/util/url/HttpClientHandler$HttpClientHelper2x.class
    > org/apache/ivy/util/url/HttpClientHandler$HttpClientHelper3x.class
    > org/apache/ivy/util/url/HttpClientHandler$IvyCredentialsProvider.class
    > org/apache/ivy/util/url/HttpClientHandler.class
  > file:/usr/local/Cellar/groovy/2.1.1/libexec/lib/jsp-api-2.0.jar
    > javax/servlet/jsp/HttpJspPage.class
  > file:/usr/local/Cellar/groovy/2.1.1/libexec/lib/servlet-api-2.4.jar
    > javax/servlet/http/
    > javax/servlet/http/Cookie.class
    > javax/servlet/http/HttpServlet.class
    > javax/servlet/http/HttpServletRequest.class
    > javax/servlet/http/HttpServletRequestWrapper.class
    > javax/servlet/http/HttpServletResponse.class
    > javax/servlet/http/HttpServletResponseWrapper.class
    > javax/servlet/http/HttpSession.class
    > javax/servlet/http/HttpSessionActivationListener.class
    > javax/servlet/http/HttpSessionAttributeListener.class
    > javax/servlet/http/HttpSessionBindingEvent.class
    > javax/servlet/http/HttpSessionBindingListener.class
    > javax/servlet/http/HttpSessionContext.class
    > javax/servlet/http/HttpSessionEvent.class
    > javax/servlet/http/HttpSessionListener.class
    > javax/servlet/http/HttpUtils.class
    > javax/servlet/http/LocalStrings.properties
    > javax/servlet/http/LocalStrings_es.properties
    > javax/servlet/http/LocalStrings_fr.properties
    > javax/servlet/http/LocalStrings_ja.properties
    > javax/servlet/http/NoBodyOutputStream.class
    > javax/servlet/http/NoBodyResponse.class
sun.misc.Launcher$AppClassLoader@1f3e8d89
sun.misc.Launcher$ExtClassLoader@43be2d65

 

Author: Matias Bjarland, Iteego Inc