=== modified file 'src/com/goldencode/p2j/persist/CacheManager.java'
--- old/src/com/goldencode/p2j/persist/CacheManager.java	2023-07-06 10:45:40 +0000
+++ new/src/com/goldencode/p2j/persist/CacheManager.java	2024-02-16 06:12:40 +0000
@@ -2,7 +2,7 @@
 ** Module   : CacheManager.java
 ** Abstract : Manages caches in the persistent package based on the directory configuration.
 **
-** Copyright (c) 2023, Golden Code Development Corporation.
+** Copyright (c) 2023-2024, Golden Code Development Corporation.
 **
 ** -#- -I- --Date-- -----------------------------------Description-----------------------------------
 ** 001 DDF 20230613 Created initial version.
@@ -10,6 +10,8 @@
 **                  that caches are initialized even if binding fails.
 **     DDF 20230706 Added an additional createLRUCache wrapper method which will use a null
 **                  discriminator by default.
+** 002 DDF 20240216 Initialize DynamicQueryHelper and DynamicValidationHelper caches through
+**                  CacheManager.
 */
 
 /*
@@ -119,9 +121,9 @@
                String className = Utils.getDirectoryNodeString(ds, nodePath + "/class-name", null, false);
                int cacheSize = Utils.getDirectoryNodeInt(ds, nodePath + "/size", -1, false);
                String discriminator = Utils.getDirectoryNodeString(ds,
-                        nodePath + "/discriminator",
-                        null,
-                        false);
+                                                                   nodePath + "/discriminator",
+                                                                   null,
+                                                                   false);
                
                if (className == null)
                {
@@ -180,7 +182,9 @@
          // There are also caches that are not static and are initialized in their specific class.
          
          FQLPreprocessor.initializeCache();
-         SortCriterion.initializeCache();   
+         SortCriterion.initializeCache(); 
+         DynamicQueryHelper.initializeCache();
+         DynamicValidationHelper.initializeCache();
       }
    }
    

=== modified file 'src/com/goldencode/p2j/persist/DynamicQueryHelper.java'
--- old/src/com/goldencode/p2j/persist/DynamicQueryHelper.java	2023-11-24 21:48:03 +0000
+++ new/src/com/goldencode/p2j/persist/DynamicQueryHelper.java	2024-02-16 07:28:36 +0000
@@ -2,7 +2,7 @@
 ** Module   : DynamicQueryHelper.java
 ** Abstract : Helper class for dynamic queries.
 **
-** Copyright (c) 2013-2023, Golden Code Development Corporation.
+** Copyright (c) 2013-2024, Golden Code Development Corporation.
 **
 ** -#- -I- --Date-- ---------------------------------------Description----------------------------------------
 ** 001 CA  20130929 Created initial version.
@@ -87,6 +87,8 @@
 ** 044 AL2 20230411 Ensure delayed execute is run only once. The flag is reset on query close. 
 ** 045 GBB 20230512 Logging methods replaced by CentralLogger/ConversionStatus.
 ** 046 EVL 20231124 Avoid duplicating string related methods for performance reason.
+** 047 DDF 20240216 lvl1Cache and lvl2Cache can only be created through CacheManager now and 
+**                  have been made non-final.
 */
 
 /*
@@ -155,7 +157,6 @@
 import com.goldencode.cache.*;
 import com.goldencode.p2j.cfg.*;
 import com.goldencode.p2j.convert.*;
-import com.goldencode.p2j.directory.*;
 import com.goldencode.p2j.jmx.*;
 import com.goldencode.p2j.persist.P2JQuery.QueryEventListener;
 import com.goldencode.p2j.persist.lock.LockType;
@@ -200,12 +201,6 @@
    /** The name of the generated java class. */
    private static final String DYN_GEN_QUERY_CLASS = "DynGenQuery";
    
-   /** The name of the directory key for the size of level 1 cache holding converted queries. */
-   private static final String LVL1_CACHE_SIZE = "dynamic-query-cache-lvl1-size";
-   
-   /** The name of the directory key for the size of level 2 cache holding converted queries. */
-   private static final String LVL2_CACHE_SIZE = "dynamic-query-cache-lvl2-size";
-   
    /** Logger. */
    private static final CentralLogger LOG = CentralLogger.get(DynamicQueryHelper.class.getName());
    
