How can you print the classpath from a plugin class? Trouble loading properties file from classpath in plugin class


(Ferzan Rizvi) #1

This build creates a BuildSrc binary containing all our gradle plugins.

I am trying to use a properties file that is packaged as a resource in a jar that’s included both on the classpath in buildscript{} and as a compile dependency. When I try to load it off the classpath in one of my plugin classes, it’s returning null. The jar is packaged correctly and I am referencing it correctly path wise, I load that properties file in many places outside of this plugin. The properties file is in the root of the jar.

I want to print the classpath to see what exactly is on there and figure out why I can’t load the file but, this.class.classLoader.getUrls() is not a valid method in Gradle’s classloader. Any help would be appreciated.

BuildSrc Project:

build.gradle --------------------------------

buildscript {
    apply from: 'https://s3.amazonaws.com/xxxx/repositories.gradle', to: buildscript
      dependencies {
        classpath "com.xxxx:BuildSrc:latest.release" <--- Build depends on itself
        classpath "org.xxx:CloudServicesTools:latest.release"
<--- This jar contains the properties file
    }
}
  dependencies {
    compile gradleApi()
      compile 'org.codehaus.groovy:groovy-all:2.1.7'
    compile "org.xxxx:CloudServicesTools:latest.release"
<--- Same jar as above, this jar contains the properties file
}

AwsDeployPlugin.groovy ---------------------------------------------------------

class AwsDeployPlugin implements Plugin<Project> {
      ConfigObject properties
    AwsDeployExtension extension
      def void apply(Project project) {
        extension = project.extensions.create('awsDeployConfig', AwsDeployExtension)
          project.afterEvaluate {
            extension.authorNodes.each { thisNode ->
                createDeployTasks(project, thisNode.toString(), "Author", 4502)
            }
              extension.publisherNodes.each { thisNode ->
                createDeployTasks(project, thisNode.toString(), "Publisher", 4503)
            }
                project.task('cqDeploy', dependsOn: [project.tasks.withType(CqPostDeployTask)]) {
                outputs.upToDateWhen { false }
            }
        }
    }
      def createDeployTasks(Project project, String host, String nodeType, Integer portNumber){
                  println "Configuration: envName=${extension.envName} | brand=${extension.brand} | scriptFile=${extension.elbScript}"
  ---->
println this.class.classLoader.getResourceAsStream('config.groovy').readLines()
---->
def env = new Environment(name: extension.envName)
 //This Environment class attempts to load the properties file I tried printing above and fails with a null pointer.
  //This class works fine outside of the plugin, it's being used in other areas of this BuildSrc build script.
           def envDns = new Route53(environment: env).getDnsNamesByIpAddress(host)
          project.task("cqPreDeploy-${nodeType}-${host}", type: CqPreDeployTask) {
            environmentName = extension.envName
            environmentDns = envDns
            brand = extension.brand
            scriptFile = extension.elbScript
        }
    }
}

Environment.groovy ---------------------------------------------------------

class Environment {
    String name
    String productCode
      URL configFileUrl = Thread.currentThread().getContextClassLoader().getResource( 'Config.groovy' )
    ConfigObject config
      Environment(Map map = [:]){
        map?.each { k, v -> this[k] = v }
          config = new ConfigSlurper().parse(configFileUrl)
          Validate.notNull(name, "Error: Environment Name cannot be null")
        name = name.toUpperCase()
          doesEnvironmentExist()
    }

StackTrace --------------------------------------------------------- Caused by: java.lang.NullPointerException: Cannot invoke method newInstance() on null object

at org.xxxx.environment.Environment.(Environment.groovy:15)

at com.xxxx.gradle.plugin.cq.AwsDeployPlugin.createDeployTasks(AwsDeployPlugin.groovy:38)

at com.xxxx.gradle.plugin.cq.AwsDeployPlugin$_apply_closure1_closure7.doCall(AwsDeployPlugin.groovy:21)

at com.xxxx.gradle.plugin.cq.AwsDeployPlugin$_apply_closure1.doCall(AwsDeployPlugin.groovy:20)

at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:40)

at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:25)

at org.gradle.listener.BroadcastDispatch.dispatch(BroadcastDispatch.java:83)

at org.gradle.listener.BroadcastDispatch.dispatch(BroadcastDispatch.java:31)

at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)

at com.sun.proxy.$Proxy12.afterEvaluate(Unknown Source)

at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:67)

… 49 more


(Peter Niederwieser) #2

Was your own attempt to print the file contents outside the ‘Environment’ class successful? Have you tried to use ‘getClass().getClassLoader()’ instead of ‘Thread.currentThread().getContextClassLoader()’ inside the ‘Environment’ class? If this doesn’t help, I’d recommend to check the class loaders in the debugger (e.g. ‘gradle --stop; gradle build --daemon -Dorg.gradle.debug=true’, then connect an external debugger on the port printed to std out).


(Ferzan Rizvi) #3

No, the print attempt from the plugin class was not successful. It is successful from anywhere else though including build.gradle.

Yes, I have tried this method as well.

Will try the debugger suggestion and report back.

I will extract this scenario out into a smaller project to see if I can reproduce the issue and upload it here.

Thanks