Javalin运行时错误:未注册.vm扩展名渲染器的解决请求
问题:Javalin访问页面抛出"No Renderer registered for extension '.vm'"错误
环境与修改内容
- 基于Javalin框架开发Web应用,以javalin-website-example为模板
- 已做修改:
- 将Javalin版本升级为5.6.3
- 将Google Guava版本改为32.1.3-jre
- 包名替换为
org.nsorokin.tools.taskcontroller.clientweb.app
- 开发环境:Eclipse 2023-09,Java 11(BellSoft JDK 11.0.15.1+2-LTS)
项目代码
ClientWeb.java
package org.nsorokin.tools.taskcontroller.clientweb.app; import org.nsorokin.tools.taskcontroller.clientweb.app.util.Filters; import org.nsorokin.tools.taskcontroller.clientweb.app.util.Path; import org.nsorokin.tools.taskcontroller.clientweb.app.login.LoginController; import org.nsorokin.tools.taskcontroller.clientweb.app.index.IndexController; import org.nsorokin.tools.taskcontroller.clientweb.app.user.UserDao; import org.nsorokin.tools.taskcontroller.clientweb.app.util.Filters; import io.javalin.plugin.bundled.RouteOverviewPlugin; //import io.javalin.rendering.JavalinRenderer; import static io.javalin.apibuilder.ApiBuilder.before; import static io.javalin.apibuilder.ApiBuilder.get; import static io.javalin.apibuilder.ApiBuilder.post; import io.javalin.Javalin; import io.javalin.http.staticfiles.Location; public class ClientWeb { public static UserDao userDao; public static void main(String[] args) { userDao = new UserDao(); Javalin clientWebApp = Javalin.create(config -> { config.staticFiles.add("/public", Location.CLASSPATH); config.plugins.register(new RouteOverviewPlugin("/routes")); }).start(7000); clientWebApp.routes(() -> { before(Filters.handleLocaleChange); before(LoginController.ensureLoginBeforeViewingBooks); get(Path.Web.INDEX, IndexController.serveIndexPage); get(Path.Web.LOGIN, LoginController.serveLoginPage); post(Path.Web.LOGIN, LoginController.handleLoginPost); post(Path.Web.LOGOUT, LoginController.handleLogoutPost); }); //ClientWeb cWeb = new ClientWeb(); //cWeb.process(args); } protected void process(String[] args) { } }
IndexController.java
package org.nsorokin.tools.taskcontroller.clientweb.app.index; import static org.nsorokin.tools.taskcontroller.clientweb.app.ClientWeb.*; import java.util.Map; import org.nsorokin.tools.taskcontroller.clientweb.app.util.Path; import org.nsorokin.tools.taskcontroller.clientweb.app.util.ViewUtil; import io.javalin.http.Handler; public class IndexController { public static Handler serveIndexPage = ctx -> { Map<String, Object> model = ViewUtil.baseModel(ctx); model.put("users", userDao.getAllUserNames()); //model.put("book", bookDao.getRandomBook()); ctx.render(Path.Template.INDEX, model); }; }
问题现象
项目构建成功,无编译错误,应用可正常启动,但访问登录页或首页时触发错误,错误信息为:
java.lang.IllegalArgumentException: No Renderer registered for extension '.vm'.
完整错误栈
Dec 14, 2023 10:47:40 AM io.javalin.util.JavalinLogger warn WARNING: Uncaught exception java.lang.IllegalArgumentException: No Renderer registered for extension '.vm'. at io.javalin.rendering.JavalinRenderer.renderBasedOnExtension(JavalinRenderer.kt:32) at io.javalin.rendering.LegacyFileRenderer.render(JavalinRenderer.kt:20) at io.javalin.http.Context.render(Context.kt:452) at org.nsorokin.tools.taskcontroller.clientweb.app.index.IndexController.lambda$0(IndexController.java:18) at io.javalin.routing.HandlerEntry.handle(HandlerEntry.kt:19) at io.javalin.http.servlet.DefaultTasks.HTTP$lambda$8$lambda$6$lambda$5(DefaultTasks.kt:39) at io.javalin.http.servlet.JavalinServlet.handleTask(JavalinServlet.kt:88) at io.javalin.http.servlet.JavalinServlet.handleSync(JavalinServlet.kt:53) at io.javalin.http.servlet.JavalinServlet.service(JavalinServlet.kt:41) at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:587) at io.javalin.jetty.JavalinJettyServlet.service(JavalinJettyServlet.kt:58) at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:587) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:764) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:529) at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1570) at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1381) at io.javalin.jetty.JettyServer$start$wsAndHttpHandler$1.doHandle(JettyServer.kt:61) at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:484) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1543) at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1303) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129) at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:173) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122) at org.eclipse.jetty.server.Server.handle(Server.java:563) at org.eclipse.jetty.server.HttpChannel$RequestDispatchable.dispatch(HttpChannel.java:1598) at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:753) at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:501) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:287) at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314) at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100) at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:969) at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1194) at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1149) at java.base/java.lang.Thread.run(Thread.java:829)
原因分析
.vm是Velocity模板引擎的文件后缀,Javalin 5.x版本开始不再默认集成Velocity渲染器,原示例项目依赖的Velocity渲染支持在升级Javalin后缺失,导致框架无法找到对应后缀的模板渲染器,触发该错误。
解决方法
1. 添加必要依赖
如果使用Maven,在pom.xml中添加以下依赖:
<!-- Javalin渲染核心依赖 --> <dependency> <groupId>io.javalin</groupId> <artifactId>javalin-rendering</artifactId> <version>5.6.3</version> </dependency> <!-- Velocity引擎核心依赖 --> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.3</version> </dependency>
2. 注册Velocity渲染器
在Javalin启动代码中注册Velocity渲染器,修改ClientWeb.java中的初始化逻辑:
import io.javalin.rendering.template.JavalinVelocity; public static void main(String[] args) { userDao = new UserDao(); Javalin clientWebApp = Javalin.create(config -> { config.staticFiles.add("/public", Location.CLASSPATH); config.plugins.register(new RouteOverviewPlugin("/routes")); // 注册Velocity渲染器 config.registerPlugin(JavalinVelocity.create()); }).start(7000); // ... 路由配置不变 }
或者手动注册渲染器(如果上述插件方式不生效):
import io.javalin.rendering.JavalinRenderer; import io.javalin.rendering.template.VelocityRenderer; public static void main(String[] args) { userDao = new UserDao(); // 手动注册Velocity渲染器 JavalinRenderer.register(new VelocityRenderer(), ".vm"); Javalin clientWebApp = Javalin.create(config -> { config.staticFiles.add("/public", Location.CLASSPATH); config.plugins.register(new RouteOverviewPlugin("/routes")); }).start(7000); // ... 路由配置不变 }
内容的提问来源于stack exchange,提问作者Nick S
相关产品推荐
相关产品推荐

