Tapestry
  1. Tapestry
  2. TAPESTRY-2184

Null pointer exception when creating an action link during a component event request

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 5.0.10
    • Fix Version/s: 5.0.11
    • Component/s: tapestry-core
    • Labels:
      None

      Description

      createActionLink cause exception when it is called in the page class(see onActionFromDelete), but works when it is called from the template, this works in 5.0.6 and 7, but fails in 5.0.9 and 5.0.10, sample code and error follows:

      public class TestPage1 {
      @Inject
      private ComponentResources resources;
      private Object[] _objs;
      public Class onActivate(Object[] obj)

      { _objs = obj; return null; }

      public Object[] onPassivate()

      { return _objs;}

      Link onActionFromDelete(Long id)

      { String x = getTheLink(); // this fails with exception return null; }

      public String getTheLink()

      { Link l = resources.createActionLink("DeleteConfirm", false); return l.toURI(); }

      public Object onDeleteConfirm(Long id)

      { return null; }

      }

      template:

      <body>
      <t:ActionLink t:id="Delete" context="1">Delete me</t:ActionLink><br />
      <p>My Link is : $

      {theLink}

      </p>
      </body>

      errors:

      java.lang.NullPointerException
      Stack trace

      • org.apache.tapestry.internal.services.LinkFactoryImpl.collectActivationContextForPage(LinkFactoryImpl.java:217)
      • org.apache.tapestry.internal.services.LinkFactoryImpl.createActionLink(LinkFactoryImpl.java:129)
      • org.apache.tapestry.internal.structure.PageImpl.createActionLink(PageImpl.java:156)

        Activity

        Hide
        Davor Hrg added a comment -

        LinkFactoryImpl(line:127)

        Page activePage = _pageRenderQueue.getRenderingPage();

        this is null in this case ...
        I'm not sure if it is safe to assume:

        if(activePage == null) activePage = page;

        for this case this would be ok, but some other situation may misbehave ...

        Show
        Davor Hrg added a comment - LinkFactoryImpl(line:127) Page activePage = _pageRenderQueue.getRenderingPage(); this is null in this case ... I'm not sure if it is safe to assume: if(activePage == null) activePage = page; for this case this would be ok, but some other situation may misbehave ...
        Hide
        Ted Steen added a comment -

        @Davor Hrg, That was my solution also, but as you say, maybe it will misbehave in other situations.

        resources.createActionLink(...) seem to work between setupRender() and cleanupRender().

        Show
        Ted Steen added a comment - @Davor Hrg, That was my solution also, but as you say, maybe it will misbehave in other situations. resources.createActionLink(...) seem to work between setupRender() and cleanupRender().
        Hide
        Howard M. Lewis Ship added a comment -

        So far I can't get this to fail the way you list it, short of:

        Object[] onPassivate() { return new Object[]

        { null }

        ; }

        Which fails a bit differently:

        java.lang.IllegalArgumentException: Parameter value was null.
        at org.apache.tapestry.ioc.internal.util.Defense.notNull(Defense.java:37)
        at org.apache.tapestry.internal.services.ContextValueEncoderImpl.toClient(ContextValueEncoderImpl.java:33)
        at $ContextValueEncoder_118435737b3.toClient($ContextValueEncoder_118435737b3.java)
        at org.apache.tapestry.internal.services.LinkFactoryImpl.toContextStrings(LinkFactoryImpl.java:239)
        at org.apache.tapestry.internal.services.LinkFactoryImpl.collectActivationContextForPage(LinkFactoryImpl.java:229)
        at org.apache.tapestry.internal.services.LinkFactoryImpl.createActionLink(LinkFactoryImpl.java:134)
        at $LinkFactory_118435737b9.createActionLink($LinkFactory_118435737b9.java)
        at org.apache.tapestry.internal.structure.PageImpl.createActionLink(PageImpl.java:156)
        at org.apache.tapestry.internal.structure.InternalComponentResourcesImpl.createActionLink(InternalComponentResourcesImpl.java:123)
        at org.apache.tapestry.integration.app1.pages.ActionViaLinkDemo.getActionURL(ActionViaLinkDemo.java:34)
        at $PropertyConduit_11843573b25.get($PropertyConduit_11843573b25.java)
        at org.apache.tapestry.internal.bindings.PropBinding.get(PropBinding.java:54)

        Show
        Howard M. Lewis Ship added a comment - So far I can't get this to fail the way you list it, short of: Object[] onPassivate() { return new Object[] { null } ; } Which fails a bit differently: java.lang.IllegalArgumentException: Parameter value was null. at org.apache.tapestry.ioc.internal.util.Defense.notNull(Defense.java:37) at org.apache.tapestry.internal.services.ContextValueEncoderImpl.toClient(ContextValueEncoderImpl.java:33) at $ContextValueEncoder_118435737b3.toClient($ContextValueEncoder_118435737b3.java) at org.apache.tapestry.internal.services.LinkFactoryImpl.toContextStrings(LinkFactoryImpl.java:239) at org.apache.tapestry.internal.services.LinkFactoryImpl.collectActivationContextForPage(LinkFactoryImpl.java:229) at org.apache.tapestry.internal.services.LinkFactoryImpl.createActionLink(LinkFactoryImpl.java:134) at $LinkFactory_118435737b9.createActionLink($LinkFactory_118435737b9.java) at org.apache.tapestry.internal.structure.PageImpl.createActionLink(PageImpl.java:156) at org.apache.tapestry.internal.structure.InternalComponentResourcesImpl.createActionLink(InternalComponentResourcesImpl.java:123) at org.apache.tapestry.integration.app1.pages.ActionViaLinkDemo.getActionURL(ActionViaLinkDemo.java:34) at $PropertyConduit_11843573b25.get($PropertyConduit_11843573b25.java) at org.apache.tapestry.internal.bindings.PropBinding.get(PropBinding.java:54)
        Hide
        Howard M. Lewis Ship added a comment -

        Ok, this does fail:

        public class ActionViaLinkDemo
        {
        @Persist("flash")
        private String _message;

        @Inject
        private ComponentResources _resources;

        Object[]
        onPassivate()
        {
        return new Object[] { };
        }

        public String getMessage()

        { return _message; }

        void onUpdateMessage(String message)

        { getActionURL(); _message = message; }

        public String getActionURL()

        { Link link = _resources.createActionLink("UpdateMessage", false, "from getActionURL()"); return link.toURI(); }

        }

        Which fails inside onUpdateMessage() with:

        java.lang.NullPointerException
        at org.apache.tapestry.internal.services.LinkFactoryImpl.collectActivationContextForPage(LinkFactoryImpl.java:225)
        at org.apache.tapestry.internal.services.LinkFactoryImpl.createActionLink(LinkFactoryImpl.java:134)
        at $LinkFactory_118435737b9.createActionLink($LinkFactory_118435737b9.java)
        at org.apache.tapestry.internal.structure.PageImpl.createActionLink(PageImpl.java:156)
        at org.apache.tapestry.internal.structure.InternalComponentResourcesImpl.createActionLink(InternalComponentResourcesImpl.java:123)
        at org.apache.tapestry.integration.app1.pages.ActionViaLinkDemo.getActionURL(ActionViaLinkDemo.java:36)
        at org.apache.tapestry.integration.app1.pages.ActionViaLinkDemo.onUpdateMessage(ActionViaLinkDemo.java:29)
        at org.apache.tapestry.integration.app1.pages.ActionViaLinkDemo.dispatchComponentEvent(ActionViaLinkDemo.java)
        at org.apache.tapestry.internal.structure.ComponentPageElementImpl.dispatchEvent(ComponentPageElementImpl.java:843)
        at org.apache.tapestry.internal.structure.ComponentPageElementImpl.triggerContextEvent(ComponentPageElementImpl.java:1004)

        And here's the culprit:

        Page activePage = _pageRenderQueue.getRenderingPage();

        Which is broken when there is no rendering page.

        We'll just assume, for the moment, that the current page is the active page. There's probably some obscure edge case where that won't work, but I can't quite envision it right now.

        Show
        Howard M. Lewis Ship added a comment - Ok, this does fail: public class ActionViaLinkDemo { @Persist("flash") private String _message; @Inject private ComponentResources _resources; Object[] onPassivate() { return new Object[] { }; } public String getMessage() { return _message; } void onUpdateMessage(String message) { getActionURL(); _message = message; } public String getActionURL() { Link link = _resources.createActionLink("UpdateMessage", false, "from getActionURL()"); return link.toURI(); } } Which fails inside onUpdateMessage() with: java.lang.NullPointerException at org.apache.tapestry.internal.services.LinkFactoryImpl.collectActivationContextForPage(LinkFactoryImpl.java:225) at org.apache.tapestry.internal.services.LinkFactoryImpl.createActionLink(LinkFactoryImpl.java:134) at $LinkFactory_118435737b9.createActionLink($LinkFactory_118435737b9.java) at org.apache.tapestry.internal.structure.PageImpl.createActionLink(PageImpl.java:156) at org.apache.tapestry.internal.structure.InternalComponentResourcesImpl.createActionLink(InternalComponentResourcesImpl.java:123) at org.apache.tapestry.integration.app1.pages.ActionViaLinkDemo.getActionURL(ActionViaLinkDemo.java:36) at org.apache.tapestry.integration.app1.pages.ActionViaLinkDemo.onUpdateMessage(ActionViaLinkDemo.java:29) at org.apache.tapestry.integration.app1.pages.ActionViaLinkDemo.dispatchComponentEvent(ActionViaLinkDemo.java) at org.apache.tapestry.internal.structure.ComponentPageElementImpl.dispatchEvent(ComponentPageElementImpl.java:843) at org.apache.tapestry.internal.structure.ComponentPageElementImpl.triggerContextEvent(ComponentPageElementImpl.java:1004) And here's the culprit: Page activePage = _pageRenderQueue.getRenderingPage(); Which is broken when there is no rendering page. We'll just assume, for the moment, that the current page is the active page. There's probably some obscure edge case where that won't work, but I can't quite envision it right now.
        Hide
        Robert Zeigler added a comment -

        Not quite sure what you mean by "current page", but...
        suppose you have, say, a view block contribution, or edit block contribution, that creates an action link; it'll be in a page, say, ViewBlocks, but the rendering page might be, say, ListOrders. So then if the action handler in ViewBlocks is called, and it, in turn, calls createActionLink, would the "active" page be ViewBlocks, or ListOrders?
        It ought to be ListOrders, but...

        Show
        Robert Zeigler added a comment - Not quite sure what you mean by "current page", but... suppose you have, say, a view block contribution, or edit block contribution, that creates an action link; it'll be in a page, say, ViewBlocks, but the rendering page might be, say, ListOrders. So then if the action handler in ViewBlocks is called, and it, in turn, calls createActionLink, would the "active" page be ViewBlocks, or ListOrders? It ought to be ListOrders, but...

          People

          • Assignee:
            Howard M. Lewis Ship
            Reporter:
            Angelo Chen
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development