jfinal undertow 是通过监听 target/classes 下面的 .class 文件被修改事件去触发的热加载。
eclipse 拥有自动编译功能,会在 java 源代码文件保存时自动编译并更新 target/classes 下的相关 .class 文件,所以 eclipse 下面默认就支持热加载。注意 eclipse 的自动编译菜单一定要勾选上(默认是勾选的),如下图:
但 IDEA 默认并不支持自动编译,那么 target/classes 下面的 .class 文件无法及时更新,所以 IDEA 默认不支持热加载。因此需要想办法触发 IDEA 的编译动作,建议去网上找一些开启 IDEA 自动编译的配置方法。 下面的链接给出了一种通过快捷键触发编译的方法供参考:
https://my.oschina.net/fdblog/blog/172229
此外,jfinal 官网很久以前的文档也给出过一种方法:
https://www.jfinal.com/share/1357
最后:别忘了 undertow.devMode 要配置成 true 才支持热加载,具体配置方法见前面两小节的文档。
在 IDEA 下发时,如果是通过打开项目的目录,或者通过打开项目的 pom.xml 文件导入的 maven 项目将会找不到模板文件路径。正确的导入方法如下:
如下图所示,一定要选择 import project,而不能选择 Open,下一步是选择项目根目录:
再一步是选择 maven:
然后再一路点击 next 直到完成即可。
要点:如果第一步选择 Open 将是错误的做法。如果项目已经使用上述方式导入过一次,IDEA 生成了各种配置文件,那么选择 Open 打开项目的方式没有问题。
如果 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
如果两个类路径与类名完全一样的两个类出现类型转换异常(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,但性能不如当前的设计好。
jfinal undertow 暂不支持 shiro 热加载,配置 undertow.devMode=false 可以使用,但不支持热加载
出于安全性考虑 jfinal undertow 早期版本的 undertow.host 默认配置为了 localhost,外网服务器上无法访问时,使用如下配置:
undertow.host=0.0.0.0
如果添加了上述配置还是无法访问,检查一下阿里云是否开启了相关的端口号(假定你用的阿里云)。
为了便利性,新版本 jfinal undertow 的 undertow.host 默认配置改成了 0.0.0.0,如果不希望在外网直接访问,需要将其配置为 localhost。
注意,这里所谓的外网无法访问,也包括局域网内访问的机器与部署机器并非同一台机器的情况。
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 依赖即可解决。
为提升应用的安全性,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://github.com/shanmine/undertow-jsp-demo.git
需要添加类似如下配置:
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