You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by "Igor Vaynberg (JIRA)" <ji...@apache.org> on 2007/09/12 07:46:32 UTC

[jira] Assigned: (WICKET-942) PageMap.remove(Page) throws ClassCastException

     [ https://issues.apache.org/jira/browse/WICKET-942?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Igor Vaynberg reassigned WICKET-942:
------------------------------------

    Assignee: Matej Knopp

> PageMap.remove(Page) throws ClassCastException
> ----------------------------------------------
>
>                 Key: WICKET-942
>                 URL: https://issues.apache.org/jira/browse/WICKET-942
>             Project: Wicket
>          Issue Type: Bug
>          Components: wicket
>    Affects Versions: 1.3.0-beta3
>            Reporter: John Ray
>            Assignee: Matej Knopp
>
> When I try to expire a page by calling PageMap.remove(Page) I get the following exception
> java.lang.ClassCastException: java.lang.Integer cannot be cast to org.apache.wicket.protocol.http.pagestore.PageWindowManager$PageWindowInternal
>      at org.apache.wicket.protocol.http.pagestore.PageWindowManager.removePage(PageWindowManager.java:544)
>      at org.apache.wicket.protocol.http.pagestore.DiskPageStore$SessionEntry.removePage(DiskPageStore.java:255)
>      at org.apache.wicket.protocol.http.pagestore.DiskPageStore.removePage(DiskPageStore.java:623)
>      at org.apache.wicket.protocol.http.pagestore.DiskPageStore.removePage(DiskPageStore.java:652)
>      at org.apache.wicket.protocol.http.SecondLevelCacheSessionStore$SecondLevelCachePageMap.removeEntry(SecondLevelCacheSessionStore.java:368)
>      at org.apache.wicket.PageMap.remove(PageMap.java:289)
> The problem in removePage() of the PageWindowManager class was that it wasn't getting the PageWindowInternal from the windows list. There is also a problem though in that it attempts to iterate through the window indexes and at the same time calls removePage() which removes them so you get a ConcurrentModificationException. I've tested the following and it works
> 	public void removePage(int pageId)
> 	{
> 		if (idToWindowIndices == null)
> 		{
> 			rebuildIndices();
> 		}
> 		List indicesList = (List) idToWindowIndices.get(pageId);
> 		if (indicesList == null)
> 		{
> 			return; // Return if page was already removed
> 		}
> 	        Object[] indices = indicesList.toArray();
>         	for (int i=0; i < indices.length; i++)
> 		{
> 			PageWindowInternal window = (PageWindowInternal)windows.get((Integer)indices[i]);
> 			removePage(window.pageId, window.versionNumber, window.ajaxVersionNumber);
> 		}
> 	}
> However I ran into another problem. When my page removes itself it then gets immediately added back in at the end of the request cycle in Session.requestDetached(). So its impossible for a page to expire itself. To fix this I would recommend changing the PageMap.remove(Page) method to
> 	public final void remove(final Page page)
> 	{
> 		// Remove the pagemap entry from session
> 		removeEntry(page.getPageMapEntry());
> 	        // Make sure it doesn't get added again at the end of the request cycle
>         	Session.get().untouch(page);
> 	}
> and then add the untouch() method to Session
> 	/**
> 	* THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT CALL IT.
> 	* <p>
> 	* This method will remove a page that was previously added via touch()
> 	* @param page
> 	*/
> 	public final void untouch(Page page)
> 	{
> 		List lst = (List)touchedPages.get();
> 		if (lst != null)
> 		{
> 			lst.remove(page);
> 		}
> 	}
> With the above changes my code works as it did under version 1.2.6

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.