java - URL.setURLStreamHandlerFactory

标签 java eclipse executable-jar

我正在使用带有嵌入式 Jetty 的可执行 jar 开发 Web 应用程序。
我的 jar 包含一个依赖的 jar。(jar in jar)
我引用了Eclipse开发的JarRsrcLoaderRsrcURLStreamHandlerFactory
JarRsrcLoader 使用 URL#setURLStreamHandlerFactory(RsrcURLStreamHandlerFactory) 解析 rsrc 协议(protocol)。
从而它可以解析jar的类路径。
但是作为副作用,解决通常的协议(protocol)变得不可能。
例如 file:xxxxjar:xxxx
RsrcURLStreamHandlerFactorysetURLStreamHandlerFactory 方法。
也许我认为我应该将默认实现设置为此方法。
我不知道是什么设置了这个方法。

最佳答案

URLStreamHandlerFactory 实现只有一个实例注册到 Java 运行时,因此该实现必须知道所有支持的协议(protocol)。

默认的 Oracle/Sun 行为不是以这种方式实现的,而是直接在 java.net.URL 类中实现的。因此,您不能简单地将默认实现作为链式工厂注入(inject)到 RsrcURLStreamHandlerFactory 中。答案的第一部分。

java.net.URL getURLStreamHandler 方法根据其类名的命名策略加载协议(protocol) X 的实现,通过默认为 sun.net.www.protocol.X.Handler

如果您查看 jre/lib/rt.jar,您会发现:

sun/net/www/protocol/ftp/Handler.class
sun/net/www/protocol/gopher/Handler.class
sun/net/www/protocol/mailto/Handler.class
sun/net/www/protocol/netdoc/Handler.class
sun/net/www/protocol/http/Handler.class
sun/net/www/protocol/jar/Handler.class
sun/net/www/protocol/file/Handler.class

用于协议(protocol) URLStreamHandler 选择的基础包列表来自 java.protocol.handler.pkgs Java 系统属性。我邀请您阅读 JDK src.zip 中的 java/net/URL.java 的完整源代码以了解详细信息。

  • 所以正确的方法(无论 IBM/Eclipse 做了什么)是保留默认机制并设置例如 -Djava.protocol.handler.pkgs="com.company.product .protocol" 在命令行上(如果您有这样做的许可/认证)。使用名为 com.company.product.protocol.rsrc.Handler 并使用 JarRsrcLoaderURLStreamHandler 实现,您就可以完成工作。

  • 另一种选择是在 RsrcURLStreamHandlerFactory 中编写一个 URLStreamHandlerFactory 实现作为链式工厂,灵感来自 URL.getURLStreamHandler 源代码。例如,您可以阅读 this old JBoss code .它依赖于 URL 内部处理程序缓存,方法是在注册工厂之前预加载其他已知(或使用)协议(protocol)。在我看来,只是丑陋。

警告:RsrcURLStreamHandler 已将 URLStreamHandler.parseURL 的原始 180 行代码替换为其自己的“10 行”版本"无需调用 super.parseURL。当然它不遵守 URL 连接规范!请注意,您可能会遇到错误,具体取决于此类 URL 的使用方式。

关于java - URL.setURLStreamHandlerFactory,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8938260/

相关文章:

java - 生成签名 APK 错误

c - 没有提示输入整数

java - 如何使用 JUnit 断言元素包含 Selenium 中的文本

java - com.mysql.cj.jdbc.exceptions.CommunicationsException : Communications link failure 2021 错误

java - 调试 HeapSort Java 代码

java - JFace:为特定节点扩展更多级别

java - Maven - 来自 java 项目的可执行文件

java - Tesseract For Java 为可执行 jar 设置 Tessdata_Prefix

java - Maven 全新安装不包括可执行 jar 文件的 sqlite 依赖项

java - 逐行读取文本文件并将这些行插入到输出文件上的 -d= 序列之后