Return-Path: Delivered-To: apmail-commons-issues-archive@minotaur.apache.org Received: (qmail 11459 invoked from network); 3 Aug 2009 21:28:35 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 3 Aug 2009 21:28:35 -0000 Received: (qmail 11141 invoked by uid 500); 3 Aug 2009 21:28:40 -0000 Delivered-To: apmail-commons-issues-archive@commons.apache.org Received: (qmail 11035 invoked by uid 500); 3 Aug 2009 21:28:39 -0000 Mailing-List: contact issues-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: issues@commons.apache.org Delivered-To: mailing list issues@commons.apache.org Received: (qmail 11025 invoked by uid 99); 3 Aug 2009 21:28:39 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 03 Aug 2009 21:28:39 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.140] (HELO brutus.apache.org) (140.211.11.140) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 03 Aug 2009 21:28:36 +0000 Received: from brutus (localhost [127.0.0.1]) by brutus.apache.org (Postfix) with ESMTP id CEAF3234C045 for ; Mon, 3 Aug 2009 14:28:14 -0700 (PDT) Message-ID: <822457738.1249334894839.JavaMail.jira@brutus> Date: Mon, 3 Aug 2009 14:28:14 -0700 (PDT) From: "Franklin Phan (JIRA)" To: issues@commons.apache.org Subject: [jira] Issue Comment Edited: (BEANUTILS-353) Unable to call isUseDefault() to check whether a default value will be returned In-Reply-To: <608682474.1248655334794.JavaMail.jira@brutus> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 X-Virus-Checked: Checked by ClamAV on apache.org [ https://issues.apache.org/jira/browse/BEANUTILS-353?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12738264#action_12738264 ] Franklin Phan edited comment on BEANUTILS-353 at 8/3/09 2:27 PM: ----------------------------------------------------------------- I am trying your suggestion from your first comment, and I am seeing an inconsistency with the workings of this "per-classloader" feature. I have two instances of Tomcat 5.5.27 running on separate machines (one Linux and one WinXP). Each Tomcat is set up similarly and runs the same copy of a webapp. Per your suggestion, I wrote each webapp a *Filter* whose *init* method registers an implementation of *SqlTimestampConverter* that returns a default of null: {code:title=EmployeeDirFilter.java|borderStyle=solid} public class EmployeeDirFilter implements RenderFilter, ActionFilter { private FilterConfig config; ... public void init(FilterConfig filterConfig) throws PortletException { config = filterConfig; // Register a SqlTimestampConverter that returns a default of NULL BeanUtilsBean.getInstance().getConvertUtils().register(new SqlTimestampConverter(null), java.sql.Timestamp.class); } } {code} Using NetBeans Debugger, I can see that during server startup, the init method is called for both webapps and a new instance of *BeanUtilsBeans* (containing the corrected *SqlTimestampConverter*) is stored in the *{{valueByClassLoader}} Map* in *ContextClassLoaderLocal*. Each converter is mapped by the *ContextClassLoader* gotten from: {code:title=org.apache.commons.beanutils.ContextClassLoaderLocal.java get() method|borderStyle=solid}ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();{code} So far so good. Later, when the webapps are called again via a different action, one webapp retrieves the same *BeanUtilsBeans* from the *{{valueByClassLoader}} Map* while the other webapp gets a different *ContextClassLoader*, thereby causing a second, _new_ instance of *BeanUtilsBeans* to be created with all the default Converters via the *{{ConvertUtilsBean.deregister}}* method and having it stores in the *{{valueByClassLoader}} Map*. This new instance of *BeanUtilsBeans* contains, of course, the _incorrect_ *SqlTimestampConverter*; and *{{valueByClassLoader}} Map* now contains _two_ *BeanUtilsBeans*. What's causing this discrepant behavior in the latter Tomcat/webapp? In case it matters, here's the *Context* for the two webapps in each Tomcat (notice that *{{useContextClassLoader}}* is set to *{{false}}*): {code:title=Context element under /conf/Catalina/localhost|borderStyle=solid} {code} was (Author: fphan): I am trying your suggestion from your first comment, and I am seeing an inconsistency with the workings of this "per-classloader" feature. I have two instances of Tomcat 5.5.27 running on separate machines (one Linux and one WinXP). Each Tomcat is set up similarly and runs the same copy of a webapp. Per your suggestion, I wrote each webapp a *Filter* whose *init* method registers an implementation of *SqlTimestampConverter* that returns a default of null: {code:title=EmployeeDirFilter.java|borderStyle=solid} public class EmployeeDirFilter implements RenderFilter, ActionFilter { private FilterConfig config; ... public void init(FilterConfig filterConfig) throws PortletException { config = filterConfig; // Register a SqlTimestampConverter that returns a default of NULL BeanUtilsBean.getInstance().getConvertUtils().register(new SqlTimestampConverter(null), java.sql.Timestamp.class); } } {code} Using NetBeans Debugger, I can see that during server startup, the init method is called for both webapps and a new instance of *BeanUtilsBeans* (containing the corrected *SqlTimestampConverter*) is stored in the *{{valueByClassLoader}} Map* in *ContextClassLoaderLocal*. Each converter is mapped by the *ContextClassLoader* gotten from: {code:title=org.apache.commons.beanutils.ContextClassLoaderLocal.java get() method|borderStyle=solid}ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();{code} So far so good. Later, when the webapps are called again via a different action, one webapp retrieves the same *BeanUtilsBeans* from the *{{valueByClassLoader}} Map* while the other webapp gets a different *ContextClassLoader* and creates a second, new instance of *BeanUtilsBeans* with all the default Converters via the *{{ConvertUtilsBean.deregister}}* method and stores it in the *{{valueByClassLoader}} Map*. This new instance of *BeanUtilsBeans* contains, of course, the _incorrect_ *SqlTimestampConverter*; and *{{valueByClassLoader}} Map* now contains _two_ *BeanUtilsBeans*. What's causing this discrepant behavior in the latter Tomcat/webapp? In case it matters, here's the *Context* for the two webapps in each Tomcat (notice that *{{useContextClassLoader}}* is set to *{{false}}*): {code:title=Context element under /conf/Catalina/localhost|borderStyle=solid} {code} > Unable to call isUseDefault() to check whether a default value will be returned > ------------------------------------------------------------------------------- > > Key: BEANUTILS-353 > URL: https://issues.apache.org/jira/browse/BEANUTILS-353 > Project: Commons BeanUtils > Issue Type: Bug > Components: ConvertUtils & Converters > Affects Versions: 1.8.0 > Environment: WinXP Pro, Linux, JDK 1.6.0_14, Tomcat 5.5.27 > Reporter: Franklin Phan > > One can never call isUseDefault() to check on a Converter given the way you have ConverterFacade designed and in ConvertUtilsBean: > {code:title=org.apache.commons.beanutils.ConverUtilsBean|borderStyle=solid} > private void register(Class clazz, Converter converter) { > register(new ConverterFacade(converter), clazz); > } > {code} -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online.