ing-bank / scruid

Scala + Druid: Scruid. A library that allows you to compose queries in Scala, and parse the result back into typesafe classes.
Apache License 2.0
115 stars 29 forks source link

Improve exception handling DruidConfig #43

Open bjgbeelen opened 5 years ago

bjgbeelen commented 5 years ago

Just encountered a problem where somehow DRUID_PORT env variable contained a string value, instead of an integer. This failed with a very unclear error message:

java.lang.NoClassDefFoundError: Could not initialize class ing.wbaa.druid.DruidConfig$ java.lang.NullPointerException

Better exception handling could prevent this confusion in the future

anskarl commented 5 years ago

Hi @bjgbeelen

I cannot reproduce the error. I've tried the following:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at issue.DeleteMe$.main(DeleteMe.scala:35)
    at issue.DeleteMe.main(DeleteMe.scala)
Caused by: com.typesafe.config.ConfigException$WrongType: env variables: port has type STRING rather than NUMBER
    at com.typesafe.config.impl.SimpleConfig.findKeyOrNull(SimpleConfig.java:163)
    at com.typesafe.config.impl.SimpleConfig.findOrNull(SimpleConfig.java:174)
    at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:188)
    at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:193)
    at com.typesafe.config.impl.SimpleConfig.getConfigNumber(SimpleConfig.java:223)
    at com.typesafe.config.impl.SimpleConfig.getInt(SimpleConfig.java:234)
    at ing.wbaa.druid.DruidConfig$.apply$default$2(DruidConfig.scala:56)
    at ing.wbaa.druid.DruidConfig$.<init>(DruidConfig.scala:53)
    at ing.wbaa.druid.DruidConfig$.<clinit>(DruidConfig.scala)
    ... 2 more

I think that the java.lang.NoClassDefFoundError happens because for some reason ing.wbaa.druid.DruidConfig$ (companion object of DruidConfig class) is not available in the classpath during runtime.

bjgbeelen commented 5 years ago

Hmm that's strange. I didn't fully dive into it when I had the issue, but I'm definitely sure it was caused by the fact that it was not an integer. I should have captured the full story when I entered this issue because I forgot some things about in the mean time... :) The error happened in the application that uses Scruid, but it was caused by the fact that DRUID_PORT was not parseable. There was no overridden configuration, so Scruid was trying to load this DRUID_PORT env variable.

If I recall correctly I noticed this issue in our Gitlab CI when running one of the steps (testing probably). In the gitlab CI a Druid container was defined, required for successfully running our unit tests. This Druid container was simply named druid and apparently in the background Gitlab (I think backed by Kubernetes) created this $SERVICE_PORT env var with the address of where that service is running, so it ended up being DRUID_PORT -> xxx.xxx.xxx.xxx:xxxx (some ip + port).

Renaming the Druid service to druid_docker, resulting an env DRUID_DOCKER_PORT and thus not setting/overwriting the DRUID_PORT solved the issue.