NPE on dependency resolution when given an invalid symbolic library name

I stumbled over a NPE today, after changing the dependencies of my project. I have a list of all external jars on which the subprojects depend on. I changed a library name and then made a typo including it into the compile configuration of a subproject.

I think Gradle should report an error on an invalid symbolic name, and not run into a NPE.

Caused by: java.lang.NullPointerException
        at org.gradle.util.GUtil.flatten(GUtil.java:66)
        at org.gradle.util.GUtil.collectionize(GUtil.java:90)
        at org.gradle.util.GUtil$collectionize.call(Unknown Source)
        at org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.methodMissing(DefaultDependencyHa
ndler.groovy:98)
        at org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.invokeMethod(DefaultDependencyHan
dler.groovy)
        at build_40s89c7ll3pd1pbcdjd7jeont1$_run_closure1.doCall(Q:\sources\trunk_clf\uvdms\de.uvdms.server.cache\build.
gradle:10)
        at org.gradle.api.internal.ClosureBackedAction.execute(ClosureBackedAction.java:58)
        at org.gradle.util.ConfigureUtil.configure(ConfigureUtil.java:130)
        at org.gradle.util.ConfigureUtil.configure(ConfigureUtil.java:91)
        at org.gradle.api.internal.project.AbstractProject.dependencies(AbstractProject.java:922)
        at org.gradle.api.internal.BeanDynamicObject$MetaClassAdapter.invokeMethod(BeanDynamicObject.java:246)
        at org.gradle.api.internal.BeanDynamicObject.invokeMethod(BeanDynamicObject.java:134)
        at org.gradle.api.internal.CompositeDynamicObject.invokeMethod(CompositeDynamicObject.java:147)
        at org.gradle.groovy.scripts.BasicScript.methodMissing(BasicScript.java:79)

I don’t quite follow what happened. Can you expand a little bit please, perhaps with some examples.

This is easy to reproduce.

I have a multiproject, and I define all libraries we are depending on in a separate file that looks like this:

ext.libraries = [
   activeIO_core
 : 'org.apache.activemq:activeio-core:3.1.2',
 (...)
  jms_api
  : 'javax.jms:jms:1.1',
(...)
]

Now, a subproject got a new dependency on jms_api; so in the build file for this subproject I declared:

dependencies {
  compile (libraries.commons_collections, libraries.jsm_api,libraries.activeMQ_core)
(...)
}

Please notice the typo “jsm_api” instead of “jms_api”! This caused the reported NPE.

So, my expectation is: Gradle sees the invalid symbolic name and reports it as invalid instead of running into the reported NPE.

Raised as GRADLE-2969 and fixed for 1.11.

Gradle can only do so much here, I’d recommend failing earlier in this case:

ext.libraries = [
 // …
].withDefault { throw new IllegalArgumentException("No library with name $it") }

thanks for this tip, Luke.