3

I have a project that uses a 3rd party library (the netapp nmsdk package, but that's not really relevant). This library appears to use guava r08, and specifically calls com.google.commons.io.NullPointerStream. The problem is that class was removed after r15. Adding to the difficulty, the library doesn't seem know about it's dependencies, so we must manually include guava r08 in our project in order for the application to find the class at runtime.

Now, we use guava in a couple of places, but unfortunately we require features found in a newer version of guava. Thus later in our project pipeline-stack-whatever, we reference r21, the current version.

But maven excludes the transient dependency for r08 in favor of r21, so now we don't have the required class at runtime!

I've tried to get shading to work, but since it doesn't seem to bring in the classes from r08, there's nothing to shade.

Can someone help me figure out how to "include" the required transient files in r08 alongside the explicit dependency on r21. Alternatively, if I'm on the wrong track, can I get directions on the right way? Thanks!

EDIT: I wanted to explicitly state that the 3rd party library doesn't appear to be a proper maven artifact, and is entirely closed source that we do not have access to.

EDIT 2: Ok, so I lied earlier, its actually three projects (fine, you caught me, there are 12, but only 3 matter).

  • 3rd Party library requires Guavar08 and throws ClassNotFound exception at runtime. 3rd party library doesn't have transient dependencies or included dependencies.
  • Project-A uses the 3rd party library, and has guava r08 so 3rd Party can find it at runtime.
  • Project-B uses Project-A and also Guava 21.
  • Project-C uses Project-A, Project-B and does not, itself, use Guava.
  • The fat jar is built from a profile of Project-C.
Kevin Milner
  • 821
  • 2
  • 14
  • 30
  • How about grabbing the source for that class and discarding the rest? – shmosel May 17 '17 at 20:24
  • Split your code so the two codebases do not overlap. You cannot fix the problem by having two guava jars on the classpath. Note that where the newer version of guava is pulled in you can explicitly exclude it, so it doesn't count. – Thorbjørn Ravn Andersen May 17 '17 at 21:54
  • Several solutions: obfuscate your 3rd party lib and its dependencies making only public things from your 3rd party lib not obfuscated; use [Jar Jar Links](https://github.com/shevek/jarjar) to rename classes in your 3rd party from `my.package.Class` to `$.my.package.Class`, freeing up the Guava packages; other solutions, see previous comments. – Olivier Grégoire May 18 '17 at 00:20
  • @shmosel: Yeah I considered that, but I'd like to find a proper solution if I can. Also, I don't actually know what dependencies the package has. I only know it has a dependency on r08 because it throws a classnotfound exception. Googling revealed that its because its tied to r08. There might be other dependencies as well – Kevin Milner May 18 '17 at 16:12
  • @ThorbjørnRavnAndersen the codebase actually spans several projects. project-a depends on the third party library and so we include r08. project-b uses r21 but also is used to build the fat jar. Ideally I could use shading to remap the missing-from-r21 namespaces, but I don't know how to make maven aware of the namespace in r08. – Kevin Milner May 18 '17 at 16:16
  • You may want to add full details to your question. – Thorbjørn Ravn Andersen May 18 '17 at 16:30
  • it ended up being easier to just remove the dependency on Guava 21 in project-B. – Kevin Milner May 19 '17 at 15:03
  • Based on your revised description there is no easy way to do this. – Thorbjørn Ravn Andersen May 20 '17 at 18:12
  • yeah that's what I figured. thanks everyone for the help. – Kevin Milner May 21 '17 at 15:29

0 Answers0