3 Replies Latest reply on Feb 3, 2012 6:52 PM by Brian Oliver-Oracle

    Bug with class-scheme and cache-ref macro

      I was trying to build and run our project using Coherence and 2.1.1 of Incubator Commons.

      In our project we have a cache mapping and class scheme that allow us to create a CQC and use it just like a normal cache, i.e. we can call Cachefactory.getCache(“ReplicatedRefSourceBook”) and we get back a CQC wrapping a cache called LatestRefSourceBook. It works like this

      Cache config file:
      <?xml version="1.0"?>
      <cache-config xmlns:element="class://com.oracle.coherence.environment.extensible.namespaces.XmlElementProcessingNamespaceContentHandler"
              <!-- Replicated Caches for Reference data -->
      Our ConnectedCache class extends WrapperNamedCache and has a constructor that takes a String and a NamedCache. The NamedCache is supplied by the {cache-ref} macro as Coherence strips the ReplicatedRef part and replaces it with LatestRef so if I ask for ReplicatedRefSourceBook the underlying-cache is LatestRefSourceBook.

      The problem is that in INC-10 2.1.1 this breaks (although it might be broken in other versions after 1.7.3) as the Incubator takes over creating class-scheme and messes up the underlying-cache parameter. The problem seems to be in the ExtensibleEnvironment.instantiateAny method. The parameters I want are inside the info (CacheInfo) parameter but these do not get added to the parameterProvider. If I change the method so it looks like the one below then it appears to work. Basically it requires parameters from the CacheInfo parameter to be copied into the parameterProvider. (My change is between the two /* Fix added by JK */ comments).
      public Object instantiateAny(CacheInfo info,
                                   XmlElement xmlClass,
                                   BackingMapManagerContext context,
                                   ClassLoader loader)
          //use a registered Scheme to produce the instance (if required)
          if (xmlClass.getName().equals("class-scheme") && xmlClass.getAttributeMap().containsKey("use-scheme"))
              //determine the schemeId for the Scheme to use
              String schemeId = xmlClass.getAttribute("use-scheme").getString();
                  //locate the builder
                  ParameterizedBuilder<?> builder = (ParameterizedBuilder<?>) getResource(BuilderRegistry.class)
                  //locate the cache mapping
                  CacheMapping cacheMapping = getResource(CacheMappingRegistry.class).findCacheMapping(
                  //determine the parameter provider for the cache mapping
                  MutableParameterProvider parameterProvider = new ScopedParameterProvider(cacheMapping == null
                          ? SystemPropertyParameterProvider.INSTANCE : cacheMapping.getParameterProvider());
                  /* ---------- Fix added by JK ----------------------------------- */
                  // Copy any attributes from the CacheInfo into the parameterProvider
                  for(Map.Entry attributeEntry : (Set<Map.Entry>)info.getAttributes().entrySet()) {
                      parameterProvider.addParameter(new Parameter(attributeEntry.getKey().toString(), attributeEntry.getValue()));
                  /* ---------- Fix added by JK ----------------------------------- */
                  //add the standard coherence parameters to the parameter provider
                  parameterProvider.addParameter(new Parameter("cache-name", info.getCacheName()));
                  parameterProvider.addParameter(new Parameter("class-loader", loader));
                  parameterProvider.addParameter(new Parameter("manager-context", context));
                  //set the class loader if we have one
                  if (builder instanceof ClassLoaderAware)
                      ((ClassLoaderAware) builder).setContextClassLoader(loader);
                  return builder.realize(parameterProvider);
              catch (ClassCastException classCastException)
                  throw new RuntimeException(String.format(
                      "Cound not instantiate %s as the namespace did not return a ClassScheme.", xmlClass),
              return super.instantiateAny(info, xmlClass, context, loader);