slim3でjspのスクリプトレットでもHot Reloadingする方法
slim3のHotReloadingでClassCastExceptionのエラーが発生した - あおうさ@日記の続き。
解決方法をid:higayasuoさんに教えてもらったので下記のようにした。
BlogDao.class
public List<Blog> findAll() { List<Blog> blogList = from().getResultList(); return (List<Blog>)this.pm.detachCopyAll(blogList); // シリアライズできるようにdetachする }
IndexController.class
List<Blog> blogList = new BlogDao().findAll(); requestScope("blogList", blogList);
ViewHelper.class
public static Object get(String attributeKey, ClassLoader clazzLoader) { Object o = RequestLocator.get().getAttribute(attributeKey); byte[] bytes = ByteUtil.toByteArray(o); return ByteUtil.toObject(bytes, clazzLoader); }
jsp
<%@ page import="static study.ViewHelper.*" %> <% List<Blog> blogList = (List<Blog>)get("blogList", getClass().getClassLoader()); Blog blog = blogList.get(0); // 単純にrequest.getAttributeするとエラーが出る場所 %>
HotReloadingClassLoaderとJasperLoader
HotReloadingなクラスはHotReloadingClassLoaderで動いているようです。当該の例ではモデルのBlogがHotReloadingなクラスです。jspのスクリプトレットではJasperLoaderで動いているのでクラスローダーが異なりClassCastExceptionが出ていました。解決するためにいったんシリアライズ(ByteUtil.toByteArray(o))してデシリアライズ(ByteUtil.toObject(bytes, clazzLoader))しています。
まとめ
簡単に解決してラッキー。
ByteUtilって便利なクラスを見つけたよ。
ViewHelperのgetメソッドの引数にClassLoaderが必要なのがいまいちなのだがどうしたものか。。RequestLocatorみたいにうまくやる方法ありますか?