Details
Description
The static finals in org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn are inconsiderate of specific components that wish to share/reuse particular class implementations in the contrib library.
Specifically our problem involved org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn.FORM_COLUMN_RENDERER_SOURCE (which is of type SimpleTableColumnFormRendererSource).
We have two different table components (being used in two different WARs that share Tapestry at the application classloader level within a single EAR). These components share the class implementors in org.apache.tapestry.contrib.* If we visit a page containing the first of our table components, the execution path through the contrib code causes FORM_COLUMN_RENDERER_SOURCE#getRenderer() to be called. This method lazy initializes one of its data members (m_objComponentRenderer), which is instantiated with reference to a particular namespace (which ultimately is pulled from the name space of whatever component is being used for the TableView). When we try to load our table component in a different namespace (after having already visiting a page with the first component), a similar execution path is taken that causes the FORM_COLUMN_RENDEER_SOURCE#getRenderer() method to be called again. However this time, because of the lazy initialization logic, the data member that was previously set/cached is used, but it is invalid for the current context (specifically, the namespace was no longer valid.)
Granted we are doing something rather atypical here (by extending the Table component twice in a different namespace), but the use of statics here seem sketchy and once we fixed the problem in the tapestry source (simply by removing the lazy initialization for now), the problem went away, and our contrib table extensions worked as expected.
I assume that there are other similar issues in contrib (relating to "static caching" like this).