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 }