Java17下Tomcat启动时EquinoxBridgeServlet.init()抛出异常求助
问题分析
核心异常为java.lang.Error: factory already defined,根源是Java平台规定URL.setURLStreamHandlerFactory()全局仅能调用一次,而Equinox OSGi的EquinoxFactoryManager在启动时尝试重复设置URL流处理工厂,触发该错误。
具体诱因:
- Java 17的模块系统与安全限制更严格,放大了旧版本Equinox与Tomcat的兼容性问题
- Tomcat本身或Web应用中的其他组件,可能已提前调用
setURLStreamHandlerFactory(),导致OSGi启动时再次调用失败 - 即使更新了
org.eclipse.core.runtime_3.29.0与org.eclipse.equinox.servletbridge_1.6.300,仍存在初始化逻辑未适配Java 17单次调用限制的问题
解决方案建议
禁用Equinox自动设置URL流处理工厂
在Servlet Bridge的配置中添加参数:- 若使用
web.xml配置BridgeServlet,添加初始化参数:<init-param> <param-name>osgi.url.handler.factory</param-name> <param-value>false</param-value> </init-param> - 若使用
config.ini,添加:osgi.url.handler.factory=false
该参数会让Equinox跳过自动安装URL流处理工厂,避免冲突。
- 若使用
升级至Java 17兼容的Equinox Servlet Bridge版本
确认是否有1.6.300之后的版本,优先选择明确标注支持Java 17的版本,新版本通常会修复URL工厂调用的兼容性问题。添加JVM模块化兼容参数
为Tomcat的启动JVM添加以下参数,确保Equinox能访问必要的JDK内部API:--add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED排查重复调用来源
检查Web应用或Tomcat的扩展组件,是否有提前调用setURLStreamHandlerFactory()的逻辑,改用-Djava.protocol.handler.pkgs参数指定协议处理包,替代直接调用该方法。清理重复依赖
检查WAR包中是否存在多版本的Equinox/OSGi相关依赖(如org.eclipse.osgi),删除重复包避免类加载冲突导致的重复初始化。
内容的提问来源于stack exchange,提问作者hotcoder
相关产品推荐
相关产品推荐

