Glassfish 5.1 EE8集成Waffle库做HTTP基础认证遇AbstractMethodError
问题:Chrome输入账号密码后抛出AbstractMethodError异常
在Google Chrome的弹出框中输入用户名和密码后,系统抛出如下异常:
java.lang.AbstractMethodError: com.sun.jna.Structure.getFieldOrder()Ljava/util/List; at com.sun.jna.Structure.fieldOrder(Structure.java:952) at com.sun.jna.Structure.getFields(Structure.java:1006) at com.sun.jna.Structure.deriveLayout(Structure.java:1172) at com.sun.jna.Structure.calculateSize(Structure.java:1097) at com.sun.jna.Structure.calculateSize(Structure.java:1049) at com.sun.jna.Structure.allocateMemory(Structure.java:403) at com.sun.jna.Structure.<init>(Structure.java:194) at com.sun.jna.Structure.<init>(Structure.java:182) at com.sun.jna.Structure.<init>(Structure.java:169) at com.sun.jna.Structure.<init>(Structure.java:161) at com.sun.jna.platform.win32.Sspi$SecHandle.<init>(Sspi.java:496) at com.sun.jna.platform.win32.Sspi$CredHandle.<init>(Sspi.java:536) at waffle.windows.auth.impl.WindowsCredentialsHandleImpl.initialize(WindowsCredentialsHandleImpl.java:92) at waffle.windows.auth.impl.WindowsAuthProviderImpl.acceptSecurityToken(WindowsAuthProviderImpl.java:125) at waffle.servlet.spi.NegotiateSecurityFilterProvider.doFilter(NegotiateSecurityFilterProvider.java:139) at waffle.servlet.spi.SecurityFilterProviderCollection.doFilter(SecurityFilterProviderCollection.java:162) at waffle.servlet.NegotiateSecurityFilter.doFilter(NegotiateSecurityFilter.java:180) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:167)
环境配置
- Windows 10 Pro 版本22H2(内部版本19045.6466)
- Glassfish 5.1
- jdk-8.0.482.8-hotspot
- NetBeans 8.2(附配置截图)
已尝试的解决方法
- 降级Glassfish到5.0
- 更换多个版本的JNA、Waffle库(最高用到3.3.0,3.4.0版本会出现Java版本不兼容异常),但问题依旧。
项目相关文件
index3.jsp
<jsp:forward page="index.jsf"/>
index.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%> <%@taglib uri="http://java.sun.com/jsf/core" prefix="f"%> <%@taglib uri="http://myfaces.apache.org/tomahawk" prefix="t"%> <html> <head> </head> <body> <div>test</div> </body> </html>
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?> <faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_2.xsd" version="2.2"> </faces-config>
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"> <context-param> <param-name>javax.faces.CONFIG_FILES</param-name> <param-value> /WEB-INF/faces-config.xml </param-value> </context-param> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file>index3.jsp</welcome-file> </welcome-file-list> <filter-mapping> <filter-name>SecurityFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>SecurityFilter</filter-name> <filter-class>waffle.servlet.NegotiateSecurityFilter</filter-class> <init-param> <param-name>securityFilterProviders</param-name> <param-value> waffle.servlet.spi.BasicSecurityFilterProvider waffle.servlet.spi.NegotiateSecurityFilterProvider </param-value> </init-param> </filter> </web-app>
解决方案
这个AbstractMethodError异常的核心原因是JNA版本冲突:应用中同时存在两个不同版本的JNA库,其中旧版本的Structure类未实现返回List的getFieldOrder()方法,但新版本的代码尝试调用该方法,导致异常。
具体解决步骤:
清理重复的JNA依赖
- 检查Glassfish服务器的
lib目录,若存在旧版本的jna.jar或jna-platform.jar,直接删除。 - 检查项目的
WEB-INF/lib目录,确保只保留与当前Waffle版本匹配的JNA库文件。
- 检查Glassfish服务器的
强制指定JNA版本
若使用Maven或Gradle管理依赖,明确指定JNA版本,避免依赖传递带来的冲突。以Maven为例:<dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>5.13.0</version> </dependency> <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna-platform</artifactId> <version>5.13.0</version> </dependency>Waffle 3.3.0要求JNA版本至少为5.6.0,建议使用官方推荐的匹配版本。
调整类加载优先级
确保项目WEB-INF/lib中的JNA库优先于服务器自带的旧版本加载。可在Glassfish的域配置文件中修改类加载顺序,或直接将匹配版本的JNA库放入WEB-INF/lib,覆盖服务器自带的旧库。验证兼容性
确认Waffle与JNA版本完全兼容,避免因版本不匹配导致的方法缺失或不兼容问题。
内容的提问来源于stack exchange,提问作者Marcin Korkuś
相关产品推荐
相关产品推荐

