You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2007/02/28 20:20:52 UTC

svn commit: r512906 - in /incubator/openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/conf/ openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ openjpa-project/src/doc/manual/

Author: pcl
Date: Wed Feb 28 11:20:51 2007
New Revision: 512906

URL: http://svn.apache.org/viewvc?view=rev&rev=512906
Log:
OPENJPA-160

Added:
    incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/BrokerValue.java   (with props)
    incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FinalizingBrokerImpl.java   (with props)
Modified:
    incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
    incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
    incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_conf.xml
    incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_optimization.xml
    incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_runtime.xml

Added: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/BrokerValue.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/BrokerValue.java?view=auto&rev=512906
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/BrokerValue.java (added)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/BrokerValue.java Wed Feb 28 11:20:51 2007
@@ -0,0 +1,49 @@
+package org.apache.openjpa.conf;
+
+import org.apache.openjpa.lib.conf.PluginValue;
+import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.kernel.BrokerImpl;
+import org.apache.openjpa.kernel.FinalizingBrokerImpl;
+import org.apache.openjpa.util.InternalException;
+
+/**
+ * Custom {@link PluginValue} that can efficiently create {@link BrokerImpl}
+ * instances.
+ *
+ * @since 0.9.7
+ */
+public class BrokerValue 
+    extends PluginValue {
+
+    private BrokerImpl _templateBroker;
+
+    public BrokerValue(String prop) {
+        super(prop, false);
+        String[] aliases = new String[] {
+            "default", FinalizingBrokerImpl.class.getName(),
+            "non-finalizing", BrokerImpl.class.getName(), 
+        };
+        setAliases(aliases);
+        setDefault(aliases[0]);
+        setString(aliases[0]);        
+    }
+
+    public Object newInstance(String clsName, Class type, Configuration conf,
+        boolean fatal) {
+        if (BrokerImpl.class.getName().equals(clsName)) {
+            // This is not synchronized. If there are concurrent invocations
+            // while _templateBroker is null, we'll just end up with extra
+            // template brokers, which will get safely garbage collected.
+            if (_templateBroker == null)
+                _templateBroker = (BrokerImpl) super.newInstance(
+                    clsName, type, conf, fatal);
+            try {
+                return _templateBroker.clone();
+            } catch (CloneNotSupportedException e) {
+                throw new InternalException(e);
+            }
+        } else {
+            return super.newInstance(clsName, type, conf, fatal);
+        }
+    }
+}

Propchange: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/BrokerValue.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java?view=diff&rev=512906&r1=512905&r2=512906
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java Wed Feb 28 11:20:51 2007
@@ -71,7 +71,7 @@
 
     // openjpa properties
     public ObjectValue classResolverPlugin;
-    public ObjectValue brokerPlugin;
+    public BrokerValue brokerPlugin;
     public ObjectValue dataCachePlugin;
     public ObjectValue dataCacheManagerPlugin;
     public IntValue dataCacheTimeout;
@@ -178,11 +178,8 @@
         brokerFactoryPlugin = new BrokerFactoryValue();
         addValue(brokerFactoryPlugin);
 
-        brokerPlugin = addPlugin("BrokerImpl", false);
-        aliases = new String[] { "default", BrokerImpl.class.getName() };
-        brokerPlugin.setAliases(aliases);
-        brokerPlugin.setDefault(aliases[0]);
-        brokerPlugin.setString(aliases[0]);
+        brokerPlugin = new BrokerValue("BrokerImpl");
+        addValue(brokerPlugin);
 
         dataCacheManagerPlugin = addPlugin("DataCacheManager", true);
         aliases =

Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java?view=diff&rev=512906&r1=512905&r2=512906
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java Wed Feb 28 11:20:51 2007
@@ -96,7 +96,7 @@
  * @author Abe White
  */
 public class BrokerImpl
