title: Optional dependencies of external library added via Grab not available
body: <p>It is not possible to use external third party libaries with optional dependencies properly in shared libraries for Jenkins.</p>
  
  <p>I have a shared library which uses <a href="https://commons.apache.org/proper/commons-configuration/" rel="nofollow noreferrer">Commons Configurations 2</a> to read varios configuration files, mostly written as YAML documents. </p>
  
  <p>Commons configurations uses SnakeYAML to read YAML documents and the dependency to SnakeYAML is defined as optional as follows:</p>
  
  <pre class="lang-xml prettyprint-override"><code> &lt;dependency&gt;
        &lt;groupId&gt;org.yaml&lt;/groupId&gt;
        &lt;artifactId&gt;snakeyaml&lt;/artifactId&gt;
        &lt;version&gt;1.26&lt;/version&gt;
        &lt;optional&gt;true&lt;/optional&gt;
   &lt;/dependency&gt;      
  </code></pre>
  
  <p>According to the <a href="https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html" rel="nofollow noreferrer">documentation of Maven how optional dependencies work</a> an optional dependency is not added by default to the classpath. If a person wants to the part of the library which depends on the optional dependency, it must add this dependency to his own POM.</p>
  
  <p>As I was going to use Commons Configuration 2 in conjunction with SnakeYAML, I defined the following variable in <code>vars/readConfig.groovy</code> as follows:</p>
  
  <pre><code>@Grapes([
    @Grab(group = "org.apache.commons", module = "commons-configuration2", version = "2.7"),
    @Grab(group = "org.yaml", module = "snakeyaml", version = "1.26")
  ])
  import org.apache.commons.configuration2.BaseConfiguration
  import org.apache.commons.configuration2.Configuration
  import org.apache.commons.configuration2.YAMLConfiguration
  
  def call() {
      Configuration config = new BaseConfiguration();
      YAMLConfiguration yamlConfiguration = new YAMLConfiguration();  
  }
  </code></pre>
  
  <p>Calling <code>readConfig()</code> from a shared Library results in a <code>java.lang.ClassNotFoundException</code> with the following message</p>
  
  <pre><code>java.lang.ClassNotFoundException: org.yaml.snakeyaml.DumperOptions
      at jenkins.util.AntClassLoader.findClassInComponents(AntClassLoader.java:1387)
      at jenkins.util.AntClassLoader.findClass(AntClassLoader.java:1342)
      at jenkins.util.AntClassLoader.loadClass(AntClassLoader.java:1089)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:352)
      at java.lang.Class.getDeclaredMethods0(Native Method)
      at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
      at java.lang.Class.privateGetPublicMethods(Class.java:2902)
      at java.lang.Class.getMethods(Class.java:1615)
      at java.beans.Introspector.getPublicDeclaredMethods(Introspector.java:1336)
      at java.beans.Introspector.getTargetMethodInfo(Introspector.java:1197)
      at java.beans.Introspector.getBeanInfo(Introspector.java:426)
      at java.beans.Introspector.getBeanInfo(Introspector.java:173)
      at groovy.lang.MetaClassImpl$15.run(MetaClassImpl.java:3313)
      at java.security.AccessController.doPrivileged(Native Method)
      at groovy.lang.MetaClassImpl.addProperties(MetaClassImpl.java:3311)
      at groovy.lang.MetaClassImpl.initialize(MetaClassImpl.java:3288)
      at org.codehaus.groovy.reflection.ClassInfo.getMetaClassUnderLock(ClassInfo.java:260)
      at org.codehaus.groovy.reflection.ClassInfo.getMetaClass(ClassInfo.java:302)
      ...
  </code></pre>
  
  <p>I also checked the directory <code>~/.groovy/grapes</code> for the presence of all needed jars and they are there.</p>
  
  <pre><code>jenkins@cb765137c926:~/.groovy$ find . -name "*.jar"
  ./grapes/commons-logging/commons-logging/jars/commons-logging-1.2.jar
  ./grapes/org.apache.commons/commons-configuration2/jars/commons-configuration2-2.7.jar
  ./grapes/org.apache.commons/commons-lang3/jars/commons-lang3-3.9.jar
  ./grapes/org.apache.commons/commons-text/jars/commons-text-1.8.jar
  ./grapes/org.yaml/snakeyaml/jars/snakeyaml-1.26.jar
  </code></pre>
  
  <p>To do a cross-check I wrote the following Groovy script and was able to execute it on my computer successfully.</p>
  
  <pre><code>@Grapes([
    @Grab(group = 'org.apache.commons', module = 'commons-configuration2', version = '2.7'),
    @Grab(group = 'org.yaml', module = 'snakeyaml', version = '1.26'),
    @GrabConfig(systemClassLoader = true)
  ])
  
  import org.apache.commons.configuration2.*
  
  println("Start")
  
  YAMLConfiguration y = new YAMLConfiguration()
  
  println y
  </code></pre>
  
  <p>So, I am not able to guess the reason for this problem, as I am not so familiar with the internals of Jenkins. But it would be great to know if there is a way to get it working as intended.</p>