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.log;
018:
019: import java.net.URL;
020:
021: import junit.framework.Test;
022: import junit.framework.TestCase;
023:
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogConfigurationException;
026: import org.apache.commons.logging.LogFactory;
027: import org.apache.commons.logging.PathableClassLoader;
028: import org.apache.commons.logging.PathableTestSuite;
029:
030: /**
031: * Verify that by default LogFactoryImpl is loaded from the tccl classloader.
032: */
033:
034: public class TcclDisabledTestCase extends TestCase {
035:
036: public static final String MY_LOG_PKG = "org.apache.commons.logging.tccl.custom";
037:
038: public static final String MY_LOG_IMPL = MY_LOG_PKG + ".MyLog";
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 Log class.
063: //
064: // We then create a tccl classloader that can see the custom
065: // Log class. Therefore if that class can be found, then the
066: // TCCL must have been used to load it.
067: PathableClassLoader emptyLoader = new PathableClassLoader(null);
068:
069: PathableClassLoader parentLoader = new PathableClassLoader(null);
070: parentLoader.useSystemLoader("junit.");
071: parentLoader.addLogicalLib("commons-logging");
072: parentLoader.addLogicalLib("testclasses");
073: // hack to ensure that the testcase classloader can't see
074: // the custom MyLog
075: parentLoader.useExplicitLoader(MY_LOG_PKG + ".", emptyLoader);
076:
077: URL propsEnableUrl = new URL(baseUrl, "props_disable_tccl/");
078: parentLoader.addURL(propsEnableUrl);
079:
080: PathableClassLoader tcclLoader = new PathableClassLoader(
081: parentLoader);
082: tcclLoader.addLogicalLib("testclasses");
083:
084: Class testClass = parentLoader.loadClass(this Class.getName());
085: return new PathableTestSuite(testClass, tcclLoader);
086: }
087:
088: /**
089: * Set up instance variables required by this test case.
090: */
091: public void setUp() throws Exception {
092: LogFactory.releaseAll();
093: }
094:
095: /**
096: * Tear down instance variables required by this test case.
097: */
098: public void tearDown() {
099: LogFactory.releaseAll();
100: }
101:
102: // ----------------------------------------------------------- Test Methods
103:
104: /**
105: * Verify that MyLog is only loadable via the tccl.
106: */
107: public void testLoader() throws Exception {
108:
109: ClassLoader this ClassLoader = this .getClass().getClassLoader();
110: ClassLoader tcclLoader = Thread.currentThread()
111: .getContextClassLoader();
112:
113: // the tccl loader should NOT be the same as the loader that loaded this test class.
114: assertNotSame("tccl not same as test classloader",
115: this ClassLoader, tcclLoader);
116:
117: // MyLog should not be loadable via parent loader
118: try {
119: Class clazz = this ClassLoader.loadClass(MY_LOG_IMPL);
120: fail("Unexpectedly able to load MyLog via test class classloader");
121: } catch (ClassNotFoundException ex) {
122: // ok, expected
123: }
124:
125: // MyLog should be loadable via tccl loader
126: try {
127: Class clazz = tcclLoader.loadClass(MY_LOG_IMPL);
128: } catch (ClassNotFoundException ex) {
129: fail("Unexpectedly unable to load MyLog via tccl classloader");
130: }
131: }
132:
133: /**
134: * Verify that the custom Log implementation which is only accessable
135: * via the TCCL has NOT been loaded. Because this is only accessable via the
136: * TCCL, and we've use a commons-logging.properties that disables TCCL loading,
137: * we should see the default Log rather than the custom one.
138: */
139: public void testTcclLoading() throws Exception {
140: LogFactory instance = LogFactory.getFactory();
141: assertEquals("Correct LogFactory loaded",
142: "org.apache.commons.logging.impl.LogFactoryImpl",
143: instance.getClass().getName());
144:
145: try {
146: Log log = instance.getLog("test");
147: fail("Unexpectedly succeeded in loading a custom Log class"
148: + " that is only accessable via the tccl.");
149: } catch (LogConfigurationException ex) {
150: // ok, expected
151: int index = ex.getMessage().indexOf(MY_LOG_IMPL);
152: assertTrue("MyLog not found", index >= 0);
153: }
154: }
155: }
|