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 }