@@ -221,48 +216,6 @@
       }
    };
    
-   /**
-    * 1st level cache. Holds the queries and their default parameters. Its management uses
-    * an aging and usage algorithm to chose entries to be dropped when the maximum capacity
-    * is reached.
-    */
-   private static final ExpiryCache<QueryCacheKey, ParametrizedJast> lvl1Cache;
-   
-   /**
-    * 2nd level cache. Queries from this level of cache do not require default parameters
-    * because they are computed before the cache key. Its management uses an aging and usage
-    * algorithm to chose entries to be dropped when the maximum capacity is reached.
-    */
-   private static final ExpiryCache<QueryCacheKey, JavaAst> lvl2Cache;
-   
-   static
-   {
-      Directory dir = DirectoryManager.getInstance();
-      lvl1Cache = new LRUCache<>("DynamicQueryHelper.1", 
-                                 dir.getInt(Directory.ID_RELATIVE, LVL1_CACHE_SIZE, 65536));
-      lvl1Cache.addCacheExpiryListener(event -> {
-         // debug only: to see when the cache is full
-         if (LOG.isLoggable(Level.INFO))
-         {
-            LOG.log(Level.INFO, 
-                    "DynamicQueryHelper cache level #1 is full. " +
-                    "Dumped " + event.getExpiredEntries().size() + " old entries.");
-         }
-      });
-      
-      lvl2Cache = new LRUCache<>("DynamicQueryHelper.2",
-                                 dir.getInt(Directory.ID_RELATIVE, LVL2_CACHE_SIZE, 16384));
-      lvl2Cache.addCacheExpiryListener(event -> {
-         // debug only: to see when the cache is full
-         if (LOG.isLoggable(Level.INFO))
-         {
-            LOG.log(Level.INFO, 
-                    "DynamicQueryHelper cache level #2 is full. " +
-                    "Dumped " + event.getExpiredEntries().size() + " old entries.");
-         }
-      });
-   }
-   
    /** Instrumentation for {@link #parseFindQuery}. */
    private static final NanoTimer PARSE_FIND = NanoTimer.getInstance(FwdJMX.TimeStat.OrmDynParseFind);
    
