1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */ 
16  package org.apache.commons.logging;
17  
18  import junit.framework.Test;
19  import junit.framework.TestCase;
20  import junit.framework.TestSuite;
21  
22  /***
23   * testcase to emulate container and application isolated from container
24   * @author  baliuka
25   * @version $Id: LoadTest.java,v 1.5 2004/02/28 21:46:45 craigmcc Exp $
26   */
27  public class LoadTest extends TestCase{
28      //TODO: need some way to add service provider packages
29      static private String LOG_PCKG[] = {"org.apache.commons.logging",
30                                          "org.apache.commons.logging.impl"};
31      
32      static class AppClassLoader extends ClassLoader{
33          
34          java.util.Map classes = new java.util.HashMap();
35          
36          AppClassLoader(ClassLoader parent){
37              super(parent);
38          }
39          
40          private Class def(String name)throws ClassNotFoundException{
41              
42              Class result = (Class)classes.get(name);
43              if(result != null){
44                  return result;
45              }
46              
47              try{
48                  
49                  java.io.InputStream is = this.getClass().getClassLoader().
50                  getResourceAsStream( name.replace('.','//') + ".class" );
51                  java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
52                  
53                  while(is.available() > 0){
54                      out.write(is.read());
55                  }
56                  
57                  byte data [] = out.toByteArray();
58                  
59                  result = super.defineClass(name, data, 0, data.length );
60                  classes.put(name,result);
61                  
62                  return result;
63                  
64              }catch(java.io.IOException ioe){
65                  
66                  throw new ClassNotFoundException( name + " caused by "
67                  + ioe.getMessage() );
68              }
69              
70              
71          }
72          
73          // not very trivial to emulate we must implement "findClass",
74          // but it will delegete to junit class loder first
75          public Class loadClass(String name)throws ClassNotFoundException{
76              
77              //isolates all logging classes, application in the same classloader too.
78              //filters exeptions to simlify handling in test
79              for(int i = 0; i < LOG_PCKG.length; i++ ){
80                  if( name.startsWith( LOG_PCKG[i] ) &&
81                  name.indexOf("Exception") == -1   ){
82                      return def(name);
83                  }
84              }
85              return super.loadClass(name);
86          }
87          
88      }
89      
90      
91      
92      public void testInContainer()throws Exception{
93          
94          //problem can be in this step (broken app container or missconfiguration)
95          //1.  Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
96          //2.  Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
97          // we expect this :
98          // 1. Thread.currentThread().setContextClassLoader(appLoader);
99          // 2. Thread.currentThread().setContextClassLoader(null);
100         
101         Class cls = reload();
102         Thread.currentThread().setContextClassLoader(cls.getClassLoader());
103         execute(cls);
104         
105         cls = reload();
106         Thread.currentThread().setContextClassLoader(null);
107         execute(cls);
108         
109         
110         cls = reload();
111         Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
112         try{
113             execute(cls);
114             fail("SystemClassLoader");
115         }catch( LogConfigurationException ok ){
116             
117         }
118         
119         
120         cls = reload();
121         Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
122         try{
123             execute(cls);
124             fail("ContainerClassLoader");
125         }catch( LogConfigurationException ok ){
126             
127         }
128         
129     }
130     
131     private Class reload()throws Exception{
132         
133         Class testObjCls = null;
134         
135         AppClassLoader appLoader = new AppClassLoader( this.getClass().
136         getClassLoader()
137         
138         );
139         try{
140             
141             testObjCls = appLoader.loadClass(UserClass.class.getName());
142             
143         }catch(ClassNotFoundException cnfe){
144             throw cnfe;
145         }catch(Throwable t){
146             t.printStackTrace();
147             fail("AppClassLoader failed ");
148         }
149         
150         assertTrue( "app isolated" ,testObjCls.getClassLoader() == appLoader );
151         
152         
153         return testObjCls;
154         
155         
156     }
157     
158     
159     private void execute(Class cls)throws Exception{
160             
161             cls.newInstance();
162         
163     }
164     
165     
166     
167     /*** Creates a new instance of LoadTest */
168     public LoadTest(String testName) {
169         super(testName);
170     }
171     
172     
173     
174     
175     public static void main(String[] args){
176         String[] testCaseName = { LoadTest.class.getName() };
177         junit.textui.TestRunner.main(testCaseName);
178     }
179     
180     public static Test suite() {
181         TestSuite suite = new TestSuite();
182         
183         suite.addTestSuite(LoadTest.class);
184         
185         return suite;
186     }
187     
188 }