Lately we noticed an issue when starting a Spring Boot Executable JAR from a path that uses the archived artifacts of our CI system. When investigating it further we found out that basically everything we scan for on the classpath via ClassGraph is no longer found when running it from such a directory. Compared to an older branch this seemed to be the result of our upgrade from ClassGraph 4.8.48 to 4.8.163.
When taking a deeper look and checking the verbose() output of ClassGraph we saw that all nested classpath entries were discarded because of a Malformed URI.
You get an error message like:
2023-11-02T12:51:42.719+0100 ClassGraph -- Skipping invalid classpath entry C:/Projects/_TMP/_User/junit4299279437227201409/directory with spaces #123/spring-boot-fully-executable-jar.jar!/BOOT-INF/lib/spring-boot-starter-actuator-1.5.9.RELEASE.jar : java.io.IOException: Malformed URI: C:/Projects/_TMP/_User/junit4299279437227201409/directory with spaces #123/spring-boot-fully-executable-jar.jar!/BOOT-INF/lib/spring-boot-starter-actuator-1.5.9.RELEASE.jar : java.net.URISyntaxException: Illegal character in opaque part at index 66: jar:file:C:/Projects/_TMP/_User/junit4299279437227201409/directory with spaces #123/spring-boot-fully-executable-jar.jar!/BOOT-INF/lib/spring-boot-starter-actuator-1.5.9.RELEASE.jar
The directories our CI system produces are in the form of ci-build product #buildnumber. So we played around a bit with that path and it seems the combination of the spaces and the hash symbol break the ClassGraph logic vor handling nested jars.
We checked the code and it seems that the base path of the file is handled as a String in the nested use case and only later again converted to a URL or as a fallback URI.
Given the following path, both conversions will fail:
jar:file:C:/Projects/_TMP/_User/junit4299279437227201409/directory with spaces #123/spring-boot-fully-executable-jar.jar!/BOOT-INF/lib/spring-core-4.3.13.RELEASE.jar
The reason for this is that first the URL conversion will fail with java.net.MalformedURLException: no !/ in spec as it will not be happy about the hash symbol (or rather what comes behind it I guess). After this the URI conversion will fail with final error java.net.URISyntaxException: Illegal character in opaque part at index 66: jar:file:... where the index is pointing to the first space present in the path.
Lately we noticed an issue when starting a Spring Boot Executable JAR from a path that uses the archived artifacts of our CI system. When investigating it further we found out that basically everything we scan for on the classpath via ClassGraph is no longer found when running it from such a directory. Compared to an older branch this seemed to be the result of our upgrade from ClassGraph
4.8.48to4.8.163.When taking a deeper look and checking the
verbose()output of ClassGraph we saw that all nested classpath entries were discarded because of a Malformed URI.You get an error message like:
The directories our CI system produces are in the form of
ci-build product #buildnumber. So we played around a bit with that path and it seems the combination of the spaces and the hash symbol break the ClassGraph logic vor handling nested jars.We checked the code and it seems that the base path of the file is handled as a
Stringin the nested use case and only later again converted to aURLor as a fallbackURI.Given the following path, both conversions will fail:
jar:file:C:/Projects/_TMP/_User/junit4299279437227201409/directory with spaces #123/spring-boot-fully-executable-jar.jar!/BOOT-INF/lib/spring-core-4.3.13.RELEASE.jarThe reason for this is that first the
URLconversion will fail withjava.net.MalformedURLException: no !/ in specas it will not be happy about the hash symbol (or rather what comes behind it I guess). After this theURIconversion will fail with final errorjava.net.URISyntaxException: Illegal character in opaque part at index 66: jar:file:...where the index is pointing to the first space present in the path.