[ 
https://issues.apache.org/jira/browse/BEANUTILS-450?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13812875#comment-13812875
 ] 

Matthew Hall commented on BEANUTILS-450:
----------------------------------------

We ensure this in our use by registering the converters before creating the 
LookAndFeel object that uses them. They are registered earlier in the same 
method that creates and installs the LookAndFeel for our application. This 
guarantees that, from an application flow standpoint, the converters would be 
registered before any attempted use, just as registering them within a static 
block would.

I think it's important to note that the exact same behavior is exhibited with 
the reworked version as with the version that registered the converters in a 
static block. All Java 6 clients have no problems whatsoever. Some Java 7 
clients report the issue, but when it is reported the workaround of enabling 
the Java console is reliable.

> BeanUtilsBean.getInstance() pseudo-singleton causes problems with Java 7 
> parallelized class loader
> --------------------------------------------------------------------------------------------------
>
>                 Key: BEANUTILS-450
>                 URL: https://issues.apache.org/jira/browse/BEANUTILS-450
>             Project: Commons BeanUtils
>          Issue Type: Bug
>          Components: Bean / Property Utils, ConvertUtils & Converters
>    Affects Versions: 1.7.0
>         Environment: Java 7u25+, Windows 7 32-bit desktop environments
>            Reporter: Matthew Hall
>            Priority: Blocker
>
> From an email I sent to the BeanUtils users mailing list:
> We recently tracked a bug in our software that started showing up with Java 7 
> back to an incompatibility between BeanUtilsBean.getInstance() 
> pseudo-singleton instance model, Java 7’s parallelized class loader, and the 
> fact that we were registering Converters with ConvertUtils inside of a static 
> class-level block. As far as I’m able to tell, this wasn’t a problem in 
> previous versions of Java because the class loader was not parallelized, 
> meaning that the class loader that handled the registration of our converters 
> was the same class loader that was in use when ConvertUtilsBean.getInstance() 
> was invoked. Now, with Java 7, it seems that there is no guarantee that the 
> class loader that executes the static block containing the Converter 
> registration is the same one in use when ConvertUtilsBean.getInstance() is 
> invoked, meaning that our custom Converters are not necessarily available 
> everywhere they used to be.
> I’m writing to the list today to ask three things about this situation:
>  1.  First off, is this the correct explanation for the reason that it seems 
> we’re not guaranteed to have our custom Converters loaded in Java 7.
>  2.  In order to ensure that a different class loader thread is not in use 
> when the Converters are registered with ConvertUtils, we’ve moved this 
> registration from a static class-level block into a user interface setup 
> method that is executed before the Converters are used.
>  3.  Given that Java 7 introduced parallelized class loading in the base 
> ClassLoader and that BeanUtilsBean builds instances on a per-classloader 
> basis, should this issue be raised to the BeanUtils developers?
> Below you’ll find some pseudocode that illustrates our situation:
> {code}
> public class UtilitiesClass {
>    ...
>    static {
>        registerConverters();
>    }
>    public static void registerConverters() {
>        ConvertUtils.register(new OurCustomColorConverter(), 
> java.awt.Color.class);
>    }
>    ...
> }
> public class MainGUIClass {
>    ...
>    public static void main(String[] args) {
>        MainGUIClass mainGui = new MainGUIClass();
>        mainGui.setup();
>        mainGui.show();
>    }
>    public void setup() {
>        UIManager.setLookAndFeel(new LookAndFeelClass());
>    }
>    public void show() {
>        ((OurLookAndFeelClass) UIManager.getLookAndFeel()).getColor();
>    }
>    ...
> }
> public class LookAndFeelClass extends LookAndFeel {
>    ...
>    public java.awt.Color getColor(String colorString) {
>        return (java.awt.Color) ConvertUtils.convert("someValidColorString", 
> java.awt.Color.class);
>    }
>    ...
> }
> {code}
> In the above example, the cast of the results of ConvertUtils.convert to 
> Color in LookAndFeelClass.getColor(String) sometimes results in a runtime 
> exception with the message “java.lang.String cannot be cast to 
> java.awt.Color.”. This appears to be due to the fact that 
> ConvertUtils.convert() fails over to the built-in String.class Converter if 
> it cannot find a Converter for the specified class. In production 
> environments, it was completely unpredictable as to when this would happen 
> and what would make the problem go away.
> The fix we implemented was to move the registration of 
> OurCustomColorConverter() from the static block inside of UtilitiesClass to 
> the first line of MainGUIClass.setup(), before the LookAndFeel is loaded. 
> Will this fix be sufficient, or does it still suffer from the thread issue, 
> if that is indeed the root cause of the problem?



--
This message was sent by Atlassian JIRA
(v6.1#6144)

Reply via email to