Closed pbrant closed 6 months ago
@pbrant Thank you for the explanation.
Now I understand why URLStreamHandler
might work. But I still don't understand why searching of this file in classpath didn't work. It should always work if the file is located in classpath.
@pbrant Juhuu, I managed to reproduce the issue in a Spring project. Given a Spring boot project
src/main/resources/templates/selenide-logo-big.png
.<img src="classpath:templates/selenide-logo-big.png"/>
It works with all FS versions: 9.3.0, 9.4.0, 9.4.1. The generated PDF contains the image.
NB!
The above mentioned error happens ONLY if I add a leading slash to image url: <img src="classpath:/templates/selenide-logo-big.png"/>
. Such URL fails with FS 9.4.0.
But I think it's just an invalid url. Users just need to remove the leading slash.
Hey, nice detective work!
My reading of RFC 3986 is that both variants are perfectly legal URIs.
In any case, the larger point is that, as a general rule, we should be quite tentative about breaking existing, working input (even if I'm sure it wasn't intentional in this case).
The new FS code is definitely not a drop-in replacement for the equivalent Spring code in more ways that just path handling. For a trivial example, take a look at https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/util/ClassUtils.html#getDefaultClassLoader() which handles the case when the context class loader is null, but it wouldn't surprise me if there are others.
No handler for the classpath protocol will be available unless the JRE is configured to make one available.
See e.g. https://docs.oracle.com/javase/8/docs/api/java/net/URL.html#URL-java.lang.String-java.lang.String-int-java.lang.String- for more information.
Based on Andrzej's description, Spring Boot (or maybe Spring itself) provides a handler for the classpath protocol.
This change provides backwards compatibility for those environments (Spring or otherwise) while falling back to the new implementation.
As an aside, I strongly suspect the Spring implementation is more defensive than the FS code. The context class loader cannot always be relied upon to return something useful (e.g. it could be null or set to something unhelpful). The FS code should be useful in many situations though.