GlassFish 7中invalid URLPatternSpec异常的成因及解决方法
在GlassFish 7中解决invalid URLPatternSpec异常的原因与修复方案
异常原因
这个invalid URLPatternSpec异常核心是传入的URL模式不符合Jakarta EE规范的语法要求,常见触发场景包括:
- URL模式违反规范:Jakarta EE只允许三种合法URL模式:精确匹配(如
/api/users)、前缀匹配(如/api/*)、扩展名匹配(如*.jsp),混合两种模式的写法(比如/api/*.jsp)直接无效。 - 配置文件存在错误:web.xml的
<url-pattern>标签、server.policy中WebResourcePermission的URL参数、代码中@WebServlet/@SecurityConstraint等注解定义的URL模式,出现语法错误、非法字符或空值。 - 无效的模式字符串:配置了空的URL模式、包含空格或其他不允许的特殊字符的模式。
修复步骤
1. 全面排查所有URL模式配置
- 检查web.xml中
<security-constraint>下的<url-pattern>,确保每个模式都符合三种合法类型,没有混合写法,也没有非法字符。 - 检查server.policy中的授权语句,比如
grant { permission jakarta.security.jacc.WebResourcePermission "/api/*", "GET,POST"; };,确认其中的URL模式严格符合规范。 - 检查代码里的注解配置,比如
@WebServlet(urlPatterns = "/invalid/*.jsp")这类错误写法要立即修正。
2. 验证URL模式合法性
- 绝对禁止使用
/api/*.jsp这种混合前缀和扩展名的模式,可拆分需求为两个独立模式(如/api/*和*.jsp)。 - 确保所有URL模式非空,且不包含空格、制表符等无效字符。
3. 清理缓存并重启服务器
- 删除GlassFish域目录下的临时文件:
domains/[你的域名]/generated和domains/[你的域名]/cache。 - 重启GlassFish,确保配置修改完全生效。
4. 定位具体无效模式
- 逐步注释配置中的URL模式,逐个测试服务,找到引发异常的具体模式。
- 查看GlassFish的详细日志,定位触发异常的请求URL,对应检查匹配该URL的所有配置项。
异常日志详情
[2024-02-09T18:49:24.885241Z] [GF 7.0.11] [SEVERE] [] [com.sun.web.security.RealmAdapter] [tid: _ThreadID=30 _ThreadName=http-listener-1(3)] [levelValue: 1000] [[ Authentication passed, but authorization failed. java.lang.IllegalArgumentException: invalid URLPatternSpec at jakarta.security.jacc.URLPatternSpec.setURLPatternArray(URLPatternSpec.java:326) at jakarta.security.jacc.URLPatternSpec.<init>(URLPatternSpec.java:79) at jakarta.security.jacc.WebResourcePermission.<init>(WebResourcePermission.java:141) at org.glassfish.exousia.AuthorizationService.checkWebResourcePermission(AuthorizationService.java:454) at org.glassfish.exousia.AuthorizationService.checkWebResourcePermission(AuthorizationService.java:442) at com.sun.enterprise.security.ee.web.integration.WebSecurityManager.hasResourcePermission(WebSecurityManager.java:260) at com.sun.web.security.RealmAdapter.invokeWebSecurityManager(RealmAdapter.java:1151) at com.sun.web.security.RealmAdapter.preAuthenticateCheck(RealmAdapter.java:450) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:415) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:529) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:503) at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:71) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:121) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:295) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:188) at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:425) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:144) at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:174) at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:153) at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:196) at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:88) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:246) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:178) at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:118) at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:96) at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:51) at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:510) at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:82) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:83) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:101) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:535) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:515) at java.base/java.lang.Thread.run(Thread.java:842)]]
内容的提问来源于stack exchange,提问作者Jabbathehutt
相关产品推荐
相关产品推荐

