[MGNLCACHE-120] Not possible to run two web apps under the same context path within one JVM Created: 22/Jul/15  Updated: 19/Aug/15  Resolved: 04/Aug/15

Status: Closed
Project: Cache Modules
Component/s: ehcache
Affects Version/s: 5.4
Fix Version/s: 5.4.1

Type: Bug Priority: Major
Reporter: Jozef Chocholacek Assignee: Roman Kovařík
Resolution: Fixed Votes: 2
Labels: cache
Remaining Estimate: 0d
Time Spent: 40m
Original Estimate: Not Specified

Issue Links:
causality
is causing MGNLCACHE-121 MalformedObjectNameException when roo... Closed
is causing MGNLCACHE-122 Cache configuration changes lose cach... Closed
Template:
Acceptance criteria:
Empty
Task DoD:
[ ]* Doc/release notes changes? Comment present?
[ ]* Downstream builds green?
[ ]* Solution information and context easily available?
[ ]* Tests
[ ]* FixVersion filled and not yet released
[ ]  Architecture Decision Record (ADR)
Bug DoR:
[ ]* Steps to reproduce, expected, and actual results filled
[ ]* Affected version filled
Date of First Response:
Sprint: Sprint 4 (Kromeriz)
Story Points: 2

 Description   

When I use our standard deployment configuration (which we've successfuly used from 4.x till latest 5.3.x), the cache module startup for the public instance crashes with net.sf.ehcache.CacheException: javax.management.InstanceAlreadyExistsException: net.sf.ehcache:type=CacheManager,name=#info.magnolia.module.cache.ehcache.EhCacheFactory#cacheManager

The deployment configuration is that the instances are deployed to webapps/magnoliaAuthor/ROOT and webapps/magnoliaPublic/ROOT, and we have two separate Service definitions in the Tomcat's server.xml, with appBase pointing to webapps/magnoliaAuthor and webapps/magnoliaPublic, respectively.

Btw. the cache is actually working, but the flushing commands are not.

The cause (and solution) could be probably similar to these in the old MAGNOLIA-786



 Comments   
Comment by Jozef Chocholacek [ 22/Jul/15 ]

Partial workaround: when I change the order of Services in the server.xml, so the public instance starts first, then the cache module crashes for author instance, where it is actually not needed. So I've lowered the priority from Critical to Major.

Comment by Arne Diekmann [ 29/Jul/15 ]

We are having the exact same problem, as soon as two different magnolia instances are started in the same servlet container with the same context path. Looks like info.magnolia.module.cache.ehcache.EhCacheFactory#getCacheManagerIdentifier might be the problem here, since the cache name is derived from the context path:

private String getCacheManagerIdentifier() {
    return StringUtils.removeStart(magnoliaInitPaths.getContextPath(), "/") + "#" + getClass().getName() + "#cacheManager";
}

Using magnoliaInitPaths.getRootPath() might do the trick.

Comment by Jozef Chocholacek [ 04/Aug/15 ]

The following (new) test would IMHO work also with the old code, because the contextPath values used to create cacheManagerIdentifier differ:

    @Test
    public void twoWebappsRunningInTheSameJVM() throws Exception {
        // WHEN
        DefaultMagnoliaInitPaths webapp1magnoliaInitPaths = mock(DefaultMagnoliaInitPaths.class);
        when(webapp1magnoliaInitPaths.getRootPath()).thenReturn("/Users/username/bundles/apache-tomcat-7.0.47/webapps/magnoliaPublic");
        EhCacheFactory webapp1Cachefactory = new EhCacheFactory(null, cacheModule, webapp1magnoliaInitPaths);

        DefaultMagnoliaInitPaths webapp2magnoliaInitPaths = mock(DefaultMagnoliaInitPaths.class);
        when(webapp1magnoliaInitPaths.getRootPath()).thenReturn("/Users/username/bundles/apache-tomcat-7.0.47/webapps/magnoliaAuthor");
        EhCacheFactory webapp2Cachefactory = new EhCacheFactory(null, cacheModule, webapp2magnoliaInitPaths);

        // WHEN
        webapp1Cachefactory.start(false);
        webapp2Cachefactory.start(false);

        // THEN net.sf.ehcache.CacheException: Another CacheManager with same name already exists in the same VM should not occur
    }

The problem occurs when the webapps use the same context, e.g. when they are in /Users/username/bundles/apache-tomcat-7.0.47/webapps/magnoliaAuthor/ROOT and /Users/username/bundles/apache-tomcat-7.0.47/webapps/magnoliaPublic/ROOT (mind the ROOT at the end of path - both are in ROOT context). I believe the code itself is correct, just the test does not reflect the original problem completely.

Comment by Roman Kovařík [ 04/Aug/15 ]

Hi Josef,
thx for investigating. The test'd pass with the original code since it'd retrieve the cacheManager from the first instance and it would skip the initialisation, see the line 228. So it this case we cannot run the test against the original (improper) code unless we add the mock settings for code which is not used anymore.

Roman

Comment by Jozef Chocholacek [ 05/Aug/15 ]

@rkovarik FYI: I've just tested the concerned configuration (instances in magnoliaAuthor/ROOT and magnoliaPublic/ROOT and two Services in server.xml) with the #4954 build from Jenkins, and everything works good.

Generated at Sun Feb 11 23:52:24 CET 2024 using Jira 9.4.2#940002-sha1:46d1a51de284217efdcb32434eab47a99af2938b.