001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.commons.logging.tccl.logfactory; 019 020 021 import java.net.URL; 022 023 import junit.framework.Test; 024 import junit.framework.TestCase; 025 026 import org.apache.commons.logging.LogFactory; 027 import org.apache.commons.logging.PathableClassLoader; 028 import org.apache.commons.logging.PathableTestSuite; 029 030 031 /** 032 * Verify that by default a custom LogFactoryImpl is loaded from the 033 * tccl classloader. 034 */ 035 036 public class TcclEnabledTestCase extends TestCase { 037 038 // ------------------------------------------- JUnit Infrastructure Methods 039 040 041 /** 042 * Return the tests included in this test suite. 043 */ 044 public static Test suite() throws Exception { 045 Class thisClass = TcclEnabledTestCase.class; 046 047 // Determine the URL to this .class file, so that we can then 048 // append the priority dirs to it. For tidiness, load this 049 // class through a dummy loader though this is not absolutely 050 // necessary... 051 PathableClassLoader dummy = new PathableClassLoader(null); 052 dummy.useExplicitLoader("junit.", Test.class.getClassLoader()); 053 dummy.addLogicalLib("testclasses"); 054 dummy.addLogicalLib("commons-logging"); 055 056 String thisClassPath = thisClass.getName().replace('.', '/') + ".class"; 057 URL baseUrl = dummy.findResource(thisClassPath); 058 059 // Now set up the desired classloader hierarchy. Everything goes into 060 // the parent classpath, but we exclude the custom LogFactoryImpl 061 // class. 062 // 063 // We then create a tccl classloader that can see the custom 064 // LogFactory class. Therefore if that class can be found, then the 065 // TCCL must have been used to load it. 066 PathableClassLoader emptyLoader = new PathableClassLoader(null); 067 068 PathableClassLoader parentLoader = new PathableClassLoader(null); 069 parentLoader.useExplicitLoader("junit.", Test.class.getClassLoader()); 070 parentLoader.addLogicalLib("commons-logging"); 071 parentLoader.addLogicalLib("testclasses"); 072 // hack to ensure that the testcase classloader can't see 073 // the cust MyLogFactoryImpl 074 parentLoader.useExplicitLoader( 075 "org.apache.commons.logging.tccl.custom.", emptyLoader); 076 077 URL propsEnableUrl = new URL(baseUrl, "props_enable_tccl/"); 078 parentLoader.addURL(propsEnableUrl); 079 080 PathableClassLoader tcclLoader = new PathableClassLoader(parentLoader); 081 tcclLoader.addLogicalLib("testclasses"); 082 083 Class testClass = parentLoader.loadClass(thisClass.getName()); 084 return new PathableTestSuite(testClass, tcclLoader); 085 } 086 087 /** 088 * Set up instance variables required by this test case. 089 */ 090 public void setUp() throws Exception { 091 LogFactory.releaseAll(); 092 } 093 094 /** 095 * Tear down instance variables required by this test case. 096 */ 097 public void tearDown() { 098 LogFactory.releaseAll(); 099 } 100 101 // ----------------------------------------------------------- Test Methods 102 103 /** 104 * Verify that MyLogFactoryImpl is only loadable via the tccl. 105 */ 106 public void testLoader() throws Exception { 107 108 ClassLoader thisClassLoader = this.getClass().getClassLoader(); 109 ClassLoader tcclLoader = Thread.currentThread().getContextClassLoader(); 110 111 // the tccl loader should NOT be the same as the loader that loaded this test class. 112 assertNotSame("tccl not same as test classloader", thisClassLoader, tcclLoader); 113 114 // MyLogFactoryImpl should not be loadable via parent loader 115 try { 116 Class clazz = thisClassLoader.loadClass( 117 "org.apache.commons.logging.tccl.custom.MyLogFactoryImpl"); 118 fail("Unexpectedly able to load MyLogFactoryImpl via test class classloader"); 119 assertNotNull(clazz); // silence warning about unused var 120 } catch(ClassNotFoundException ex) { 121 // ok, expected 122 } 123 124 // MyLogFactoryImpl should be loadable via tccl loader 125 try { 126 Class clazz = tcclLoader.loadClass( 127 "org.apache.commons.logging.tccl.custom.MyLogFactoryImpl"); 128 assertNotNull(clazz); 129 } catch(ClassNotFoundException ex) { 130 fail("Unexpectedly unable to load MyLogFactoryImpl via tccl classloader"); 131 } 132 } 133 134 /** 135 * Verify that the custom LogFactory implementation which is only accessable 136 * via the TCCL has successfully been loaded as specified in the config file. 137 * This proves that the TCCL was used to load that class. 138 */ 139 public void testTcclLoading() throws Exception { 140 LogFactory instance = LogFactory.getFactory(); 141 142 assertEquals( 143 "Correct LogFactory loaded", 144 "org.apache.commons.logging.tccl.custom.MyLogFactoryImpl", 145 instance.getClass().getName()); 146 } 147 }