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

Jacques Le Roux commented on OFBIZ-6747:
----------------------------------------

Hi,

As those interested certainly noticed the commits above are only somehow 
related to Caffeine. Actually to run Caffeine 3.1.1 Java 11 is needed. We are 
already running all current supported branches (including deprecated R18.12) 
with Java 11 for few months. But the main build. gradle was not clearly 
building with it. So that what those commits were all about.

I tried to get further and so replace CLHM with Caffeine. As Taher mentionned 
above CLHM is only used in 2 places: UtilCache and ServiceDispatcher classes. 
Moreover in UtilCache it's only really used OOTB by 
EntityPerformanceTest.groovy. It's accessible in Webtools, eg: 
https://demo-trunk.ofbiz.apache.org/webtools/control/EntityPerformanceTest and 
is currently failing:

{noformat}
2022-10-17 15:32:15,403 |27.0.0.1-8009-exec-1 |UtilCache                     
|W| Error getting maxSize value from ResourceBundle for propNames: [null]
java.lang.NullPointerException: null
        at 
org.apache.ofbiz.base.util.cache.UtilCache.getPropertyParam(UtilCache.java:155) 
~[main/:?]
        at 
org.apache.ofbiz.base.util.cache.UtilCache.setPropertiesParams(UtilCache.java:181)
 ~[main/:?]
        at 
org.apache.ofbiz.base.util.cache.UtilCache.setPropertiesParams(UtilCache.java:174)
 ~[main/:?]
        at 
org.apache.ofbiz.base.util.cache.UtilCache.setPropertiesParams(UtilCache.java:170)
 ~[main/:?]
        at 
org.apache.ofbiz.base.util.cache.UtilCache.<init>(UtilCache.java:126) ~[main/:?]
        at 
jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
~[?:?]
        at 
jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
 ~[?:?]
        at 
jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
 ~[?:?]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:490) 
~[?:?]
        at 
org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:80)
 ~[groovy-2.5.18.jar:2.5.18]
        at 
org.codehaus.groovy.reflection.CachedConstructor.doConstructorInvoke(CachedConstructor.java:74)
 ~[groovy-2.5.18.jar:2.5.18]
        at 
org.codehaus.groovy.runtime.callsite.ConstructorSite.callConstructor(ConstructorSite.java:45)
 ~[groovy-2.5.18.jar:2.5.18]
        at 
org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:59)
 ~[groovy-2.5.18.jar:2.5.18]
        at 
org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:237)
 ~[groovy-2.5.18.jar:2.5.18]
        at EntityPerformanceTest.run(EntityPerformanceTest.groovy:193) ~[?:?]
{noformat}
I did not dig into it, I guess it's a long time it's like that.

All other usages of UtilCache simply use ConcurrentHashMap because maxInMemory 
is passed to 0.

Now there is an important use of CLHM in ServiceDispatcher. There I tried 
Caffeine but got an issue I don't clearly understand. Here is my try:
{code:java}
 .../org/apache/ofbiz/service/ServiceDispatcher.java   | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git 
a/framework/service/src/main/java/org/apache/ofbiz/service/ServiceDispatcher.java
 
b/framework/service/src/main/java/org/apache/ofbiz/service/ServiceDispatcher.java
index dd85ece5fd..b9f2821490 100644
--- 
a/framework/service/src/main/java/org/apache/ofbiz/service/ServiceDispatcher.java
+++ 
b/framework/service/src/main/java/org/apache/ofbiz/service/ServiceDispatcher.java
@@ -58,11 +58,13 @@ import org.apache.ofbiz.service.job.JobManager;
 import org.apache.ofbiz.service.job.JobManagerException;
 import org.apache.ofbiz.service.semaphore.ServiceSemaphore;

