7

JSF (MyFaces 1.2) アプリケーションで汎用メニューを使用したいと考えています。

<h:form>
  <h:dataTable id="dt1" value="#{portal.actionList}" var="item">
    <f:facet name="header">
        <h:outputText value="Menu" />
    </f:facet>
    <h:column>
        <h:commandLink action="#{item.action}">
            <h:outputText value="clickme"/>
        </h:commandLink>
     </h:column>
   </h:dataTable>
 </h:form>

次に、セッション スコープのポータルは次のようになります。

 class Portal {
    private ArrayList<IAction> list = new ArrayList<IAction>();

    public Portal() {
       list.add(new IAction() {
                public action() {
                    log.info("called action here");
                }
        });
    }
    public ArrayList<IAction> getActionList() {
        return list;
    }
 }

このコードを実行すると、正常に表示されます。ただし、「clickme」コマンド リンクをクリックしてアクションを実行しようとすると、次の例外が発生します。

  Class org.apache.el.parser.AstValue can not access a member of class Portal$1 with modifiers "public"

メソッド (この例ではITemplate.action()) を実行できる匿名クラスのリストを表示する方法はありますか?

編集:

(内部)クラスを使用すると機能します。たとえば、次のようにします。

    class Bla implements IAction {
         public void action() {
             log.info("yes, i am working");
         }

および Portal コンストラクターで

 public Portal() {
   list.add( new Bla() );
}

しかし、これは私が望んでいる方法ではありません...

4

2 に答える 2

11

これは、匿名クラスを含むパッケージの外部から匿名クラスにアクセスできないためです。

これが舞台裏で起こっていることのデモンストレーションです:

public static void main(String[] args) throws Exception {
    Portal portal = new Portal();
    Object list = portal.getClass().getDeclaredMethod("getActionList", null).invoke(portal, null);
    Object action = list.getClass().getDeclaredMethod("get", new Class[] { int.class }).invoke(list, 0);
    action.getClass().getDeclaredMethod("action", null).invoke(action, null);
}

これをクラスと同じパッケージで実行してPortalから、パッケージ外の別のクラスでもう一度実行してみてください。他のパッケージでは、最後の行がまったく同じ例外をスローします。それは反射に基づいているので、ELが苦労している問題です。

public(内部)を作成する以外に、これをうまく解決する方法は他にありませんclass。Reflection(したがってELも)は他のパッケージからそれらにアクセスできます。

public class Portal {

    private List<IAction> list = new ArrayList<IAction>();

    public Portal() {
        list.add(new IActionImpl());
    }

    public class IActionImpl implements IAction {
        public void action() {
            System.out.println("called action here");
        }
    }

    public List<IAction> getActionList() {
        return list;
    }

}
于 2010-06-10T15:25:27.187 に答える
0

質問はかなり古いですが、今日同じ問題に遭遇しましたが、Jetty 7 から Tomcat 7 に切り替えたからです。

Jasper EL ライブラリを GlassFish EL ライブラリに置き換えることで問題を解決します。

于 2012-10-05T16:09:54.460 に答える