You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by "Joonas Koivunen (JIRA)" <ji...@apache.org> on 2011/03/28 18:10:06 UTC
[jira] [Created] (WICKET-3564) AjaxRequestTarget#addComponent(..)
should guard against improper usage
AjaxRequestTarget#addComponent(..) should guard against improper usage
----------------------------------------------------------------------
Key: WICKET-3564
URL: https://issues.apache.org/jira/browse/WICKET-3564
Project: Wicket
Issue Type: Improvement
Components: wicket-core
Affects Versions: 1.4.17
Reporter: Joonas Koivunen
It's possible to call ART#addComponent(...) from (for example) Component#onComponentTag(..) which will later throw ConcurrentModificationException from line 675 (getting next from iterator).
Guarding the addComponent(Component, String) and the other add* and register* methods would seem better in the terms of fail-fast behaviour and save someone else a bit of debugging time.
Patching this is rather trivial at least for Components; for javascripts I'm not sure if correctly blocking adding prependJs just before rendering it could break someones (already broken, unrendered) javascript?
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
[jira] [Commented] (WICKET-3564) AjaxRequestTarget#addComponent(..)
should guard against improper usage
Posted by "Igor Vaynberg (JIRA)" <ji...@apache.org>.
[ https://issues.apache.org/jira/browse/WICKET-3564?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13052604#comment-13052604 ]
Igor Vaynberg commented on WICKET-3564:
---------------------------------------
Joonas, that would be great.
> AjaxRequestTarget#addComponent(..) should guard against improper usage
> ----------------------------------------------------------------------
>
> Key: WICKET-3564
> URL: https://issues.apache.org/jira/browse/WICKET-3564
> Project: Wicket
> Issue Type: Improvement
> Components: wicket-core
> Affects Versions: 1.4.17
> Reporter: Joonas Koivunen
> Assignee: Juergen Donnerstag
> Fix For: 1.5-RC5
>
> Attachments: 3564-list_comp_resp.diff
>
>
> It's possible to call ART#addComponent(...) from (for example) Component#onComponentTag(..) which will later throw ConcurrentModificationException from line 675 (getting next from iterator).
> Guarding the addComponent(Component, String) and the other add* and register* methods would seem better in the terms of fail-fast behaviour and save someone else a bit of debugging time.
> Patching this is rather trivial at least for Components; for javascripts I'm not sure if correctly blocking adding prependJs just before rendering it could break someones (already broken, unrendered) javascript?
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
[jira] [Resolved] (WICKET-3564) AjaxRequestTarget#addComponent(..)
should guard against improper usage
Posted by "Juergen Donnerstag (JIRA)" <ji...@apache.org>.
[ https://issues.apache.org/jira/browse/WICKET-3564?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Juergen Donnerstag resolved WICKET-3564.
----------------------------------------
Resolution: Fixed
Fix Version/s: (was: 1.5-RC5)
1.5-RC6
patch applied
> AjaxRequestTarget#addComponent(..) should guard against improper usage
> ----------------------------------------------------------------------
>
> Key: WICKET-3564
> URL: https://issues.apache.org/jira/browse/WICKET-3564
> Project: Wicket
> Issue Type: Improvement
> Components: wicket-core
> Affects Versions: 1.4.17
> Reporter: Joonas Koivunen
> Assignee: Juergen Donnerstag
> Fix For: 1.5-RC6
>
> Attachments: 3564-list_comp_resp.diff, fix-3564-2.diff, wi-3564-quickstart.tar.gz
>
>
> It's possible to call ART#addComponent(...) from (for example) Component#onComponentTag(..) which will later throw ConcurrentModificationException from line 675 (getting next from iterator).
> Guarding the addComponent(Component, String) and the other add* and register* methods would seem better in the terms of fail-fast behaviour and save someone else a bit of debugging time.
> Patching this is rather trivial at least for Components; for javascripts I'm not sure if correctly blocking adding prependJs just before rendering it could break someones (already broken, unrendered) javascript?
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
[jira] [Commented] (WICKET-3564) AjaxRequestTarget#addComponent(..)
should guard against improper usage
Posted by "Martijn Dashorst (JIRA)" <ji...@apache.org>.
[ https://issues.apache.org/jira/browse/WICKET-3564?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13052545#comment-13052545 ]
Martijn Dashorst commented on WICKET-3564:
------------------------------------------
The newly introduced state/assertions try to prevent
ConcurrentModificationExceptions when adding listeners to the target
while the listeners are being processed. While this is a laudable
goal, it fails when something that just works without causing
ConcurrentModificationExceptions now suddenly is forbidden.
That said, WiQuery does the following to ensure that a component does
the JQuery initialization dance. The javascript js is something like
"$('id').activatePlugin();"
AjaxRequestTarget ajaxRequestTarget = (AjaxRequestTarget) requestHandler;
ajaxRequestTarget.addListener(new IListener() {
public void onAfterRespond(Map<String, Component> map,
IJavaScriptResponse response) {
response.addJavaScript(js);
}
public void onBeforeRespond(Map<String, Component> map,
AjaxRequestTarget target) {
// Do nothing
}
});
This is (ultimately) called from AjaxRequestTarget#renderHead().
Now I am quite positive that this is a bit of over-engineering/left
overs from 1.4 days on WiQuery's part, according to me the following
should also work:
AjaxRequestTarget ajaxRequestTarget = (AjaxRequestTarget) requestHandler;
requestHandler.getHeaderResponse().renderOnDomReadyJavaScript(js);
Given that WiQuery probably does something stupid (the simplified code
suggests such), I do think that the current implementation of
restricting additions to the listeners is too strict.
There are a couple of things we can change:
1. relax the assertions such that they only cover the cases where
things actually go wrong, or
2. use CopyOnWriteArraySet instead of HashSet to make iteration safe
even when things get added to the set, or
3. ...?
Number 2 sounds like a good idea, but might introduce errors where
someone is adding a listener which doesn't get processed since the
iterator works on a previous copy—hard to debug, but quite easy to
track (keep a previous size and compare/assert after the loop). It
also consumes more memory during request processing.
I agree with the issue that a ConcurrentModificationException is less
descriptive than asserting that things are set in stone. So I'd like
to opt for number 1 and relax the assertions to just those spots where
things go wrong, *and* properly document it instead of relying on
runtime exceptions that may/may not occur.
> AjaxRequestTarget#addComponent(..) should guard against improper usage
> ----------------------------------------------------------------------
>
> Key: WICKET-3564
> URL: https://issues.apache.org/jira/browse/WICKET-3564
> Project: Wicket
> Issue Type: Improvement
> Components: wicket-core
> Affects Versions: 1.4.17
> Reporter: Joonas Koivunen
> Assignee: Juergen Donnerstag
> Fix For: 1.5-RC5
>
> Attachments: 3564-list_comp_resp.diff
>
>
> It's possible to call ART#addComponent(...) from (for example) Component#onComponentTag(..) which will later throw ConcurrentModificationException from line 675 (getting next from iterator).
> Guarding the addComponent(Component, String) and the other add* and register* methods would seem better in the terms of fail-fast behaviour and save someone else a bit of debugging time.
> Patching this is rather trivial at least for Components; for javascripts I'm not sure if correctly blocking adding prependJs just before rendering it could break someones (already broken, unrendered) javascript?
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
[jira] [Resolved] (WICKET-3564) AjaxRequestTarget#addComponent(..)
should guard against improper usage
Posted by "Juergen Donnerstag (JIRA)" <ji...@apache.org>.
[ https://issues.apache.org/jira/browse/WICKET-3564?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Juergen Donnerstag resolved WICKET-3564.
----------------------------------------
Resolution: Fixed
Fix Version/s: 1.5-RC5
Assignee: Juergen Donnerstag
> AjaxRequestTarget#addComponent(..) should guard against improper usage
> ----------------------------------------------------------------------
>
> Key: WICKET-3564
> URL: https://issues.apache.org/jira/browse/WICKET-3564
> Project: Wicket
> Issue Type: Improvement
> Components: wicket-core
> Affects Versions: 1.4.17
> Reporter: Joonas Koivunen
> Assignee: Juergen Donnerstag
> Fix For: 1.5-RC5
>
> Attachments: 3564-list_comp_resp.diff
>
>
> It's possible to call ART#addComponent(...) from (for example) Component#onComponentTag(..) which will later throw ConcurrentModificationException from line 675 (getting next from iterator).
> Guarding the addComponent(Component, String) and the other add* and register* methods would seem better in the terms of fail-fast behaviour and save someone else a bit of debugging time.
> Patching this is rather trivial at least for Components; for javascripts I'm not sure if correctly blocking adding prependJs just before rendering it could break someones (already broken, unrendered) javascript?
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
[jira] [Commented] (WICKET-3564) AjaxRequestTarget#addComponent(..)
should guard against improper usage
Posted by "Joonas Koivunen (JIRA)" <ji...@apache.org>.
[ https://issues.apache.org/jira/browse/WICKET-3564?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13052584#comment-13052584 ]
Joonas Koivunen commented on WICKET-3564:
-----------------------------------------
I think that (1) can be achieved through what I described above, in the end of my comment. I made the patch too strict due to *my* misunderstanding of IListener contract.
@Juergen: I'll write a better patch w/ comments later today?
> AjaxRequestTarget#addComponent(..) should guard against improper usage
> ----------------------------------------------------------------------
>
> Key: WICKET-3564
> URL: https://issues.apache.org/jira/browse/WICKET-3564
> Project: Wicket
> Issue Type: Improvement
> Components: wicket-core
> Affects Versions: 1.4.17
> Reporter: Joonas Koivunen
> Assignee: Juergen Donnerstag
> Fix For: 1.5-RC5
>
> Attachments: 3564-list_comp_resp.diff
>
>
> It's possible to call ART#addComponent(...) from (for example) Component#onComponentTag(..) which will later throw ConcurrentModificationException from line 675 (getting next from iterator).
> Guarding the addComponent(Component, String) and the other add* and register* methods would seem better in the terms of fail-fast behaviour and save someone else a bit of debugging time.
> Patching this is rather trivial at least for Components; for javascripts I'm not sure if correctly blocking adding prependJs just before rendering it could break someones (already broken, unrendered) javascript?
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
[jira] [Reopened] (WICKET-3564) AjaxRequestTarget#addComponent(..)
should guard against improper usage
Posted by "Martijn Dashorst (JIRA)" <ji...@apache.org>.
[ https://issues.apache.org/jira/browse/WICKET-3564?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Martijn Dashorst reopened WICKET-3564:
--------------------------------------
This breaks WiQuery which adds listeners during renderHead. This worked perfectly without throwing ConcurrentModificationExceptions.
21-06-11 12:11:09,928 [qtp1774197673-55] INFO nl.topicus.cobra.app.requestcycle.ExceptionHandlingRequestCycleListener.onException(ExceptionHandlingRequestCycleListener.java:40) : Exception in page null
java.lang.IllegalStateException: IListeners can no longer be added
at org.apache.wicket.ajax.AjaxRequestTarget.assertNotFrozen(AjaxRequestTarget.java:299)
at org.apache.wicket.ajax.AjaxRequestTarget.assertListenersNotFrozen(AjaxRequestTarget.java:306)
at org.apache.wicket.ajax.AjaxRequestTarget.addListener(AjaxRequestTarget.java:333)
at org.odlabs.wiquery.core.javascript.JsQuery.addAjaxJavascript(JsQuery.java:226)
at org.odlabs.wiquery.core.javascript.JsQuery.renderHead(JsQuery.java:215)
at org.odlabs.wiquery.core.commons.WiQueryCoreHeaderContributor.renderPlugin(WiQueryCoreHeaderContributor.java:236)
at org.odlabs.wiquery.core.commons.WiQueryCoreHeaderContributor.renderAjaxResponse(WiQueryCoreHeaderContributor.java:212)
at org.odlabs.wiquery.core.commons.WiQueryCoreHeaderContributor.renderHead(WiQueryCoreHeaderContributor.java:129)
at org.apache.wicket.Component.renderHead(Component.java:2735)
at org.apache.wicket.ajax.AjaxRequestTarget.respondHeaderContribution(AjaxRequestTarget.java:1243)
at org.apache.wicket.ajax.AjaxRequestTarget.respondComponent(AjaxRequestTarget.java:953)
at org.apache.wicket.ajax.AjaxRequestTarget.respondComponents(AjaxRequestTarget.java:787)
at org.apache.wicket.ajax.AjaxRequestTarget.constructResponseBody(AjaxRequestTarget.java:677)
at org.apache.wicket.ajax.AjaxRequestTarget.respond(AjaxRequestTarget.java:629)
at org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor.respond(RequestCycle.java:717)
at org.apache.wicket.request.RequestHandlerStack.execute(RequestHandlerStack.java:63)
at org.apache.wicket.request.RequestHandlerStack.execute(RequestHandlerStack.java:96)
at org.apache.wicket.request.cycle.RequestCycle.processRequest(RequestCycle.java:212)
at org.apache.wicket.request.cycle.RequestCycle.processRequestAndDetach(RequestCycle.java:253)
at org.apache.wicket.protocol.http.WicketFilter.processRequest(WicketFilter.java:160)
at org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:216)
> AjaxRequestTarget#addComponent(..) should guard against improper usage
> ----------------------------------------------------------------------
>
> Key: WICKET-3564
> URL: https://issues.apache.org/jira/browse/WICKET-3564
> Project: Wicket
> Issue Type: Improvement
> Components: wicket-core
> Affects Versions: 1.4.17
> Reporter: Joonas Koivunen
> Assignee: Juergen Donnerstag
> Fix For: 1.5-RC5
>
> Attachments: 3564-list_comp_resp.diff
>
>
> It's possible to call ART#addComponent(...) from (for example) Component#onComponentTag(..) which will later throw ConcurrentModificationException from line 675 (getting next from iterator).
> Guarding the addComponent(Component, String) and the other add* and register* methods would seem better in the terms of fail-fast behaviour and save someone else a bit of debugging time.
> Patching this is rather trivial at least for Components; for javascripts I'm not sure if correctly blocking adding prependJs just before rendering it could break someones (already broken, unrendered) javascript?
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
[jira] [Updated] (WICKET-3564) AjaxRequestTarget#addComponent(..)
should guard against improper usage
Posted by "Joonas Koivunen (JIRA)" <ji...@apache.org>.
[ https://issues.apache.org/jira/browse/WICKET-3564?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Joonas Koivunen updated WICKET-3564:
------------------------------------
Attachment: 3564-list_comp_resp.diff
Diff for freezing components, listeners and responders as late as possible. Untested.
> AjaxRequestTarget#addComponent(..) should guard against improper usage
> ----------------------------------------------------------------------
>
> Key: WICKET-3564
> URL: https://issues.apache.org/jira/browse/WICKET-3564
> Project: Wicket
> Issue Type: Improvement
> Components: wicket-core
> Affects Versions: 1.4.17
> Reporter: Joonas Koivunen
> Attachments: 3564-list_comp_resp.diff
>
>
> It's possible to call ART#addComponent(...) from (for example) Component#onComponentTag(..) which will later throw ConcurrentModificationException from line 675 (getting next from iterator).
> Guarding the addComponent(Component, String) and the other add* and register* methods would seem better in the terms of fail-fast behaviour and save someone else a bit of debugging time.
> Patching this is rather trivial at least for Components; for javascripts I'm not sure if correctly blocking adding prependJs just before rendering it could break someones (already broken, unrendered) javascript?
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
[jira] [Updated] (WICKET-3564) AjaxRequestTarget#addComponent(..)
should guard against improper usage
Posted by "Joonas Koivunen (JIRA)" <ji...@apache.org>.
[ https://issues.apache.org/jira/browse/WICKET-3564?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Joonas Koivunen updated WICKET-3564:
------------------------------------
Attachment: fix-3564-2.diff
Note that this is incremental, on latest HEAD revision.
I also discovered a huge bug related to ITargetRespondListener freezing.. Perhaps the methods fireOn(Before|After)RespondListener could be named without the "Respond"? :)
I've now tested all the good and bad cases that I can think of, and none of the pre-existing tests started failing on "mvn test".
> AjaxRequestTarget#addComponent(..) should guard against improper usage
> ----------------------------------------------------------------------
>
> Key: WICKET-3564
> URL: https://issues.apache.org/jira/browse/WICKET-3564
> Project: Wicket
> Issue Type: Improvement
> Components: wicket-core
> Affects Versions: 1.4.17
> Reporter: Joonas Koivunen
> Assignee: Juergen Donnerstag
> Fix For: 1.5-RC5
>
> Attachments: 3564-list_comp_resp.diff, fix-3564-2.diff, wi-3564-quickstart.tar.gz
>
>
> It's possible to call ART#addComponent(...) from (for example) Component#onComponentTag(..) which will later throw ConcurrentModificationException from line 675 (getting next from iterator).
> Guarding the addComponent(Component, String) and the other add* and register* methods would seem better in the terms of fail-fast behaviour and save someone else a bit of debugging time.
> Patching this is rather trivial at least for Components; for javascripts I'm not sure if correctly blocking adding prependJs just before rendering it could break someones (already broken, unrendered) javascript?
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
[jira] [Updated] (WICKET-3564) AjaxRequestTarget#addComponent(..)
should guard against improper usage
Posted by "Joonas Koivunen (JIRA)" <ji...@apache.org>.
[ https://issues.apache.org/jira/browse/WICKET-3564?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Joonas Koivunen updated WICKET-3564:
------------------------------------
Attachment: wi-3564-quickstart.tar.gz
Quickstart of all the things I think we should try to avoid. Not sure how I could turn this into a junit test though..
> AjaxRequestTarget#addComponent(..) should guard against improper usage
> ----------------------------------------------------------------------
>
> Key: WICKET-3564
> URL: https://issues.apache.org/jira/browse/WICKET-3564
> Project: Wicket
> Issue Type: Improvement
> Components: wicket-core
> Affects Versions: 1.4.17
> Reporter: Joonas Koivunen
> Assignee: Juergen Donnerstag
> Fix For: 1.5-RC5
>
> Attachments: 3564-list_comp_resp.diff, wi-3564-quickstart.tar.gz
>
>
> It's possible to call ART#addComponent(...) from (for example) Component#onComponentTag(..) which will later throw ConcurrentModificationException from line 675 (getting next from iterator).
> Guarding the addComponent(Component, String) and the other add* and register* methods would seem better in the terms of fail-fast behaviour and save someone else a bit of debugging time.
> Patching this is rather trivial at least for Components; for javascripts I'm not sure if correctly blocking adding prependJs just before rendering it could break someones (already broken, unrendered) javascript?
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
[jira] [Commented] (WICKET-3564) AjaxRequestTarget#addComponent(..)
should guard against improper usage
Posted by "Joonas Koivunen (JIRA)" <ji...@apache.org>.
[ https://issues.apache.org/jira/browse/WICKET-3564?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13052475#comment-13052475 ]
Joonas Koivunen commented on WICKET-3564:
-----------------------------------------
I didn't test it out with WiQuery, but cannot immediatedly see from where could the IListener of their's be called after that point? Their listener seems to be doing this:
{code}
public void onAfterRespond(Map<String, Component> map, IJavascriptResponse response) {
response.addJavascript(js);
}
{code}
Where js is String.. I have misunderstood the IListener interface's onAfterRespond(...) documentation; I thought it was merely a read-only view as I only read the NOTE part, and understood it too broadly.
Fix would seem to be unfreezing after the for-loop on line 608...611, allowing the components to provide more IListeners up until line 678 where {{fireOnAfterRespondListeners}} is called.
> AjaxRequestTarget#addComponent(..) should guard against improper usage
> ----------------------------------------------------------------------
>
> Key: WICKET-3564
> URL: https://issues.apache.org/jira/browse/WICKET-3564
> Project: Wicket
> Issue Type: Improvement
> Components: wicket-core
> Affects Versions: 1.4.17
> Reporter: Joonas Koivunen
> Assignee: Juergen Donnerstag
> Fix For: 1.5-RC5
>
> Attachments: 3564-list_comp_resp.diff
>
>
> It's possible to call ART#addComponent(...) from (for example) Component#onComponentTag(..) which will later throw ConcurrentModificationException from line 675 (getting next from iterator).
> Guarding the addComponent(Component, String) and the other add* and register* methods would seem better in the terms of fail-fast behaviour and save someone else a bit of debugging time.
> Patching this is rather trivial at least for Components; for javascripts I'm not sure if correctly blocking adding prependJs just before rendering it could break someones (already broken, unrendered) javascript?
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
[jira] [Commented] (WICKET-3564) AjaxRequestTarget#addComponent(..)
should guard against improper usage
Posted by "Juergen Donnerstag (JIRA)" <ji...@apache.org>.
[ https://issues.apache.org/jira/browse/WICKET-3564?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13052467#comment-13052467 ]
Juergen Donnerstag commented on WICKET-3564:
--------------------------------------------
Hi Martjin,
could you please build a quickstart or even better a test case and attach it. It'd avoid we break important functionality in the future again. Thanks a lot.
-Juergen
> AjaxRequestTarget#addComponent(..) should guard against improper usage
> ----------------------------------------------------------------------
>
> Key: WICKET-3564
> URL: https://issues.apache.org/jira/browse/WICKET-3564
> Project: Wicket
> Issue Type: Improvement
> Components: wicket-core
> Affects Versions: 1.4.17
> Reporter: Joonas Koivunen
> Assignee: Juergen Donnerstag
> Fix For: 1.5-RC5
>
> Attachments: 3564-list_comp_resp.diff
>
>
> It's possible to call ART#addComponent(...) from (for example) Component#onComponentTag(..) which will later throw ConcurrentModificationException from line 675 (getting next from iterator).
> Guarding the addComponent(Component, String) and the other add* and register* methods would seem better in the terms of fail-fast behaviour and save someone else a bit of debugging time.
> Patching this is rather trivial at least for Components; for javascripts I'm not sure if correctly blocking adding prependJs just before rendering it could break someones (already broken, unrendered) javascript?
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira