This was true before Java 5 but it works since Java 5 IF you use a volatile 
field to hold the reference.

Jacopo

On Sep 3, 2014, at 3:38 PM, Adrian Crum <[email protected]> 
wrote:

> The DCL design pattern will fail 90% of the time. I was able to prove this a 
> while back when I removed the DCL pattern from the transaction factory and 
> connection factory.
> 
> I recommend using an atomic reference.
> 
> Adrian Crum
> Sandglass Software
> www.sandglass-software.com
> 
> On 9/3/2014 10:10 AM, [email protected] wrote:
>> Author: jacopoc
>> Date: Wed Sep  3 09:10:04 2014
>> New Revision: 1622193
>> 
>> URL: http://svn.apache.org/r1622193
>> Log:
>> Greatly simplified the UtilJ2eeCompat class by removing a series of 
>> variables and methods no more in use.
>> The class was not thread safe and this didn't cause particular issues 
>> probably just because all the threads using it were passing ServletContext 
>> with the same server info value (because they were associated to the same 
>> servlet container); it was however inefficient.
>> Now it is thread safe using the DCL pattern which I usually tend to avoid 
>> but is useful here.
>> However this class should probably go away but before taking a decision I 
>> will start a discussion in the dev list.
>> 
>> Modified:
>>    ofbiz/trunk/framework/base/src/org/ofbiz/base/util/UtilJ2eeCompat.java
>> 
>> Modified: 
>> ofbiz/trunk/framework/base/src/org/ofbiz/base/util/UtilJ2eeCompat.java
>> URL: 
>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/UtilJ2eeCompat.java?rev=1622193&r1=1622192&r2=1622193&view=diff
>> ==============================================================================
>> --- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/UtilJ2eeCompat.java 
>> (original)
>> +++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/UtilJ2eeCompat.java 
>> Wed Sep  3 09:10:04 2014
>> @@ -28,74 +28,60 @@ public class UtilJ2eeCompat {
>> 
>>     public static final String module = UtilJ2eeCompat.class.getName();
>> 
>> -    public static final String TOMCAT = "apache tomcat";
>> -    public static final String ORION = "orion";
>> -    public static final String RESIN = "resin";
>> -    public static final String REX_IP = "tradecity";
>> -    public static final String OC4J = "oracle";
>> -    public static final String JRUN = "jrun";
>> -    public static final String JETTY = "jetty";
>> -    public static final String WEBSPHERE = "websphere";
>> -
>> -    protected static Boolean doFlushOnRenderValue = null;
>> -    protected static Boolean useOutputStreamNotWriterValue = null;
>> -    protected static Boolean useNestedJspException = null;
>> -
>> -    public static boolean doFlushOnRender(ServletContext context) {
>> -        initCompatibilityOptions(context);
>> -        return doFlushOnRenderValue.booleanValue();
>> -    }
>> -
>> -    public static boolean useOutputStreamNotWriter(ServletContext context) {
>> -        initCompatibilityOptions(context);
>> -        return useOutputStreamNotWriterValue.booleanValue();
>> -    }
>> +    private static final String TOMCAT = "apache tomcat";
>> +    private static final String ORION = "orion";
>> +    private static final String REX_IP = "tradecity";
>> +    private static final String JRUN = "jrun";
>> +    private static final String JETTY = "jetty";
>> +    private static final String WEBSPHERE = "websphere";
>> +
>> +    private volatile static UtilJ2eeCompat instance;
>> +
>> +    private final boolean useOutputStreamNotWriter;
>> +
>> +    private UtilJ2eeCompat(ServletContext context) {
>> +        boolean usestream = true;
>> +        // if context is null use an empty string here which will cause the 
>> defaults to be used
>> +        String serverInfo = context == null ? "" : 
>> context.getServerInfo().toLowerCase();
>> +
>> +        Debug.logInfo("serverInfo: " + serverInfo, module);
>> +
>> +        if (serverInfo.indexOf(TOMCAT) >= 0) {
>> +            Debug.logInfo("Apache Tomcat detected, using response.getWriter 
>> to write text out instead of response.getOutputStream", module);
>> +            usestream = false;
>> +        } else if (serverInfo.indexOf(REX_IP) >= 0) {
>> +            Debug.logInfo("Trade City RexIP detected, using 
>> response.getWriter to write text out instead of response.getOutputStream", 
>> module);
>> +            usestream = false;
>> +        } else if (serverInfo.indexOf(JRUN) >= 0) {
>> +            Debug.logInfo("JRun detected, using response.getWriter to write 
>> text out instead of response.getOutputStream", module);
>> +            usestream = false;
>> +        } else if (serverInfo.indexOf(JETTY) >= 0) {
>> +            Debug.logInfo("Jetty detected, using response.getWriter to 
>> write text out instead of response.getOutputStream", module);
>> +            usestream = false;
>> +        } else if (serverInfo.indexOf(ORION) >= 0) {
>> +            Debug.logInfo("Orion detected, using response.getWriter to 
>> write text out instead of response.getOutputStream", module);
>> +            usestream = false;
>> +        } else if (serverInfo.indexOf(WEBSPHERE) >= 0) {
>> +            Debug.logInfo("IBM Websphere Application Server detected, using 
>> response.getWriter to write text out instead of response.getOutputStream", 
>> module);
>> +            usestream = false;
>> +        }
>> 
>> -    public static boolean useNestedJspException(ServletContext context) {
>> -        initCompatibilityOptions(context);
>> -        return useNestedJspException.booleanValue();
>> +        useOutputStreamNotWriter = usestream;
>>     }
>> 
>> -    protected static void initCompatibilityOptions(ServletContext context) {
>> -        // this check to see if we should flush is done because on most 
>> servers this
>> -        // will just slow things down and not solve any problems, but on 
>> Tomcat, Orion, etc it is necessary
>> -        if (useOutputStreamNotWriterValue == null || doFlushOnRenderValue 
>> == null) {
>> -            boolean doflush = true;
>> -            boolean usestream = true;
>> -            boolean nestjspexception = true;
>> -            // if context is null use an empty string here which will cause 
>> the defaults to be used
>> -            String serverInfo = context == null ? "" : 
>> context.getServerInfo().toLowerCase();
>> -
>> -            Debug.logInfo("serverInfo: " + serverInfo, module);
>> -
>> -            if (serverInfo.indexOf(RESIN) >= 0) {
>> -                Debug.logInfo("Resin detected, disabling the flush on the 
>> region render from PageContext for better performance", module);
>> -                doflush = false;
>> -            } else if (serverInfo.indexOf(REX_IP) >= 0) {
>> -                Debug.logInfo("Trade City RexIP detected, using 
>> response.getWriter to write text out instead of response.getOutputStream", 
>> module);
>> -                usestream = false;
>> -            } else if (serverInfo.indexOf(TOMCAT) >= 0) {
>> -                Debug.logInfo("Apache Tomcat detected, using 
>> response.getWriter to write text out instead of response.getOutputStream", 
>> module);
>> -                usestream = false;
>> -            } else if (serverInfo.indexOf(JRUN) >= 0) {
>> -                Debug.logInfo("JRun detected, using response.getWriter to 
>> write text out instead of response.getOutputStream", module);
>> -                usestream = false;
>> -            } else if (serverInfo.indexOf(JETTY) >= 0) {
>> -                Debug.logInfo("Jetty detected, using response.getWriter to 
>> write text out instead of response.getOutputStream", module);
>> -                usestream = false;
>> -            } else if (serverInfo.indexOf(ORION) >= 0) {
>> -                Debug.logInfo("Orion detected, using response.getWriter to 
>> write text out instead of response.getOutputStream", module);
>> -                usestream = false;
>> -                Debug.logInfo("Orion detected, using non-nested 
>> JspException", module);
>> -                nestjspexception = false;
>> -            } else if (serverInfo.indexOf(WEBSPHERE) >= 0) {
>> -                Debug.logInfo("IBM Websphere Application Server detected, 
>> using response.getWriter to write text out instead of 
>> response.getOutputStream", module);
>> -                usestream = false;
>> +    private static UtilJ2eeCompat getInstance(ServletContext context) {
>> +        if (instance == null) {
>> +            synchronized (UtilJ2eeCompat.class) {
>> +                if (instance == null) {
>> +                    instance = new UtilJ2eeCompat(context);
>> +                }
>>             }
>> -
>> -            doFlushOnRenderValue = Boolean.valueOf(doflush);
>> -            useOutputStreamNotWriterValue = Boolean.valueOf(usestream);
>> -            useNestedJspException = Boolean.valueOf(nestjspexception);
>>         }
>> +        return instance;
>>     }
>> +
>> +    public static boolean useOutputStreamNotWriter(ServletContext context) {
>> +        return getInstance(context).useOutputStreamNotWriter;
>> +    }
>> +
>> }
>> 
>> 

Reply via email to