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