3

簡単に言うと、componentTypeが指定された複合コンポーネントがあるということです。ページ上で複合コンポーネントを単独で使用すると、正常に機能します。別の複合コンポーネント内(これもui:repeat内)にネストすると、UINamingContainer内のcomponentTypeクラスで定義したプロパティを見つけようとして例外が発生します。これは間違ったクラスです。cc.whateverに置き換えることでその問題を解決できることがわかりましcomponent.parent.parent.parent.whateverたが、少しひどいハックだと思います。私はJSFを混乱させるような愚かなことをしていると思いますが、それが何であるか、または私が別の方法で何をすべきかわかりません。

さて、非常に詳細に、私は次の複合コンポーネントを持っています:

<?xml version='1.0' encoding='UTF-8' ?>
<ui:component xmlns:ui="http://java.sun.com/jsf/facelets"
              xmlns:cc="http://java.sun.com/jsf/composite"
              xmlns:ice="http://www.icesoft.com/icefaces/component"
              xmlns:f="http://java.sun.com/jsf/core">
  <cc:interface componentType="edu.nrao.sss.tools.resrccat.ui.support.LinearVelocityUIComponent">
    <cc:attribute name             = "value"
                  class            = "edu.nrao.sss.measure.LinearVelocity"
                  required         = "true"
                  shortDescription = "The LinearVelocity value to show or edit."/>

    <cc:attribute name             = "separate-units"
                  type             = "boolean"
                  default          = "true"
                  shortDescription = "If true, provide a drop-box to edit the units separately from the value."/>
  </cc:interface>
  <cc:implementation>
    <ice:inputText id="velocity" value="#{cc.attrs.value}" rendered="#{not cc.attrs['separate-units']}"/>

    <ui:fragment rendered="#{cc.attrs['separate-units']}">
      <ice:inputText id="velocityDecimal" value="#{cc.velocityDecimal}"/>
      <ice:selectOneMenu id="velocityUnits" value="#{cc.velocityUnits}">
        <f:selectItems value="#{siFactory.linearVelocityUnits}"/>
      </ice:selectOneMenu>
    </ui:fragment>
  </cc:implementation>
</ui:component>

バッキングコンポーネントは次のとおりです。

@FacesComponent("edu.nrao.sss.tools.resrccat.ui.support.LinearVelocityUIComponent")
public class LinearVelocityUIComponent extends UIInput implements NamingContainer {

  @Override public String getFamily() {
    return UINamingContainer.COMPONENT_FAMILY;
  }

  public LinearVelocity getVelocity() {
    return (LinearVelocity) getValueExpression("value").getValue(FacesContext.getCurrentInstance().getELContext());
  }

  public void setVelocity(LinearVelocity newVelocity) {
    getValueExpression("value").setValue(FacesContext.getCurrentInstance().getELContext(), newVelocity);
  }

  public BigDecimal getVelocityDecimal() {
    return getVelocity().getValue();
  }

  public LinearVelocityUnits getVelocityUnits() {
    return getVelocity().getUnits();
  }

  public void setVelocityDecimal(BigDecimal newVelocity) {
    setVelocity(new LinearVelocity(newVelocity, getVelocityUnits()));
  }

  public void setVelocityUnits(LinearVelocityUnits units) {
    setVelocity(new LinearVelocity(getVelocityDecimal(), units));
  }
}

このコンポーネントをページで単独で使用すると、すべて問題ありません。

<p>Your linear velocity is <rct:linear-velocity value="#{test.velocity}"/></p>

次のような別の複合コンポーネント内にネストすると、次のようになります。

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:component xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ice="http://www.icesoft.com/icefaces/component"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:cc="http://java.sun.com/jsf/composite"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:rct="http://java.sun.com/jsf/composite/components/rct">
  <cc:interface>
    <cc:attribute name="specs"        required="true"/>
    <cc:attribute name="type"         default="line"/>
  </cc:interface>
  <cc:implementation>
    <table class="iceDatTbl">
      <thead>
        <tr>
          ...
          <th class="iceDatTblColHdr2">Minimum<br/>Span</th> 
          ...
        </tr>
      </thead>
      <tbody>
        <ui:repeat var="spec" value="#{cc.attrs.specs}" varStatus="stat">
          <tr class="#{stat.even ? 'iceDatTblRow1' : 'iceDatTblRow2'}">
            ...
            <td class="iceDatTblCol2">
              Req: <rct:linear-velocity value="#{spec.minimumSpan}"/><br/>
              Sug: #{spec.suggestedMinimumSpan}
            </td>
            ...
          </tr>
        </ui:repeat>
      </tbody>
    </table>
  </cc:implementation>
</ui:component>

この例外が発生します:

Nov 19, 2012 4:10:37 PM org.icefaces.impl.application.ExtendedExceptionHandler handle
WARNING: queued exception
javax.el.PropertyNotFoundException: /resources/components/rct/linear-velocity.xhtml @20,113 value="#{cc.velocityDecimal}": Property 'velocityDecimal' not found on type javax.faces.component.UINamingContainer
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:111)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
    at javax.faces.component.UIOutput.getValue(UIOutput.java:169)
    at com.sun.faces.facelets.component.UIRepeat$SavedState.populate(UIRepeat.java:823)
    at com.sun.faces.facelets.component.UIRepeat.saveChildState(UIRepeat.java:369)
    at com.sun.faces.facelets.component.UIRepeat.saveChildState(UIRepeat.java:375)
    at com.sun.faces.facelets.component.UIRepeat.saveChildState(UIRepeat.java:375)
    at com.sun.faces.facelets.component.UIRepeat.saveChildState(UIRepeat.java:355)
    at com.sun.faces.facelets.component.UIRepeat.setIndex(UIRepeat.java:440)
    at com.sun.faces.facelets.component.UIRepeat.visitTree(UIRepeat.java:613)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
    at javax.faces.component.UINamingContainer.visitTree(UINamingContainer.java:163)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
    at org.icefaces.impl.component.UISeriesBase.visitRows(UISeriesBase.java:1174)
    at org.icefaces.impl.component.UISeriesBase.visitTree(UISeriesBase.java:1065)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
    at javax.faces.component.UIForm.visitTree(UIForm.java:344)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
    at org.icefaces.impl.event.RestoreResourceDependencies.processEvent(RestoreResourceDependencies.java:24)
    at javax.faces.event.SystemEvent.processListener(SystemEvent.java:106)
    at com.sun.faces.application.ApplicationImpl.processListeners(ApplicationImpl.java:2168)
    at com.sun.faces.application.ApplicationImpl.invokeListenersFor(ApplicationImpl.java:2144)
    at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:302)
    at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:246)
    at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:812)
    at javax.faces.component.UIViewRoot.encodeBegin(UIViewRoot.java:962)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1755)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:402)
    at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
    at com.ocpsoft.pretty.faces.application.PrettyViewHandler.renderView(PrettyViewHandler.java:163)
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:145)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:487)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:412)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339)
    at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:137)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at edu.nrao.sss.webapp.LookupUserFilter.doFilter(LookupUserFilter.java:57)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.jasig.cas.client.util.HttpServletRequestWrapperFilter.doFilter(HttpServletRequestWrapperFilter.java:50)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.jasig.cas.client.validation.AbstractTicketValidationFilter.doFilter(AbstractTicketValidationFilter.java:167)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.jasig.cas.client.authentication.AuthenticationFilter.doFilter(AuthenticationFilter.java:111)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)

それが機能することを可能にする私ができる交換はこれです:

<ui:fragment rendered="#{cc.attrs['separate-units']}">
  <ice:inputText id="velocityDecimal" value="#{component.parent.parent.parent.velocityDecimal}"/>
  <ice:selectOneMenu id="velocityUnits" value="#{component.parent.parent.parent.velocityUnits}">
    <f:selectItems value="#{siFactory.linearVelocityUnits}"/>
  </ice:selectOneMenu>
</ui:fragment>

これは本当に間違っていると感じ、歴史的には、数か月後にJSFをこのようなハッキングで機能させようとすると、私の人生が台無しになります。助けていただければ幸いです。私はJSFが大好きで、複合コンポーネントを使用して構造化することを本当に楽しんでいますが、複合コンポーネントをネストできる必要があります。

編集:Glassfishでは、コンポーネントが単独でまったくレンダリングされないことを発見しました。他のコンポーネントにネストされた同じエラー(UINamingContainerにはこのプロパティLinearVelocityUIComponentにはありません)が生成されます。

4

2 に答える 2

2

Tomcat7.0.30上のMojarra2.1.14での問題を再現することができました(そして<h:xxx>、これらのICEfacesコンポーネントと同等の標準のJSFを使用しました)。<ui:repeat>これは、Mojarraにネストされた状態保存メカニズムが壊れていることが原因です。「ネストされたui:repeat」に関するMojarraのバグレポートのどれがあなたの特定の問題をカバーしているかは正直わかりません。レポートが多すぎて、あなたの特定のバグは私にとって新しいものです。

MyFaces 2.1.9では、まったく同じコードで問題なく動作します。少なくともアウター<ui:repeat><h:dataTable>またはに置き換えても問題なく動作し<p:dataList>ます。

したがって、この問題を解決するには2つのオプションがあります。

  1. (少なくとも外側の)<ui:repeat>完全に価値のあるUIData実装に置き換えてください。たとえば、<h:dataTable>または<p:dataList>または頭のてっぺんからはわからない同等のICEfacesに置き換えてください。これは必要なHTMLを生成しない可能性がありますが、それは機能し、CSSを使用すると多くのことができます。

  2. MojarraをMyFacesに置き換えます。Webアプリ全体を徹底的に(単体)テストすることを忘れないでください。MyFacesには、独自の癖やバグもあります。

于 2012-11-20T02:47:57.237 に答える
1

それが誰かを助けるなら、私は別の複合コンポーネント内に複合コンポーネント(cc)をネストした同様の問題を解決しました。1つのインスタンスは問題なく、ページ内の2つのインスタンスは問題があり、ネストされたccに属するクラスフィールドを見つけようとしましたが、ホストccでそれらを探していました。問題は、両方のccに同じ名前の変数を使用したことでした。そのため、EL式「cc.attrs.bean」はJSFが処理するのを混乱させていました...私は、CC間で異なるパラメーター名を保持することによってそれを解決しました。これを見つけるのに少し時間がかかりました。

于 2019-05-16T14:04:57.900 に答える