Uploaded image for project: 'Tapestry'
  1. Tapestry
  2. TAPESTRY-2184

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

    Details

    • Type: Bug
    • Status: Closed
    • Priority: 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
        hrgdavor 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
        hrgdavor 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 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 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
        hlship 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
        hlship 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
        hlship 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
        hlship 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
        ongakugainochi 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
        ongakugainochi 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:
            hlship Howard M. Lewis Ship
            Reporter:
            angelochen960 Angelo Chen
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development