如何在Groovy 2.4中排除内置servlet-api-2.4以使用Jetty 9?
解决Groovy 2.4与Jetty 9(Servlet API 3.1)的依赖冲突问题
我太懂这个坑了!Groovy 2.4自带的servlet-api-2.4.jar确实是个顽固的家伙,优先级还特别高——就算你用Grape拉了3.1版本,旧版依然会覆盖它,导致调用Servlet 3.x新增的方法(比如HttpServletResponse.getStatus())时抛出java.lang.NoSuchMethodError。给你几个亲测有效的解决办法:
1. 通过启动参数强制优先加载新版Servlet API
运行Groovy脚本时,把javax.servlet-api 3.1.0的jar路径放在classpath最前端,直接覆盖Groovy自带的旧版。
如果已经用Grape声明了依赖,可以用下面的命令自动获取Grape下载的jar路径并拼到classpath:
groovy -Dgroovy.classpath=$(groovy -e 'println Grape.grab([group:"javax.servlet", module:"javax.servlet-api", version:"3.1.0"]).collect{it.absolutePath}.join(":")') YourScript.groovy
或者手动指定jar路径:
groovy -cp "/path/to/javax.servlet-api-3.1.0.jar:/path/to/jetty-related-jars/*" YourScript.groovy
2. 直接替换Groovy安装目录的旧版依赖
这个方法一劳永逸,但要注意会影响所有使用该Groovy环境的项目:
- 找到你的Groovy安装目录下的
lib文件夹 - 删除里面的
servlet-api-2.4.jar - 下载
javax.servlet-api-3.1.0.jar放到该lib文件夹中
3. 在脚本中通过类加载器强制加载新版
在脚本最开头添加一段代码,把新版Servlet API的jar加到根类加载器的URL列表中,让它优先被加载:
@Grab('javax.servlet:javax.servlet-api:3.1.0') // 获取Grape下载的servlet-api jar路径 def servletApiJar = new File(Grape.grab([group:'javax.servlet', module:'javax.servlet-api', version:'3.1.0'])[0].absolutePath) // 加到根类加载器 this.getClass().classLoader.rootLoader.addURL(servletApiJar.toURI().toURL()) // 接下来正常编写你的Jetty代码 import org.eclipse.jetty.server.Server import org.eclipse.jetty.servlet.ServletHandler import javax.servlet.http.HttpServlet import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse def server = new Server(8080) def handler = new ServletHandler() server.handler = handler handler.addServletWithMapping(new HttpServlet() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) { resp.status = 200 // 现在可以正常调用3.1的方法了 resp.writer.println("Hello from Jetty 9!") } }, "/*") server.start() server.join()
4. 用构建工具管理依赖(推荐复杂项目)
如果你的项目规模较大,建议用Gradle或Maven来管理依赖,它们会自动处理依赖冲突,确保新版Servlet API被优先加载。比如Gradle的配置:
plugins { id 'groovy' } repositories { mavenCentral() } dependencies { implementation 'org.codehaus.groovy:groovy-all:2.4.21' implementation 'javax.servlet:javax.servlet-api:3.1.0' implementation 'org.eclipse.jetty:jetty-server:9.4.52.v20230823' implementation 'org.eclipse.jetty:jetty-servlet:9.4.52.v20230823' }
运行时直接用gradle run,构建工具会帮你处理好classpath的优先级问题。
内容的提问来源于stack exchange,提问作者r0b0
相关产品推荐
相关产品推荐

