Liferay用ポートレットの開発チップ

  • portlet.xml の portlet-class タグ内にスペースを入れない

たとえば、

<portlet-class>org.apache.portals.bridges.portletfilter.FilterPortlet</portlet-class>

と言う感じで、無駄なスペースを入れない。スペースがあると、それもクラス名の一部として処理される。

(補足:どうやら、portlet-classタグ以外のところも文字列として扱いたいところにスペースが前後とかにあると、それも文字列の一部として処理されるので、余計なものは入れない方が良いと思われる)

Liferayを試す

まず、LiferayにVFSポートレットを配備して、動作確認を試みる。でも、動かない・・・。ログを見てみると、ガツガツエラーをはいている。そもそも、bin ディレクトリで実行しなければならなかったり、なんだか怪しい。VFSポートレットもportlet.xmlの解釈の仕方が違うらしく、そこいらのスペースとかもそのまま認識しているようにも思える。というわけで、苦戦中・・・。でも、おもしろそうなポートレットは入っているな。PAL Portal にももってこれないだろうか・・・。

コンストラクタ

javassist を使って、MyFaces ブリッジを作っていたのだが、RenderResponse の実装にデフォルトのコンストラクタみたいなのがない場合に、自動処理が難しいと感じ始める・・・。次のような場合、

public class App
{
public static void main(String[] args)
{
Test3 a = new Test3();
}
}
class Test1
{
public Test1()
{
System.out.println("Test1のコンストラクタです。");
}
}
class Test2 extends Test1
{
public Test2()
{
System.out.println("Test2のコンストラクタです。");
}
}
class Test3 extends Test2
{
public Test3()
{
System.out.println("Test3のコンストラクタです。");
}
}

実行すると

Test1のコンストラクタです。
Test2のコンストラクタです。
Test3のコンストラクタです。

となるわけだが、もし、Test2クラスでTest2()がTest2(int a)とかに変わった場合、Test3のコンストラクタでコンパイルエラーになる。そのため、Test3のコンストラクタでは、次のように、明示的にsuper(1)とかTest3()でやらねばならない。

public class App
{
public static void main(String[] args)
{
Test3 a = new Test3();
}
}
class Test1
{
public Test1()
{
System.out.println("Test1のコンストラクタです。");
}
}
class Test2 extends Test1
{
public Test2(int a)
{
System.out.println("Test2のコンストラクタです。");
}
}
class Test3 extends Test2
{
public Test3()
{
super(1);
System.out.println("Test3のコンストラクタです。");
}
}

つまり、やりたかったことは、RenderResponse(ここではTest2クラスを想定)を動的にラップするクラス(つまりTest3クラス)を作りたかったのだが、Test2 にデフォルトのコンストラクタがない場合は、super(..)を呼び出せねばならない。適当な引数を渡して、とりあえず、インスタンス化すればいいかとも思うが、PlutoやJ2の場合、ServletResponseWrapperなどが親にいるから、適当なresponseをコンストラクタに渡すとExceptionをくらってしまう。

うむむ、何か他に方法があるのだろうか。javassistの知識も深まったけど、結局、この方法でも解決できなそうな気がしてきた・・・。