0

We are using a Jenkins Shared Library to centralize some code for all our (scripted) pipelines. Now we factored out some Groovy code into a .jar library (written in Kotlin, compiled to be Java 8 compatible). We published this library to our in-house maven repo and now want to use it in our Shared Libary.

We are using @Grab to load our library and up until that point it works like a charm. However we are getting NoSuchMethodError's. We pinpointed it down a bit, we are using OkHttp in our Kotlin lib. OkHttp internally uses Okio. When we call methods that internally call OkHttp-Code from our pipeline, everything is fine. However when the OkHttp-Code call Okio internally, we get a NoSuchMethodError.

We already checked the published .jar file, it contains the classes with the methods that seem to be missing. Does anybody have an idea what the issue could be?

While we are at it, we can't access environment variables set on Jenkins in our Kotlin library, is there a way we can fix this?

Simon Schiller
  • 644
  • 1
  • 8
  • 23

2 Answers2

1

We figured it out. The problem was, that a Jenkins plugin used an older version of okio internally. Because plugins and shared libraries somehow share the same classpath, okio did not get loaded and the version from the plugin got used, therefore the class was not present.

We fixed this by repackaging all dependencies in our .jar, so package names would not interfere and we can make sure that our specified dependencies are being used.

Simon Schiller
  • 644
  • 1
  • 8
  • 23
0

Looking the dependencies here you have a few problems:

  1. OKHttp - seems to expect some Android libraries
  2. okio - depends on the Kotlin runtime

Any calls to these will result in method not found errors unless you find a way to make them available without causing problems in Jenkins

Rich Duncan
  • 1,845
  • 1
  • 12
  • 13
  • OkHttp does not contain any kind of android specific code afaik. Also, we are also using Kotlin for our lib, so the Kotlin runtime should be available, shouldn't it? – Simon Schiller Oct 24 '18 at 15:04
  • So the android stuff 'probably' isn't the problem, but if I remember correctly the Kotlin libs were 'provided' dependencies, like a JDK. Java arranges for the JDK to be available to your running Java app, but I'm pretty sure that the Kotlin runtime will not be made available to code running in Jenkins... – Rich Duncan Oct 24 '18 at 17:28
  • If that were the case, the first statement would fail, right? Because previous (Kotlin only) statements work just find, it's just the library calls that fail. – Simon Schiller Oct 25 '18 at 08:44
  • Since it's a library, it would be the first time your code makes a call to the Kotlin specific runtime. Since your getting NoSuchMethod exceptions, do the names of the methods help distinguish the class(es) that is not getting loaded? – Rich Duncan Oct 25 '18 at 13:03
  • Yes, it complains at `ByteStream.encodeString`, which is the first call of Okio (but not the first of OkHttp) – Simon Schiller Oct 26 '18 at 14:06
  • Do you have a stack trace and or a package reference. A quick google on that class name and method don't return anything... I'd look at the Okio dependencies to see if you can find where it comes from. If the dependency type is 'provided' or 'runtime' try doing a @Grab on it – Rich Duncan Oct 26 '18 at 14:49
  • I just checked it again, all dependencies get downloaded by grape correctly, okio, kotlin, you name it, everything is in the `.groovy/grapes` folder. But still the Jenkins script does not find it – Simon Schiller Oct 29 '18 at 07:56
  • Any idea where the ByteStream class is from? – Rich Duncan Oct 29 '18 at 11:48