@@ -281,6 +234,48 @@
    public static final NanoTimer PROCESS_INTERN = NanoTimer.getInstance(FwdJMX.TimeStat.OrmDynQueryProcess_Intern);
    
    /**
+    * 1st level cache. Holds the queries and their default parameters. Its management uses
+    * an aging and usage algorithm to chose entries to be dropped when the maximum capacity
+    * is reached.
+    */
+   private static ExpiryCache<QueryCacheKey, ParametrizedJast> lvl1Cache;
+   
+   /**
+    * 2nd level cache. Queries from this level of cache do not require default parameters
+    * because they are computed before the cache key. Its management uses an aging and usage
+    * algorithm to chose entries to be dropped when the maximum capacity is reached.
+    */
+   private static ExpiryCache<QueryCacheKey, JavaAst> lvl2Cache;
+   
+   /**
+    * Initialize caches using CacheManager. The default value of the cache
+    * is used when there is no size available from the configuration.
+    */
+   public static void initializeCache()
+   {
+      lvl1Cache = CacheManager.createLRUCache(DynamicQueryHelper.class, "lvl1", 65536);
+      lvl1Cache.addCacheExpiryListener(event -> {
+         // debug only: to see when the cache is full
+         if (LOG.isLoggable(Level.INFO))
+         {
+            LOG.log(Level.INFO, 
+                    "DynamicQueryHelper cache level #1 is full. " +
+                    "Dumped " + event.getExpiredEntries().size() + " old entries.");
+         }
+      });
+      lvl2Cache = CacheManager.createLRUCache(DynamicQueryHelper.class, "lvl2", 16384);
+      lvl2Cache.addCacheExpiryListener(event -> {
+         // debug only: to see when the cache is full
+         if (LOG.isLoggable(Level.INFO))
+         {
+            LOG.log(Level.INFO, 
+                    "DynamicQueryHelper cache level #2 is full. " +
+                    "Dumped " + event.getExpiredEntries().size() + " old entries.");
+         }
+      });
+   }
+   
+   /**
     * Private worker for parsing a given query string using the QueryProcessor and return a
     * {@link P2JQuery} instance.
     * This method is only called by the package-public methods {@link #parseQuery} and

=== modified file 'src/com/goldencode/p2j/persist/DynamicValidationHelper.java'
--- old/src/com/goldencode/p2j/persist/DynamicValidationHelper.java	2023-05-12 10:05:12 +0000
+++ new/src/com/goldencode/p2j/persist/DynamicValidationHelper.java	2024-02-16 07:28:46 +0000
@@ -2,7 +2,7 @@
 ** Module   : DynamicValidationHelper.java
 ** Abstract : Helper class for dynamic validation expressions.
 **
-** Copyright (c) 2017-2023, Golden Code Development Corporation.
+** Copyright (c) 2017-2024, Golden Code Development Corporation.
 **
 ** -#- -I- --Date-- ---------------------------------------Description---------------------------------------
 ** 001 SVL 20171024 Created initial version.
@@ -18,6 +18,7 @@
 **     CA  20230116 Avoid using handle.unwrap, handle.getReference or other BDT usage from within FWD runtime.
 ** 004 OM  20230215 Handled collision of buffers with same dynamic table name.
 ** 005 GBB 20230512 Logging methods replaced by CentralLogger/ConversionStatus.
+** 006 DDF 20240216 cache can only be created through CacheManager now and has been made non-final.
 */
 
 /*
@@ -79,7 +80,6 @@
 import com.goldencode.ast.*;
 import com.goldencode.cache.*;
 import com.goldencode.p2j.convert.*;
-import com.goldencode.p2j.directory.*;
 import com.goldencode.p2j.schema.*;
 import com.goldencode.p2j.security.*;
 import com.goldencode.p2j.uast.*;
@@ -101,21 +101,12 @@
    /** Counter for converted validation expressions. */
    private static final AtomicLong valexpCounter = new AtomicLong(1);
    
-   /** Name of the directory parameter which specifies cache size. */
-   private static final String CACHE_SIZE_PARAMETER = "dynamic-valexp-cache-size";
-   
    /** Name of the variable which replaces the validated field reference in the validation expression. */
    public static final String VAL_EXPR_VAR_NAME = "valExprDynParam";
    
    /** The name of the generated java class. */
    private static final String DYN_GEN_VAL_EXPR_CLASS = "DynGenValExpr";
    
-   /**
-    * Cache for JASTs generated from validation expressions. Cache management uses an aging and
-    * usage algorithm to chose entries to be dropped when the maximum capacity is reached.
-    */
-   private static final ExpiryCache<ValExprCacheKey, JavaAst> cache;
-   
    /** Logger. */
    private static final CentralLogger LOG = CentralLogger.get(DynamicValidationHelper.class.getName());
    
@@ -128,11 +119,19 @@
       }
    };
    
-   static
+   /**
+    * Cache for JASTs generated from validation expressions. Cache management uses an aging and
+    * usage algorithm to chose entries to be dropped when the maximum capacity is reached.
+    */
+   private static ExpiryCache<ValExprCacheKey, JavaAst> cache;
+   
+   /**
+    * Initializes the cache using CacheManager. The default value of the cache
+    * is used when there is no size available from the configuration.
+    */
+   public static void initializeCache()
    {
-      Directory dir = DirectoryManager.getInstance();
-      cache = new LRUCache<>("DynamicValidationHelper",
-                                  dir.getInt(Directory.ID_RELATIVE, CACHE_SIZE_PARAMETER, 65536));
+      cache = CacheManager.createLRUCache(DynamicValidationHelper.class, 65536);
       cache.addCacheExpiryListener(event ->
       {
          // debug only: to see when the cache is full