-    implements Broker, FindCallbacks {
+    implements Broker, FindCallbacks, Cloneable {
 
     /**
      * Incremental flush.
@@ -155,14 +155,13 @@
     private ManagedRuntime _runtime = null;
     private LockManager _lm = null;
     private InverseManager _im = null;
-    private final JCAHelper _jca = new JCAHelper();
+    private JCAHelper _jca = null;
     private ReentrantLock _lock = null;
     private OpCallbacks _call = null;
     private RuntimeExceptionTranslator _extrans = null;
 
     // cache class loader associated with the broker
-    private ClassLoader _loader = Thread.currentThread().
-        getContextClassLoader();
+    private ClassLoader _loader = null;
 
     // user state
     private Synchronization _sync = null;
@@ -225,6 +224,8 @@
     private LifecycleEventManager _lifeEventManager = null;
     private int _lifeCallbackMode = 0;
 
+    private boolean _initializeWasInvoked = false;
+    
     /**
      * Set the persistence manager's authentication. This is the first
      * method called after construction.
@@ -251,6 +252,9 @@
      */
     public void initialize(AbstractBrokerFactory factory,
         DelegatingStoreManager sm, boolean managed, int connMode) {
+        _initializeWasInvoked = true;
+        _loader = Thread.currentThread().getContextClassLoader();
+        _jca = new JCAHelper();
         _conf = factory.getConfiguration();
         _compat = _conf.getCompatibilityInstance();
         _factory = factory;
@@ -295,14 +299,13 @@
             beginInternal();
     }
 
-    /**
-     * Close on finalize.
-     */
-    protected void finalize()
-        throws Throwable {
-        super.finalize();
-        if (!isClosed())
-            free();
+    public Object clone()
+        throws CloneNotSupportedException {
+        if (_initializeWasInvoked)
+            throw new CloneNotSupportedException();
+        else {
+            return super.clone();
+        }
     }
 
     /**

Added: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FinalizingBrokerImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FinalizingBrokerImpl.java?view=auto&rev=512906
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FinalizingBrokerImpl.java (added)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FinalizingBrokerImpl.java Wed Feb 28 11:20:51 2007
@@ -0,0 +1,23 @@
+package org.apache.openjpa.kernel;
+
+/**
+ * Subtype of {@link BrokerImpl} that automatically closes itself during
+ * finalization. This implementation guards against potential resource leaks,
+ * but also incurs a scalability bottleneck as instances are enlisted in the
+ * finalization queue and subsequently cleaned up.
+ *
+ * @since 0.9.7
+ */
+public class FinalizingBrokerImpl
+    extends BrokerImpl {
+
+    /**
+     * Close on finalize.
+     */
+    protected void finalize()
+        throws Throwable {
+        super.finalize();
+        if (!isClosed())
+            free();
+    }
+}

Propchange: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FinalizingBrokerImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_conf.xml
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_conf.xml?view=diff&rev=512906&r1=512905&r2=512906
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_conf.xml (original)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_conf.xml Wed Feb 28 11:20:51 2007
@@ -585,7 +585,7 @@
 <xref linkend="ref_guide_conf_plugins"/>) describing the
 <ulink url="../javadoc/org/apache/openjpa/kernel/Broker.html"><classname>
 org.apache.openjpa.kernel.Broker</classname></ulink> type to use at runtime. See
-<xref linkend="ref_guide_runtime_pmextension"/> on for details.
+<xref linkend="ref_guide_runtime_broker_extension"/> on for details.
             </para>
         </section>
         <section id="openjpa.ClassResolver">

Modified: incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_optimization.xml
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_optimization.xml?view=diff&rev=512906&r1=512905&r2=512906
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_optimization.xml (original)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_optimization.xml Wed Feb 28 11:20:51 2007
@@ -564,6 +564,25 @@
 collection of results can speed up data loading by orders of magnitude.
                     </entry>
                 </row>
+                <row>
+                    <entry colname="name">
+                        <emphasis role="bold">
+                            Disable BrokerImpl finalization
+                        </emphasis>
+                        <para>
+<emphasis>performance, scalability</emphasis>
+                        </para>
+                    </entry>
+                    <entry colname="desc">
+By default, OpenJPA's EntityManagers use finalizers to ensure that resources
+get cleaned up. If you are properly managing your resources, this finalization
+is not necessary, and will introduce unneeded synchronization, leading to
+scalability problems. You can disable this protective behavior by setting the
+<literal>openjpa.BrokerImpl</literal> property to
+<literal>non-finalizing</literal>. See <link
+linkend="ref_guide_runtime_broker_finalization"/> for details.
+                    </entry>
+                </row>
             </tbody>
         </tgroup>
     </table>

Modified: incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_runtime.xml
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_runtime.xml?view=diff&rev=512906&r1=512905&r2=512906
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_runtime.xml (original)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_runtime.xml Wed Feb 28 11:20:51 2007
@@ -103,30 +103,47 @@
 <classname>BrokerFactories</classname>, <classname>EntityManager</classname>s
 and <classname>Broker</classname>s.
         </para>
-        <section id="ref_guide_runtime_pmextension">
+        <section id="ref_guide_runtime_broker_finalization">
             <title>
-                Broker Customization
+                Broker Finalization
             </title>
-            <indexterm zone="ref_guide_runtime_pmextension">
+            <indexterm zone="ref_guide_runtime_broker_finalization">
                 <primary>
-                    OpenJPAEntityManager
+                    EntityManager
                 </primary>
                 <secondary>
-                    extending
+                    finalizing
+                </secondary>
+                <secondary>
+                    clean-up
                 </secondary>
             </indexterm>
             <para>
-Some advanced users may want to add capabilities to OpenJPA's internal
-<ulink url="../javadoc/org/apache/openjpa/kernel/BrokerImpl.html"><classname>
-org.apache.openjpa.kernel.BrokerImpl</classname></ulink>. You can configure
-OpenJPA to use a custom subclass of <classname>BrokerImpl</classname> through
-the <link linkend="openjpa.BrokerImpl"><literal>openjpa.BrokerImpl</literal>
-</link> configuration property. Set this property to the full class name of your
-custom subclass.
+The default OpenJPAEntityManager implementation automatically closes itself 
+during instance finalization. This guards against accidental resource leaks
+that may occur if a developer fails to explicitly close EntityManagers when
+finished with them, but it also incurs a scalability bottleneck, since the 
+JVM must perform synchronization during instance creation, and since the 
+finalizer thread will have more instances to monitor. To avoid this overhead,
+set the <link linkend="openjpa.BrokerImpl"><literal>openjpa.BrokerImpl</literal>
+</link> configuration property to <literal>non-finalizing</literal>.
             </para>
+        </section>
+        <section id="ref_guide_runtime_broker_extension">
+            <title>
+                Broker Customization and Finalization
+            </title>
+            <indexterm zone="ref_guide_runtime_broker_extension">
+                <primary>
+                    OpenJPAEntityManager
+                </primary>
+                <secondary>
+                    extending
+                </secondary>
+            </indexterm>
             <para>
-As a <link linkend="ref_guide_conf_plugins">plugin string</link>, you can also
-use this property to configure the <classname> BrokerImpl</classname> with the
+As a <link linkend="ref_guide_conf_plugins">plugin string</link>, this property
+can be used to configure the <classname> BrokerImpl</classname> with the
 following properties:
             </para>
             <itemizedlist>
@@ -147,6 +164,22 @@
 &lt;property name="openjpa.BrokerImpl" value="EvictFromDataCache=true"/&gt;
 </programlisting>
             </example>
+            <para>
+Additionally, some advanced users may want to add capabilities to OpenJPA's
+internal <ulink url="../javadoc/org/apache/openjpa/kernel/BrokerImpl.html">
+<classname>org.apache.openjpa.kernel.BrokerImpl</classname></ulink>. You can 
+configure OpenJPA to use a custom subclass of <classname>BrokerImpl</classname> 
+with the <link linkend="openjpa.BrokerImpl"><literal>openjpa.BrokerImpl
+</literal></link> configuration property. Set this property to the full class 
+name of your custom subclass. When implementing your subclass, consider the
+finalization issues mentioned in 
+<link linkend="ref_guide_runtime_broker_finalization"/>. It may be appropriate
+to create a subtype of both 
+<ulink url="../javadoc/org/apache/openjpa/kernel/BrokerImpl.html">
+<classname>org.apache.openjpa.kernel.BrokerImpl</classname></ulink> and
+<ulink url="../javadoc/org/apache/openjpa/kernel/FinalizingBrokerImpl.html">
+<classname>org.apache.openjpa.kernel.FinalizingBrokerImpl</classname></ulink>.
+            </para>
         </section>
     </section>
     <section id="ref_guide_runtime_jpa">



RE: svn commit: r512906 - in /incubator/openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/conf/ openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ openjpa-project/src/doc/manual/

Posted by Patrick Linskey <pl...@bea.com>.
> Cloneable _templateBroker = null;
> boolean _templateTried = false;

>      if (broker instanceof Cloneable)
>          _templateBroker = (Cloneable) broker;

Since BrokerImpl is Cloneable, and the property always returns a
BrokerImpl, I don't think that we need to check for cloneability.

-Patrick

-- 
Patrick Linskey
BEA Systems, Inc. 

_______________________________________________________________________
Notice:  This email message, together with any attachments, may contain
information  of  BEA Systems,  Inc.,  its subsidiaries  and  affiliated
entities,  that may be confidential,  proprietary,  copyrighted  and/or
legally privileged, and is intended solely for the use of the individual
or entity named in this message. If you are not the intended recipient,
and have received this message in error, please immediately return this
by email and then delete it. 

> -----Original Message-----
> From: Abe White 
> Sent: Wednesday, February 28, 2007 11:41 AM
> To: open-jpa-dev@incubator.apache.org
> Subject: Re: svn commit: r512906 - in 
> /incubator/openjpa/trunk: 
> openjpa-kernel/src/main/java/org/apache/openjpa/conf/ 
> openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ 
> openjpa-project/src/doc/manual/
> 
> 
> > +    public Object newInstance(String clsName, Class type,  
> > Configuration conf,
> > +        boolean fatal) {
> > +        if (BrokerImpl.class.getName().equals(clsName)) {
> > +            // This is not synchronized. If there are concurrent  
> > invocations
> > +            // while _templateBroker is null, we'll just end up  
> > with extra
> > +            // template brokers, which will get safely garbage  
> > collected.
> > +            if (_templateBroker == null)
> > +                _templateBroker = (BrokerImpl) super.newInstance(
> > +                    clsName, type, conf, fatal);
> > +            try {
> > +                return _templateBroker.clone();
> > +            } catch (CloneNotSupportedException e) {
> > +                throw new InternalException(e);
> > +            }
> > +        } else {
> > +            return super.newInstance(clsName, type, conf, fatal);
> > +        }
> > +    }
> > +}
> 
> Don't we want FinalizingBrokerImpls to clone too?  And possible  
> subclasses?  How about:
> 
> Cloneable _templateBroker = null;
> boolean _templateTried = false;
> 
> ...
> 
> if (!_templateTried) {
>      Object broker = super.newInstance(clsName, type, conf, false);
>      if (broker instanceof Cloneable)
>          _templateBroker = (Cloneable) broker;
>      _templateTried = true;
> }
> 
> if (_templateBroker != null) {
>      return _templateBroker.clone...
> }
> return super.newInstance...
> 
> And for completeness we should set _templateTrid to false on set/ 
> setString.
> ______________________________________________________________
> _________
> Notice:  This email message, together with any attachments, 
> may contain
> information  of  BEA Systems,  Inc.,  its subsidiaries  and  
> affiliated
> entities,  that may be confidential,  proprietary,  
> copyrighted  and/or
> legally privileged, and is intended solely for the use of the 
> individual
> or entity named in this message. If you are not the intended 
> recipient,
> and have received this message in error, please immediately 
> return this
> by email and then delete it.
> 

RE: svn commit: r512906 - in /incubator/openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/conf/ openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ openjpa-project/src/doc/manual/

Posted by Patrick Linskey <pl...@bea.com>.
Good catch; I wrote that before the finalization changes went in.
Changing...

-Patrick

-- 
Patrick Linskey
BEA Systems, Inc. 

_______________________________________________________________________
Notice:  This email message, together with any attachments, may contain
information  of  BEA Systems,  Inc.,  its subsidiaries  and  affiliated
entities,  that may be confidential,  proprietary,  copyrighted  and/or
legally privileged, and is intended solely for the use of the individual
or entity named in this message. If you are not the intended recipient,
and have received this message in error, please immediately return this
by email and then delete it. 

> -----Original Message-----
> From: Abe White 
> Sent: Wednesday, February 28, 2007 11:41 AM
> To: open-jpa-dev@incubator.apache.org
> Subject: Re: svn commit: r512906 - in 
> /incubator/openjpa/trunk: 
> openjpa-kernel/src/main/java/org/apache/openjpa/conf/ 
> openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ 
> openjpa-project/src/doc/manual/
> 
> 
> > +    public Object newInstance(String clsName, Class type,  
> > Configuration conf,
> > +        boolean fatal) {
> > +        if (BrokerImpl.class.getName().equals(clsName)) {
> > +            // This is not synchronized. If there are concurrent  
> > invocations
> > +            // while _templateBroker is null, we'll just end up  
> > with extra
> > +            // template brokers, which will get safely garbage  
> > collected.
> > +            if (_templateBroker == null)
> > +                _templateBroker = (BrokerImpl) super.newInstance(
> > +                    clsName, type, conf, fatal);
> > +            try {
> > +                return _templateBroker.clone();
> > +            } catch (CloneNotSupportedException e) {
> > +                throw new InternalException(e);
> > +            }
> > +        } else {
> > +            return super.newInstance(clsName, type, conf, fatal);
> > +        }
> > +    }
> > +}
> 
> Don't we want FinalizingBrokerImpls to clone too?  And possible  
> subclasses?  How about:
> 
> Cloneable _templateBroker = null;
> boolean _templateTried = false;
> 
> ...
> 
> if (!_templateTried) {
>      Object broker = super.newInstance(clsName, type, conf, false);
>      if (broker instanceof Cloneable)
>          _templateBroker = (Cloneable) broker;
>      _templateTried = true;
> }
> 
> if (_templateBroker != null) {
>      return _templateBroker.clone...
> }
> return super.newInstance...
> 
> And for completeness we should set _templateTrid to false on set/ 
> setString.
> ______________________________________________________________
> _________
> Notice:  This email message, together with any attachments, 
> may contain
> information  of  BEA Systems,  Inc.,  its subsidiaries  and  
> affiliated
> entities,  that may be confidential,  proprietary,  
> copyrighted  and/or
> legally privileged, and is intended solely for the use of the 
> individual
> or entity named in this message. If you are not the intended 
> recipient,
> and have received this message in error, please immediately 
> return this
> by email and then delete it.
> 

