我正在开发一个提供REST HTTP(S)请求的Spring Boot应用程序.(很常见).
它按预期工作,但在最终(和工作)jar签名后(通过有效证书),所有URL映射都停止工作,只返回404到任何请求.(请注意,嵌入式Tomcat服务器启动没有问题,我没有收到任何异常)
经过一些调试后,我发现Java的默认ClassLoader(Laucher $ AppClassLoader)在jar签名时不会返回我配置的包(@ComponentScan)中的类.
//org.springframework.core.io.support.PathMatchingResourcePatternResolver
//Param 'path' has my valid, existing and desired package with @Controller or @Component inside
protected Set<Resource> doFindAllClassPathResources(String path) throws IOException {
Set<Resource> result = new LinkedHashSet<Resource>(16);
ClassLoader cl = getClassLoader(); //sun.misc.Laucher$AppClassLoader
Enumeration<URL> resourceUrls = (cl != null ? cl.getResources(path) : ClassLoader.getSystemResources(path));
//Empty enumeration when jar is signed
...
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用自定义类加载器但没有成功; 同样的问题.
由于它在我使用自签名证书对jar进行签名时起作用,我认为签名过程可能存在由另一个人完成的问题.但我找不到任何证据.
看来,一旦签名,我就无法列出包裹内容......
如果我认为有用,我会尝试更多的测试并添加到这里...
UPDATE
在自定义类加载器的帮助下调试后,我发现:
((java.net.JarURLConnection)new java.net.URL("jar:file:/home/user/my-app-with-dependencies_signed.jar!/META-INF/MANIFEST.MF").openConnection()).getJarEntry();
Run Code Online (Sandbox Code Playgroud)
好.作品.
((java.net.JarURLConnection)new java.net.URL("jar:file:/home/user/my-app-with-dependencies_signed.jar!/META-INF/").openConnection()).getJarEntry();
Run Code Online (Sandbox Code Playgroud)
不行!>.<它抛出
Exception occurred in target VM: JAR entry META-INF/ not found …Run Code Online (Sandbox Code Playgroud)