WinstoneでTopLink

JPAの手習い兼,Winstone/DerbyプラグインによるIDEAで完結した開発環境の検証なんてのをやってみたんだけど,意外なところでハマってしまった。一応,解決できたんで,経緯をメモっておく。


えーと,この構成をMacBookで試したときは,なんの問題もなく実施できたんだけど,Windowsでやったらダメだった。理由は,Winstoneのクラスローダに問題があるらしく,TopLinkがpersistence.xmlの読み込みに失敗してしまう(エラーコードはTOPLINK-30005)。
原因はハッキリしていて,persistence.xmlのURLのパス情報に"/"じゃなくて"\"が使われているからだった。で,どこでその設定をしているのか見つけるのが,少々面倒だったのだが,突き止めた先はこちら。

== WebAppConfiguration.java ==
  private ClassLoader buildWebAppClassLoader(Map startupArgs, ClassLoader parentClassLoader,
          String webRoot, List classPathFileList) {
    List urlList = new ArrayList();

    try {
        :
      // Classes folder
      File classesFolder = new File(webInfFolder, CLASSES);
      if (classesFolder.exists()) {
        Logger.log(Logger.DEBUG, Launcher.RESOURCES,
                   "WebAppConfig.WebAppClasses");
        urlList.add(new URL("file", "", classesFolder.getCanonicalPath() + "/"));
                                 ここ→ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        :

classesFolder.getCanonicalPath()なんてやってるから,おかしな事になるので,ここを以下のように書き換える。

urlList.add(new URL("file", "", classesFolder.getCanonicalPath() + "/"));
    ↓
urlList.add(classesFolder.toURL());

これで解決と思いきや。今度は,TopLinkがDerbyのJDBCドライバの読み込みに失敗する(TOPLINK-4002)。:-(


TopLinkもDerbyも同じくcommonLibFolderに入れてるんだけどなぁ。同じ親のクラスローダを共有しているはずだから,お互いを認識できると思うんだけど,なぜかダメみたい(なんでOSXで平気だったんだ?)。こっちは,しゃあないんで,DerbyをTopLinkより上のクラスローダに配置することで,急場をしのぐこととした。


ちょっと釈然としないところもあるが,まあいいや。
#ちなみに,Tomcatでは何もしなくてもすんなり動くよ。