Re: svn commit: r512906 - in /incubator/openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/conf/ openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ openjpa-project/src/doc/manual/

Posted by Abe White <aw...@bea.com>.
> +    public Object newInstance(String clsName, Class type,  
> Configuration conf,
> +        boolean fatal) {
> +        if (BrokerImpl.class.getName().equals(clsName)) {
> +            // This is not synchronized. If there are concurrent  
> invocations
> +            // while _templateBroker is null, we'll just end up  
> with extra
> +            // template brokers, which will get safely garbage  
> collected.
> +            if (_templateBroker == null)
> +                _templateBroker = (BrokerImpl) super.newInstance(
> +                    clsName, type, conf, fatal);
> +            try {
> +                return _templateBroker.clone();
> +            } catch (CloneNotSupportedException e) {
> +                throw new InternalException(e);
> +            }
> +        } else {
> +            return super.newInstance(clsName, type, conf, fatal);
> +        }
> +    }
> +}

Don't we want FinalizingBrokerImpls to clone too?  And possible  
subclasses?  How about:

Cloneable _templateBroker = null;
boolean _templateTried = false;

...

if (!_templateTried) {
     Object broker = super.newInstance(clsName, type, conf, false);
     if (broker instanceof Cloneable)
         _templateBroker = (Cloneable) broker;
     _templateTried = true;
}

if (_templateBroker != null) {
     return _templateBroker.clone...
}
return super.newInstance...

And for completeness we should set _templateTrid to false on set/ 
setString.
_______________________________________________________________________
Notice:  This email message, together with any attachments, may contain
information  of  BEA Systems,  Inc.,  its subsidiaries  and  affiliated
entities,  that may be confidential,  proprietary,  copyrighted  and/or
legally privileged, and is intended solely for the use of the individual
or entity named in this message. If you are not the intended recipient,
and have received this message in error, please immediately return this
by email and then delete it.