1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.commons.logging.tccl.logfactory;
19
20
21 import java.net.URL;
22
23 import junit.framework.Test;
24 import junit.framework.TestCase;
25
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.commons.logging.PathableClassLoader;
28 import org.apache.commons.logging.PathableTestSuite;
29
30
31 /**
32 * Verify that by default a custom LogFactoryImpl is loaded from the
33 * tccl classloader.
34 */
35
36 public class TcclEnabledTestCase extends TestCase {
37
38 // ------------------------------------------- JUnit Infrastructure Methods
39
40
41 /**
42 * Return the tests included in this test suite.
43 */
44 public static Test suite() throws Exception {
45 Class thisClass = TcclEnabledTestCase.class;
46
47 // Determine the URL to this .class file, so that we can then
48 // append the priority dirs to it. For tidiness, load this
49 // class through a dummy loader though this is not absolutely
50 // necessary...
51 PathableClassLoader dummy = new PathableClassLoader(null);
52 dummy.useExplicitLoader("junit.", Test.class.getClassLoader());
53 dummy.addLogicalLib("testclasses");
54 dummy.addLogicalLib("commons-logging");
55
56 String thisClassPath = thisClass.getName().replace('.', '/') + ".class";
57 URL baseUrl = dummy.findResource(thisClassPath);
58
59 // Now set up the desired classloader hierarchy. Everything goes into
60 // the parent classpath, but we exclude the custom LogFactoryImpl
61 // class.
62 //
63 // We then create a tccl classloader that can see the custom
64 // LogFactory class. Therefore if that class can be found, then the
65 // TCCL must have been used to load it.
66 PathableClassLoader emptyLoader = new PathableClassLoader(null);
67
68 PathableClassLoader parentLoader = new PathableClassLoader(null);
69 parentLoader.useExplicitLoader("junit.", Test.class.getClassLoader());
70 parentLoader.addLogicalLib("commons-logging");
71 parentLoader.addLogicalLib("testclasses");
72 // hack to ensure that the testcase classloader can't see
73 // the cust MyLogFactoryImpl
74 parentLoader.useExplicitLoader(
75 "org.apache.commons.logging.tccl.custom.", emptyLoader);
76
77 URL propsEnableUrl = new URL(baseUrl, "props_enable_tccl/");
78 parentLoader.addURL(propsEnableUrl);
79
80 PathableClassLoader tcclLoader = new PathableClassLoader(parentLoader);
81 tcclLoader.addLogicalLib("testclasses");
82
83 Class testClass = parentLoader.loadClass(thisClass.getName());
84 return new PathableTestSuite(testClass, tcclLoader);
85 }
86
87 /**
88 * Set up instance variables required by this test case.
89 */
90 public void setUp() throws Exception {
91 LogFactory.releaseAll();
92 }
93
94 /**
95 * Tear down instance variables required by this test case.
96 */
97 public void tearDown() {
98 LogFactory.releaseAll();
99 }
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 }