-import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
+//import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
+import com.github.benmanes.caffeine.cache.Caffeine;
+
+

 /**
- * The global service dispatcher. This is the "engine" part of the
- * Service Engine.
+ * The global service dispatcher. This is the "engine" part of the Service 
Engine.
  */
 public final class ServiceDispatcher {

@@ -70,8 +72,15 @@ public final class ServiceDispatcher {
     public static final int LRU_LOG_SIZE = 200;
     public static final int LOCK_RETRIES = 3;

-    private static final Map<RunningService, ServiceDispatcher> RUN_LOG = new 
ConcurrentLinkedHashMap.Builder<RunningService,
-            ServiceDispatcher>().maximumWeightedCapacity(LRU_LOG_SIZE).build();
+//    private static final Map<RunningService, ServiceDispatcher> RUN_LOG = 
new ConcurrentLinkedHashMap.Builder<RunningService,
+//            
ServiceDispatcher>().maximumWeightedCapacity(LRU_LOG_SIZE).build();
+
+    @SuppressWarnings("unchecked")
+    private static final Map<RunningService,ServiceDispatcher> RUN_LOG = 
(Map<RunningService, ServiceDispatcher>) Caffeine.newBuilder()
+            .maximumSize(LRU_LOG_SIZE)
+            //.executor(Runnable::run)
+            .build();
+
     private static ConcurrentHashMap<String, ServiceDispatcher> dispatchers = 
new ConcurrentHashMap<>();
     // FIXME: These fields are not thread-safe. They are modified by 
EntityDataLoadContainer.
     // We need a better design - like have this class query 
EntityDataLoadContainer if data is being loaded.
{code}
And here is the issue I stumbled upon:
{noformat}
Oct 17, 2022 12:07:15 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["ajp-nio-127.0.0.1-8009"]
Oct 17, 2022 12:07:15 PM org.apache.coyote.http11.AbstractHttp11Protocol 
configureUpgradeProtocol
INFO: The ["http-nio-8080"] connector has been configured to support HTTP 
upgrade to [h2c]
Oct 17, 2022 12:07:15 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-nio-8080"]
Oct 17, 2022 12:07:15 PM org.apache.coyote.http11.AbstractHttp11Protocol 
configureUpgradeProtocol
INFO: The ["https-jsse-nio-8443"] connector has been configured to support 
negotiation to [h2] via ALPN
Oct 17, 2022 12:07:15 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["https-jsse-nio-8443"]
Oct 17, 2022 12:07:15 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service [Tomcat]
Oct 17, 2022 12:07:15 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet engine: [Apache Tomcat/9.0.65]
Oct 17, 2022 12:07:16 PM org.apache.catalina.core.ApplicationContext log
INFO: No Spring WebApplicationInitializer types detected on classpath
Oct 17, 2022 12:07:46 PM org.apache.catalina.core.StandardContext filterStart
SEVERE: Exception starting filter [ContextFilter]
java.lang.ExceptionInInitializerError
        at 
org.apache.ofbiz.service.GenericDispatcherFactory.createLocalDispatcher(GenericDispatcherFactory.java:42)
        at 
org.apache.ofbiz.service.ServiceContainer.getLocalDispatcher(ServiceContainer.java:93)
        at 
org.apache.ofbiz.webapp.WebAppUtil.makeWebappDispatcher(WebAppUtil.java:184)
        at org.apache.ofbiz.webapp.WebAppUtil.getDispatcher(WebAppUtil.java:147)
        at 
org.apache.ofbiz.webapp.control.ContextFilter.init(ContextFilter.java:82)
        at 
org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:272)
        at 
org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:253)
        at 
org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:102)
        at 
org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4613)
        at 
org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5256)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
        at 
org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396)
        at 
org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at 
org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
        at 
java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140)
        at 
org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919)
        at 
org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:835)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
        at 
org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396)
        at 
org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at 
org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
        at 
java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140)
        at 
org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919)
        at 
org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:265)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
        at 
org.apache.catalina.core.StandardService.startInternal(StandardService.java:432)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
        at 
org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:930)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
        at org.apache.catalina.startup.Tomcat.start(Tomcat.java:486)
        at 
org.apache.ofbiz.catalina.container.CatalinaContainer.start(CatalinaContainer.java:134)
        at 
org.apache.ofbiz.base.container.ContainerLoader.startLoadedContainers(ContainerLoader.java:153)
        at 
org.apache.ofbiz.base.container.ContainerLoader.load(ContainerLoader.java:77)
        at 
