This is basically same issue but with a test project provided that you can debug https://bz.apache.org/bugzilla/show_bug.cgi?id=57736 What happens is javax.crypto.JarVerifier.verifySingleJar complains about unsigned content which in fact there's not such content in the jar but for some reason all WAR resources appear as jar's content java.util.jar.JarException: jar:file:/C:/Users/bahisha/work/apache-tomcat-8.0.36/webapps/test.war!/WEB-INF/lib/bcprov-jdk16-1.46.jar has unsigned entries - WEB-INF/lib/bcprov-jdk16-1.46.jar
Created attachment 34206 [details] test war zip part 1
Created attachment 34207 [details] test war zip part 2
I reproduced error on Tomcat 8.0.x with unpackWARs="false". Error because of the getLocation(), which returns codeBaseURL for resource file. Location URL is jar:file:/some_path/webapps/test.war!/WEB-INF/lib/bcprov-jdk16-1.46.jar, but ((JarURLConnection)url.openConnection()).getJarFile() connects to the test.war instead bcprov-jdk16-1.46.jar, because the test.war before separator '!/'. We need jar:war: path to access resource inside of test.war file (because it doesn't unpack). This is example of the URL which have to be used in given test: jar:war:file:/some_path/webapps/test.war*/WEB-INF/lib/bcprov-jdk16-1.46.jar!/ I looked at sources and notice that getLocation() returns AbstractArchiveResource.codeBaseUrl field, for war resources this field generates in constructor JarWarResource, I changed constructor of JarWarResource for codeBaseUrl: before codeBaseUrl="jar:" + baseUrl + "!/" + archivePath after codeBaseUrl="jar:war:" + baseUrl + "*/" + archivePath+"!/" I rebuilt tomcat and tried attached test, everything works fine, But I have doubts in solution correctness, because codeBaseUrl uses in WebappClassLoaderBase.getPermissions() function, which gets permissions for codeSource. In current version, for codeSource /some_path/webapps/test.war!/WEB-INF/lib/bcprov-jdk16-1.46.jar, getPermissions returns permission collection for test.war, but after changes of codeBaseURL getPermissions() returns permissions for bcprov-jdk16-1.46.jar which located in war archive. Could somebody confirm that changing JarWarResource's constructor is a right solution?
Unfortunately, it doesn't appear to be as clear cut as I would like. If we look at how the JRE constructs a code path for a JAR, it returns a "file:" URL to the JAR, not a "jar:" URL. Therefore, if Tomcat is to be consistent with that, the current behavior is correct. However, the JarVerifier accepts either a "file:" or "jar:" URL for a JAR and ignores the possibility of JARs in WARs etc entirely. Returning "jar:" URLs and "jar:war:" URLs would fix JarVerifier but might break other functionality. I need to do some more testing with the security manager.
This has been fixed in the following branches: - 9.0.x for 9.0.0.M11 onwards - 8.5.x for 8.5.6 onwards - 8.0.x for 8.0.38 onwards 7.0.x and earlier versions were not affected. Fixing this required refactoring of the web resources handling to use the Tomcat specific 'war:file:...' URL protocol to refer to WAR files and their contents rather than the standard 'jar:file:...' form. A side-effect of the refactoring is that when using packed WARs, it is now possible to reference a WAR and/or specific JARs within a WAR in the security policy file used when running under a SecurityManager.
This solution has introduced a new issue resolving resources url. I've made a project to test this behaviour https://github.com/didiez/tomcat-bug-60087 Run the main-app to see the problem. If built changing tomcat.version to 8.5.5 everything works as expected.
(In reply to Diego Díez Ricondo from comment #6) > This solution has introduced a new issue resolving resources url. > I've made a project to test this behaviour > https://github.com/didiez/tomcat-bug-60087 > > Run the main-app to see the problem. If built changing tomcat.version to > 8.5.5 everything works as expected. Update the status in favor to the archives. This has been fixed: https://bz.apache.org/bugzilla/show_bug.cgi?id=60391