2

We are using the shared library Jenkins plugin for our Jenkins code, namely workflow-cps-global-lib.

We implemented workflows successfully on different project types with groovy code in one single shared library.

Today we are encountering an issue which seem class-loading related and I m not sure where the problem lies.

Using an instance of "JAXBContext" in our shared library leads to a classcastexception. I will update later with the exact exception.

The class gets loaded from some other plugin installed on our jenkins.

At some point it was loaded from deployit-plugin (jenkins/plugins/deployit-plugin/web-inf/lib/jaxb-impl-xxx.jar).

After installing xlrelease-plugin (xlrelease-plugin/web-inf/lib/jaxb-impl-xxx.jar), it seems that JAXBContext is now loaded from this plugin and we don't get "ClassCastException" anymore.

There is no direct dependency between the shared library plug-in and those. Our code call methods exposed by those plug-ins tho. My guess for now is that somehow, because we call those plug-ins in our code, we inherit their class path.

If that's the case then how can we have control over which jar version is called? WE tried using grape to grab our version of the jaxb implementation and api but still, the jaxbcontext that was loaded was still the one from xlrelease-plugin.

I looked a bit at the code of workflow-cps-global-lib on github. As expected there's some class loader manipulation.

But I didn't find any pointer to the relations with the class loaders of other plugins.

If I understood correctly what's stated in the Jenkins documentation, when plugin A depends on plugin B, plugin class loader inherits jars from plugin B.

https://jenkins.io/doc/developer/plugin-development/dependencies-and-class-loading/

"workflow-cps-global-lib" does not depend on xlrelease-plugin or deployit-plugin thus should not inherit their class paths.

If anyone has insight as to why I get those classes loaded it in my pipeline exécution it would be very helpful.

1
  • Facing the exact same issue with aws-java-sdk-core. Although I am trying to @Grab a specific version (1.11.568) in my shared library, it always loads the version installed as plugin (required for aws credentials plugin). Jesse, please help Commented Jun 17, 2019 at 19:30

1 Answer 1

0

You found a valid document, though it does not touch on class loading from user Groovy library code, only from code in plugins. Groovy libraries are offered classes from the UberClassLoader, so if multiple plugins offer the same class, it is not defined where it will be loaded from.

(Recent versions of Jenkins include an actual JAXB plugin, which might take precedence over those.)

You might be able to work around this by explicitly @Grabbing the JAR you need for your library. But it would be better to avoid using JAXB from your library at all. In-process scripting and third-party libraries really do not mix well. Try to stick to the Java platform and Groovy built-ins for straightforward “glue” code, and for any actual computation just sh out to the tool of your choice (ideally moving some or all of the functionality out of the Groovy library altogether).

4
  • Hi Jesse. Thanks for your prompt reply. We tried installing the Jaxb plug-in but it didn't take precedence over the other two. We can definitely work around jaxbcontext. We thought about putting some of the logic into some standalone tool and ssh it from Jenkins. but we're trying to put the maximum of the logic we could in pure groovy or as jars grabbed from the library. The reason for that is that is to minimize the tools we have to deploy on every slave. Also if we do that it means starting a jvm at every call of the tool meaning some overhead in cpu and memory.
    – Mike C
    Commented Apr 17, 2019 at 21:23
  • Maybe another way to do that would be to build some Java code launched as a multithreaded service and call it via some IPC mechanism. That would reduce the Java code to one single artefact to deploy on slaves and would reduce the overhead per call (one thread instead of a jvm). We didn't plan on it so for now I guess we ll just not use Jaxb. Anyway thanks for ur reply I ll put it as solved
    – Mike C
    Commented Apr 17, 2019 at 21:25
  • Hey Jesse. Would there be a way to define the classes that we grab (@grab via Grape) to be prioritized ? I guess if that's the case, that'd mean some modification in the code of the "workflow-cps-global-lib" plugin ? I'm not sure which class-loader is used for classes loaded from grape, but guessing from our tests it seems like it's one that's higher in the hierarchy than uberclassloader. (priority is bottom class loader first i think ?)
    – Mike C
    Commented Apr 25, 2019 at 6:27
  • Facing the exact same issue with aws-java-sdk-core. Although I am trying to @Grab a specific version (1.11.568) in my shared library, it always loads the version installed as plugin (required for aws credentials plugin). Jesse, please help Commented Jun 17, 2019 at 19:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .