1 快速上手

2 JFinalConfig

3 Controller

4 AOP

5 ActiveRecord

6 Enjoy 模板引擎

7 EhCachePlugin

8 RedisPlugin

9 Cron4jPlugin

10 Validator

11 国际化

12 Json 转换

13 JFinal架构及扩展

14 升级到 5.2.2

1.5 jfinal-undertow 常见问题

1、IDEA 下支持热加载

     jfinal undertow 是通过监听 target/classes 下面的 .class 文件被修改事件去触发的热加载。

    eclipse 拥有自动编译功能,会在 java 源代码文件保存时自动编译并更新 target/classes 下的相关 .class 文件,所以 eclipse 下面默认就支持热加载。注意 eclipse 的自动编译菜单一定要勾选上(默认是勾选的),如下图:

eclipse-auto-compile.png

    但 IDEA 默认并不支持自动编译,那么 target/classes 下面的 .class 文件无法及时更新,所以 IDEA 默认不支持热加载。因此需要想办法触发 IDEA 的编译动作,建议去网上找一些开启 IDEA 自动编译的配置方法。 下面的链接给出了一种通过快捷键触发编译的方法供参考:

https://my.oschina.net/fdblog/blog/172229

    此外,jfinal 官网很久以前的文档也给出过一种方法:

https://www.jfinal.com/share/1357

    最后:别忘了 undertow.devMode 要配置成 true 才支持热加载,具体配置方法见前面两小节的文档。


2、IDEA 下模板文件路径不正确

    在 IDEA 下发时,如果是通过打开项目的目录,或者通过打开项目的 pom.xml 文件导入的 maven 项目将会找不到模板文件路径。正确的导入方法如下:

idea-1.png

    如下图所示,一定要选择 import project,而不能选择 Open,下一步是选择项目根目录:

idea-2.png

    再一步是选择 maven:

idea-3.png

    然后再一路点击 next 直到完成即可。

    要点:如果第一步选择 Open 将是错误的做法。如果项目已经使用上述方式导入过一次,IDEA 生成了各种配置文件,那么选择 Open 打开项目的方式没有问题。


3、 maven 多模块项目启动报错

    如果 maven 的多 module 结构项目在启动时出现找不到模板的异常,该异常的原因是在 IDEA 多模块中启动项目时,其工作路径处在当前启动模块的上一级目录,所以默认的 undertow.resourcePath 配置值 src/main/webapp 是不正确的,需要再加一层当前模块名才能指向正确的资源路径,例如:

undertow.resourcePath = 这里修改为启动模块的名称/src/main/webapp, src/main/webapp

    以上配置用逗号分隔了两个路径配置,前者支持 IDEA,后者支持 ecilpse,该配置可以同时兼容两种开发工具。并且,上述配置即便在路径不存在时也没有副作用(jfinal undertow内部会判断路径是否存在),非常优雅。

    这里有相关问题的分享:

http://www.jfinal.com/share/1285

https://my.oschina.net/imlzw/blog/3106769


4、类型转换异常、子类对象无法赋值到基类变量

    如果两个类路径与类名完全一样的两个类出现类型转换异常(java.lang.ClassCastException),或者子类对象无法赋值给基类变量,可以通过配置 hotSwapClassPrefix 来解决。

    再补充几个也属于这个问题的异常:java.lang.VerifyError: Bad type on operand stack 以及 java.lang.IncompatibleClassChangeError

    假定出现转换异常的类为: "com.abc.UserService",解决办法如下:

UndertowServer.create(MyApp.class)
    .addHotSwapClassPrefix("com.abc.")
    .start();

    如上所示,将出现类型转换异常的类的包前缀通过 addHotSwapClassPrefix(...) 添加进去即可。原因是 jfinal undertow 默认只对 target/classes 以及 jfinal 自身进行热加载,所以当你的类文件在 jar 包并且需要被热加载的时候就需要通过上面的办法添加为被热加载。

    一般情况下你项目中 target/classes 下的类文件正好才是需要被热加载的类,所以不会有问题。这个配置仅用于开发环境,部署环境没有热加载机制,所以完全没有影响。

    此外,还可以通过配置文件来设置:

undertow.hotSwapClassPrefix=com.abc.

   如果要添加多个,可以通过逗号分隔。


     最新补充:在少数情况下即便是通过配置 hotSwapClassPrefix 将出现类型转换异常的类处理掉了,但仍然不起作用,这是因为一些第三方软件里头缓存了出问题的 class 或者对象,例如:xstream 这个将 xml 转 object 的工具,需要再追加如下配置:

addHotSwapClassPrefix("com.thoughtworks.")

    如上所示,将这类有缓存动作的第三方也配置成 hot swap class 就没问题了,重点要找到这些第三方。

    

    用户反馈不断补充要配置的项目还有 j2cache 以及作者 dreamlu 开源的一些项目,需要配置:

addHotSwapClassPrefix("net.oschina.j2cache.")

addHotSwapClassPrefix("net.dreamlu.")


    这个设计完全是出于热加载的性能优化,本可以默认将这类 class 加载为 hotSwapClass,但性能不如当前的设计好。

   

5、shiro 热加载问题

    jfinal undertow 暂不支持 shiro 热加载,配置 undertow.devMode=false 可以使用,但不支持热加载


6、部署在外网服务器上无法访问问题

   出于安全性考虑 jfinal undertow 早期版本的 undertow.host 默认配置为了 localhost,外网服务器上无法访问时,使用如下配置:

undertow.host=0.0.0.0

   如果添加了上述配置还是无法访问,检查一下阿里云是否开启了相关的端口号(假定你用的阿里云)。

    为了便利性,新版本 jfinal undertow 的 undertow.host 默认配置改成了 0.0.0.0,如果不希望在外网直接访问,需要将其配置为 localhost。

   注意,这里所谓的外网无法访问,也包括局域网内访问的机器与部署机器并非同一台机器的情况。


7、脚本无法使用问题

     jfinal 官方提供的 jfinal.sh、jfinal.bat 脚本文件里面有较为详细的使用说明,只要按照说明去使用一般不会有问题。

    这里要提醒一个比较奇葩的问题,假定你自己创建上述脚本文件,虽然是从 jfinal 官方 copy 过去的内容,然后死活就是无法使用,原因是脚本文件的换行符出了问题。 linux、mac 系统之下的脚本换行字符必须是 '\n',而 windows 下必须是 "\r\n"。

     查看脚本文件的换行字符的方法是:先用 eclipse 打开一个 java 源代码文件,然后在工具栏点击一下 "Show Whitespace Characters" 这个图标,然后再用 eclipse 打开脚本文件,在每行末尾处会显示出换行字符。显示一个字符的就是 '\n',否则就是 '\r\n'。

    注意,此问题与 jfinal 完全无关,是操作系统自己的限制。

    重要:最近俱乐部同学发现一类新的脚本无法启动的原因,那就是 pom.xml 中的 jetty 依赖没有删除,从而引发异常:java.lang.NoClassDefFoundError: com/jfinal/config/JFinalConfig,删掉 jetty 依赖即可解决。


8、JSP 支持问题

   为提升应用的安全性,jfinal 较新的版本默认不能对 .jsp 文件直接进行访问,也就是在浏览器地址栏中无法输入 .jsp 文件名去访问 jsp 文件,但是可以通过 renderJsp(xxx.jsp) 来访问 jsp 文件。如果确实需要直接访问 jsp 文件,需要添加如下配置:

public void configConstant(Constants me) {
    me.setDenyAccessJsp(false);
}

   jfinal undertow 支持 jsp 功能需要类似下面的配置:

UndertowServer.create(DemoConfig.class)
   .configWeb(wb -> {
      wb.getDeploymentInfo().addServlet(JspServletBuilder.createServlet("Default Jsp Servlet", "*.jsp"));

      HashMaptagLibraryInfo = new HashMap<>();
      JspServletBuilder.setupDeployment(wb.getDeploymentInfo(), new HashMap(),
      tagLibraryInfo, new HackInstanceManager());
   })
   .start();

    更多信息可以参考如下资源:

https://jfinal.com/share/1890

https://jfinal.com/share/1899

https://github.com/shanmine/undertow-jsp-demo.git


9、 mp4 无法播放、xls 无法下载等 contentType 不正确的问题

    需要添加类似如下配置:

UndertowServer
  .create()
  .configWeb(
      builder->{MimeMapping xlsMimeMapping = new MimeMapping("xls","application/vnd.ms-excel");
      builder.getDeploymentInfo().addMimeMapping(xlsMimeMapping);
})
.start();

   以上是 xls 的示例,mp4 文件与之也类似,相关参考资源:

https://jfinal.com/feedback/7237
https://gitee.com/jfinal/jfinal-undertow/issues/I1FIBH