/** * Copyright 2011-2013 Terracotta, Inc. * Copyright 2011-2013 Oracle, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jsr107.tck.spi; import org.jsr107.tck.testutil.ExcludeListExcluder; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import javax.cache.Cache; import javax.cache.CacheManager; import javax.cache.Caching; import javax.cache.configuration.MutableConfiguration; import javax.cache.spi.CachingProvider; import java.io.File; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.net.URLClassLoader; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; /** * Functional Tests for CachingProvider ClassLoader isolation. * * @author Brian Oliver * @author Yannis Cosmadopoulos * @see CachingProvider * @since 1.0 */ public class CachingProviderClassLoaderTest { /** * Rule used to exclude tests */ @Rule public ExcludeListExcluder rule = new ExcludeListExcluder(this.getClass()); @Before public void startUp() { //ensure that there are no open CacheManagers for the CachingProvider Caching.getCachingProvider().close(); } /** * Multiple invocations of {@link javax.cache.spi.CachingProvider#getCacheManager()} * will return the same instance. */ @Test public void getCacheManagerSingleton() { // obtain the default caching provider CachingProvider provider = Caching.getCachingProvider(); // obtain the default class loader ClassLoader classLoader = Caching.getDefaultClassLoader(); // obtain the default cache manager CacheManager manager = provider.getCacheManager(); assertNotNull(classLoader); assertNotNull(manager); // ensure the default manager is the same as asking the provider // for a cache manager using the default URI and classloader assertSame(manager, provider.getCacheManager()); assertSame(manager, provider.getCacheManager(provider.getDefaultURI(), provider.getDefaultClassLoader())); // using a different ClassLoader ClassLoader otherLoader = new MyClassLoader(classLoader); CachingProvider otherProvider = Caching.getCachingProvider(otherLoader); CacheManager otherManager = otherProvider.getCacheManager(); assertSame(otherManager, otherProvider.getCacheManager()); assertSame(otherManager, otherProvider.getCacheManager(otherProvider.getDefaultURI(), otherProvider.getDefaultClassLoader())); } /** * The default CacheManager is the same as the CacheManager using the default * CachingProvider URI. */ @Test public void getCacheManagerDefaultURI() { ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); CachingProvider provider = Caching.getCachingProvider(contextLoader); CacheManager manager = provider.getCacheManager(); assertEquals(provider.getDefaultURI(), manager.getURI()); // using a different ClassLoader ClassLoader otherLoader = new MyClassLoader(contextLoader); CachingProvider otherProvider = Caching.getCachingProvider(otherLoader); assertNotSame(provider, otherProvider); CacheManager otherManager = otherProvider.getCacheManager(); assertNotSame(manager, otherManager); assertEquals(otherProvider.getDefaultURI(), otherManager.getURI()); } /** * The URI of the CacheManager returned by {@link CachingProvider#getCacheManager(java.net.URI, ClassLoader)} * is the same as the URI used in the invocation. */ @Test public void getCacheManagerSameURI() { ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); CachingProvider provider = Caching.getCachingProvider(contextLoader); URI uri = provider.getDefaultURI(); CacheManager manager = provider.getCacheManager(uri, contextLoader); assertEquals(uri, manager.getURI()); // using a different ClassLoader ClassLoader otherLoader = new MyClassLoader(contextLoader); CachingProvider otherProvider = Caching.getCachingProvider(otherLoader); assertNotSame(provider, otherProvider); CacheManager otherManager = otherProvider.getCacheManager(uri, contextLoader); assertNotSame(manager, otherManager); assertEquals(uri, otherManager.getURI()); } /** * Close all CacheManagers from a CachingProvider, each CacheManager being * based on a different ClassLoader. */ @Test public void closeAllCacheManagers() throws Exception { ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); CachingProvider provider = Caching.getCachingProvider(contextLoader); URI uri = provider.getDefaultURI(); ClassLoader loader1 = new MyClassLoader(contextLoader); CacheManager manager1 = provider.getCacheManager(uri, loader1); ClassLoader loader2 = new MyClassLoader(contextLoader); CacheManager manager2 = provider.getCacheManager(uri, loader2); ClassLoader loader3 = new MyClassLoader(contextLoader); CacheManager manager3 = provider.getCacheManager(uri, loader3); provider.close(); assertNotSame(manager1, provider.getCacheManager(uri, loader1)); assertNotSame(manager2, provider.getCacheManager(uri, loader2)); assertNotSame(manager3, provider.getCacheManager(uri, loader3)); } /** * Closing a single CacheManager from a CachingProvider when there are * multiple available across different ClassLoaders. */ @Test public void closeCacheManager() throws Exception { ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); CachingProvider provider = Caching.getCachingProvider(contextLoader); URI uri = provider.getDefaultURI(); ClassLoader loader1 = new MyClassLoader(contextLoader); CacheManager manager1 = provider.getCacheManager(uri, loader1); ClassLoader loader2 = new MyClassLoader(contextLoader); CacheManager manager2 = provider.getCacheManager(uri, loader2); ClassLoader loader3 = new MyClassLoader(contextLoader); CacheManager manager3 = provider.getCacheManager(uri, loader3); provider.close(manager2.getURI(), loader2); assertSame(manager1, provider.getCacheManager(uri, loader1)); assertNotSame(manager2, provider.getCacheManager(uri, loader2)); assertSame(manager3, provider.getCacheManager(uri, loader3)); } /** * Attempt to close CacheManagers using URIs and/or ClassLoaders that don't * have associated CacheManagers. */ @Test public void closeClassLoader() throws Exception { ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); CachingProvider provider = Caching.getCachingProvider(contextLoader); URI uri = provider.getDefaultURI(); ClassLoader loader1 = new MyClassLoader(contextLoader); CacheManager manager1 = provider.getCacheManager(uri, loader1); ClassLoader loader2 = new MyClassLoader(contextLoader); CacheManager manager2 = provider.getCacheManager(uri, loader2); ClassLoader loader3 = new MyClassLoader(contextLoader); CacheManager manager3 = provider.getCacheManager(uri, loader3); provider.close(contextLoader); provider.close(provider.getDefaultURI(), contextLoader); provider.close(provider.getDefaultURI(), contextLoader); provider.close(provider.getDefaultURI(), contextLoader); assertSame(manager1, provider.getCacheManager(uri, loader1)); assertSame(manager2, provider.getCacheManager(uri, loader2)); assertSame(manager3, provider.getCacheManager(uri, loader3)); } /** * Wrapper round domain program. */ private static class ApplicationDomain { private static String TEST_CLASS_NAME = "domain.Zoo"; /** * this should be set by maven to point at the domain jar */ private static final String DOMAINJAR = "domainJar"; private final ClassLoader classLoader; private final Cache<Integer, Object> cache; public ApplicationDomain() throws MalformedURLException { this.classLoader = createClassLoader(); cache = createCache(); } private ClassLoader createClassLoader() throws MalformedURLException { String domainJarFileName; if (System.getProperties().containsKey(DOMAINJAR)) { domainJarFileName = System.getProperty(DOMAINJAR); } else { Class<?> clazz = CachingProviderClassLoaderTest.class; final String clazzURI = clazz.getName().replace('.', File.separatorChar) + ".class"; final URL clazzURL = clazz.getClassLoader().getResource(clazzURI); final String clazzPath = clazzURL.getPath(); final File root = new File(clazzPath.substring(0, clazzPath.length() - clazzURI.length())); domainJarFileName = new File(root.getParentFile().getParentFile().getParentFile(), "implementation-tester" + File.separatorChar + "specific-implementation-tester" + File.separatorChar + "target" + File.separatorChar + "domainlib" + File.separatorChar + "domain.jar").toString(); } File file = new File(domainJarFileName); if (!file.exists()) { throw new IllegalArgumentException("can't find domain jar: " + domainJarFileName); } URL urls[] = new URL[]{file.toURI().toURL()}; ClassLoader parent = Thread.currentThread().getContextClassLoader(); return new URLClassLoader(urls, parent); } private Cache<Integer, Object> createCache() { CachingProvider provider = Caching.getCachingProvider(classLoader); provider.getCacheManager(provider.getDefaultURI(), classLoader).createCache("c1", new MutableConfiguration<Integer, Object>()); return provider.getCacheManager(provider.getDefaultURI(), classLoader).getCache("c1"); } public Class getClassForDomainClass() throws ClassNotFoundException { return Class.forName(TEST_CLASS_NAME, false, classLoader); } public Cache<Integer, Object> getCache() { return cache; } } private static class MyClassLoader extends ClassLoader { public MyClassLoader(ClassLoader parent) { super(parent); } } }