Surviving Dependency Hell
Speakers: Robert Scholte (@rfscholte) & Ray Tsang (@saturnism)
For more blog posts, see The Oracle Code One table of contents
Identifying problem
- Setup two dependencies with Maven and ran
- Errors: NoSuchMethodError, NoSuchFieldError, ClassNotFoundException
- mvn dependency:tree – lots of output
- mvn dependency:tree -Dincludes=com.google.guava – filters by the jar suspected
- mvn dependency:tree -Dincludes=com.google.guava -Dverbose=true – shows conflicts and reason
- Showed IntelliJ dependency tree graph
Picking a dependency
- Classpath – first class wins
- Maven – nearest wins
- Maven doesn’t understand Semver (semantic versioning)
- Use Maven Enforcer with upper bound. This assumes library is backwards compatible
- Guava 21+ is backward compatible
Other problems
- Shade – Copies files to creates problems. Problem if jars relocated. Only do as last resort
- Classloaders
Solutions
- Explicit dependency with version you need
- Exclude dependency when pull in transitive dependency
- Dependency management to specify version you need. Dependency management is a lookup table. It doesn’t actually need to exist. Can have a reference to a snapshot in there.
- When making breaking changes – use new group id or artifact id. Use new package name. This is what commons lang did. – http://jlbp.dev/JLBP-6.html
- BOM file for multi module projects with all transitive dependencies needed. Only use for modules within the project. – http://jlbp.dev/JLBP-15.html
<and then I needed to leave to get to my session in another building and get ready>
My take
Regardless of how good this is, I needed to leave early to get to my own session in another building right after this. I’m sorry I had to leave. It was excellent. I like that I learned about http://jlbp.dev so I can do more reading later.