title: Spring boot doesn't read Components after jar signing
body: <p>I am developing a Spring Boot Application that serves REST HTTP(S) requests. (pretty common).</p>
  
  <p>It works as it is supposed, but after the final (and working) jar is signed (by a valid certificate) all URL mappings stop working, returning only 404 to any request. (Note that the embedded Tomcat server starts without problems and I don't receive any exception)</p>
  
  <p>After some debugging I found that the Java's default ClassLoader (Laucher$AppClassLoader) just doesn't return the classes within the packages I configurated (@ComponentScan) when the jar is signed.</p>
  
  <pre><code>//org.springframework.core.io.support.PathMatchingResourcePatternResolver
  //Param 'path' has my valid, existing and desired package with @Controller or @Component inside
  protected Set&lt;Resource&gt; doFindAllClassPathResources(String path) throws IOException {
              Set&lt;Resource&gt; result = new LinkedHashSet&lt;Resource&gt;(16);
              ClassLoader cl = getClassLoader(); //sun.misc.Laucher$AppClassLoader
              Enumeration&lt;URL&gt; resourceUrls = (cl != null ? cl.getResources(path) : ClassLoader.getSystemResources(path));
              //Empty enumeration when jar is signed
              ...
  }
  </code></pre>
  
  <p>I tried to use a custom Class Loader without success; same problem.</p>
  
  <p>Since it works when I sign the jar with a self signed certificate, I think that there may be a problem with the signing process that was done by another person. But I can't find any proof of that.</p>
  
  <p>It appears that once signed, I can't list the package content...</p>
  
  <p>I'll try some more tests and add here if I consider useful...</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>After debugging with the help of a custom Class Loader, I found that:</p>
  
  <pre><code>((java.net.JarURLConnection)new java.net.URL("jar:file:/home/user/my-app-with-dependencies_signed.jar!/META-INF/MANIFEST.MF").openConnection()).getJarEntry(); 
  </code></pre>
  
  <p>Ok. Works.</p>
  
  <pre><code>((java.net.JarURLConnection)new java.net.URL("jar:file:/home/user/my-app-with-dependencies_signed.jar!/META-INF/").openConnection()).getJarEntry();
  </code></pre>
  
  <p>Doesn't work! >.&lt;
  It throws</p>
  
  <pre><code>Exception occurred in target VM: JAR entry META-INF/ not found in /home/user/my-app-with-dependencies_signed.jar 
  java.io.FileNotFoundException: JAR entry META-INF/ not found in /home/user/my-app-with-dependencies_signed.jar
      at sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.java:142)
      at sun.net.www.protocol.jar.JarURLConnection.getJarEntry(JarURLConnection.java:94)
  ...
  </code></pre>
  
  <p>This same second example works when trying to access a unsigned or self-signed jar.</p>
  
  <p>This operation of opening the jar is performed by Spring when reading @Controller and @Component from the given packages in @ComponentScan.</p>
  
  <p>In the same way, Java's Class Loader doesn't read directories content, only specified files.</p>
  
  <pre><code>this.getClass().getClassLoader(); //sun.misc.Launcher$AppClassLoader@18b4aac2
  this.getClass().getClassLoader().getResources("META-INF/MANIFEST.MF").hasMoreElements(); //always true
  this.getClass().getClassLoader().getResources("META-INF/").hasMoreElements(); //false when signed
  </code></pre>
  
  <p><strong>UPDATE 2</strong></p>
  
  <p>I got the information about the signature. The people responsible for signatures and certificates actually uses a Windows applications that signs the jar with certificates from Windows-MY keystore and private key from a USB token.</p>
  
  <p>Not that this is certainly the cause, but I think it is important to note that <code>jarsigner</code> is not used.</p>
  
  <p><strong>UPDATE 3</strong></p>
  
  <p>I created a github repository with a simple test case: 
  <a href="https://github.com/jesjobom/signed-jar-class-loader-test" rel="nofollow noreferrer">https://github.com/jesjobom/signed-jar-class-loader-test</a></p>