WildFly 26.1.3.Final中JAR包内@WebServlet注解Servlet无法加载的解决方法
我有一个需集成若干Servlet的项目,因客户要求需部署JAR包而非WAR包。经多日研究,仍未找到让WildFly的Servlet容器加载JAR包中带@WebServlet注解的Servlet的方案(WAR包中的@WebServlet可正常工作,但无法采用WAR部署)。请问是否存在实现JAR包中Servlet正常运行的方法?
环境信息:
- WildFly 26.1.3.Final
- Servlet版本 4.0
附Servlet代码:
import java.io.IOException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(name = "hello", urlPatterns = {"/hello"}) public class Web extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.setContentType("text/html"); resp.getWriter().println("<html><head><title>hello</title></head><body>"); resp.getWriter().println("<h1>Hello World!</h1>"); resp.getWriter().println("</body></html>"); resp.getWriter().close(); } }
原本期望Servlet容器能启动Web上下文并加载带注解的Servlet。
在WildFly中部署包含@WebServlet注解的JAR包并让Servlet容器识别加载,可按以下步骤操作:
1. 调整JAR包结构,符合Web片段规范
WildFly只会自动识别符合Servlet规范的Web片段JAR,需要在JAR的META-INF目录下添加web-fragment.xml文件(即使内容为空,也能触发容器的Web组件扫描):
<?xml version="1.0" encoding="UTF-8"?> <web-fragment xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="4.0"> <!-- 无特殊配置需求时,保持内容为空即可 --> </web-fragment>
确保你的Servlet类已正确添加@WebServlet注解(你的代码已满足要求)。
2. 部署JAR到WildFly指定目录
将构建好的JAR包直接放入WildFly的standalone/deployments目录,WildFly的部署扫描器会自动检测并处理这个Web片段JAR。
3. 验证Servlet加载状态
启动WildFly后,查看standalone/log/server.log日志,搜索Servlet名称hello,如果出现类似Servlet hello mapped to [/hello]或Registered web context的日志条目,说明Servlet已成功加载。此时可通过http://<服务器地址>:8080/hello访问该Servlet。
备选方案:嵌入式容器启动(直接运行JAR)
如果需要直接通过java -jar命令启动JAR并运行Servlet,可集成WildFly嵌入式Servlet容器:
- 添加对应版本的嵌入式容器依赖(以Maven为例):
<dependency> <groupId>org.wildfly</groupId> <artifactId>wildfly-embedded</artifactId> <version>26.1.3.Final</version> </dependency>
- 创建主类手动启动容器并注册Servlet:
import org.jboss.as.embedded.EmbeddedServerFactory; import org.jboss.as.server.ServerController; import javax.servlet.ServletRegistration; import org.jboss.as.web.WebSubsystemServices; import org.jboss.msc.service.ServiceContainer; public class Main { public static void main(String[] args) throws Exception { ServerController server = EmbeddedServerFactory.createServer(); server.start(); ServiceContainer container = server.getServiceContainer(); ServletRegistration.Dynamic registration = container.getService(WebSubsystemServices.SERVLET_CONTEXT).getValue() .addServlet("hello", Web.class); registration.addMapping("/hello"); } }
构建可执行JAR后,直接通过java -jar your-jar-file.jar启动即可。
内容的提问来源于stack exchange,提问作者Riva86

