読者です 読者をやめる 読者になる 読者になる

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みたいにうまくやる方法ありますか?