org.apache.ofbiz.base.start.StartupControlPanel.loadContainers(StartupControlPanel.java:146)
        at 
org.apache.ofbiz.base.start.StartupControlPanel.start(StartupControlPanel.java:70)
        at org.apache.ofbiz.base.start.Start.main(Start.java:89)
Caused by: java.lang.ClassCastException: class 
com.github.benmanes.caffeine.cache.BoundedLocalCache$BoundedLocalManualCache 
cannot be cast to class java.util.Map 
(com.github.benmanes.caffeine.cache.BoundedLocalCache$BoundedLocalManualCac
he is in unnamed module of loader 'app'; java.util.Map is in module java.base 
of loader 'bootstrap')
        at 
org.apache.ofbiz.service.ServiceDispatcher.<clinit>(ServiceDispatcher.java:82)
        ... 38 more

Oct 17, 2022 12:07:47 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: One or more Filters failed to start. Full details will be found in the 
appropriate container log file
Oct 17, 2022 12:07:47 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Context [/ebay] startup failed due to previous errors
Oct 17, 2022 12:07:47 PM org.apache.catalina.loader.WebappClassLoaderBase 
clearReferencesThreads
WARNING: The web application [ebay] appears to have started a thread named 
[ReferenceCleaner] but has failed to stop it. This is very likely to create a 
memory leak. Stack trace of thread:
 java.base@11.0.2/java.lang.Object.wait(Native Method)
 java.base@11.0.2/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155)
 java.base@11.0.2/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:176)
 
app//org.apache.ofbiz.base.util.ReferenceCleaner$CleanerThread.run(ReferenceCleaner.java:45)
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by 
org.apache.catalina.loader.WebappClassLoaderBase 
(file:/Z:/Gradle/caches/modules-2/files-2.1/org.apache.tomcat/tomcat-catalina/9.0.65/660daec193384908640601d8d0e9c1b4a29fabc/tomcat-catalina-9.0.65.ja
r) to field java.io.ObjectStreamClass$Caches.localDescs
WARNING: Please consider reporting this to the maintainers of 
org.apache.catalina.loader.WebappClassLoaderBase
WARNING: Use --illegal-access=warn to enable warnings of further illegal 
reflective access operations
WARNING: All illegal access operations will be denied in a future release
Oct 17, 2022 12:07:47 PM org.apache.catalina.core.ApplicationContext log
INFO: No Spring WebApplicationInitializer types detected on classpath
Oct 17, 2022 12:07:47 PM org.apache.catalina.core.ApplicationContext log
INFO: No Spring WebApplicationInitializer types detected on classpath
{noformat}
I tried several ways to cast instead of Map (BoundedLocalCache is not the way I 
found, among others) and also tried to use {{.executor(Runnable::run)}} to no 
avail.

So it's not yet much conclusing, any help is welcome :)

> Replace ConcurrentLinkedHashMap by Caffeine
> -------------------------------------------
>
>                 Key: OFBIZ-6747
>                 URL: https://issues.apache.org/jira/browse/OFBIZ-6747
>             Project: OFBiz
>          Issue Type: Improvement
>          Components: framework/base, framework/service
>    Affects Versions: Upcoming Branch
>            Reporter: Ben Manes
>            Assignee: Jacques Le Roux
>            Priority: Minor
>             Fix For: Upcoming Branch
>
>
> Similar to OFBIZ-3779, please consider upgrading the library used by 
> [UtilCache|https://github.com/apache/ofbiz/blob/trunk/framework/base/src/main/java/org/apache/ofbiz/base/util/cache/UtilCache.java]
>  (v1.2). The current version is 1.4.2 and is the last major release planned.
> The preferable alternative would be to upgrade to 
> [Caffeine|https://github.com/ben-manes/caffeine]. This is a Java 8 rewrite 
> based on what I've learned since developing CLHM and Guava's cache. As 
> expected it provides [superior 
> performance|https://github.com/ben-manes/caffeine/wiki/Benchmarks]. It also 
> provides a [near 
> optimal|https://github.com/ben-manes/caffeine/wiki/Efficiency] eviction 
> policy.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to