KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > planetamessenger > security > JJarClassLoader


1 /*
2     =========================================================================
3     Package security - Implements the security package.
4
5     This module is developed and maintained by PlanetaMessenger.org.
6     Specs, New and updated versions can be found in
7     http://www.planetamessenger.org
8     If you want contact the Team please send a email to Project Manager
9     Leidson Campos Alves Ferreira at leidson@planetamessenger.org
10
11     Copyright (C) since 2001 by PlanetaMessenger.org
12     
13     This library is free software; you can redistribute it and/or
14     modify it under the terms of the GNU Lesser General Public
15     License as published by the Free Software Foundation; either
16     version 2.1 of the License, or (at your option) any later version.
17
18     This library is distributed in the hope that it will be useful,
19     but WITHOUT ANY WARRANTY; without even the implied warranty of
20     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21     Lesser General Public License for more details.
22
23     You should have received a copy of the GNU Lesser General Public
24     License along with this library; if not, write to the Free Software
25     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26
27     =========================================================================
28 */

29 /**
30  *
31  * $Id: JJarClassLoader.java,v 1.11 2007/02/11 21:05:24 popolony2k Exp $
32  * $Author: popolony2k $
33  * $Name: $
34  * $Revision: 1.11 $
35  * $State: Exp $
36  *
37  */

38
39 package org.planetamessenger.security;
40
41 import org.planetamessenger.io.*;
42 import java.util.jar.*;
43 import java.util.*;
44 import java.io.*;
45 import java.net.*;
46
47
48 public class JJarClassLoader extends java.lang.ClassLoader JavaDoc {
49   
50   private final java.lang.String JavaDoc SUFFIX_CLASS = ".class";
51
52   private JarFile jarFile = null;
53   private Manifest manifest = null;
54   private HashMap<String JavaDoc, String JavaDoc> depList = null;
55
56
57   /**
58    * Create a class loader that will
59    * read the files from the supplied zip/jar
60    * file.
61    */

62   public JJarClassLoader() {
63     
64     this( java.lang.ClassLoader.getSystemClassLoader() );
65   }
66   
67   /**
68    * Create a class loader that will
69    * read the files from the supplied zip/jar
70    * file.
71    * @param parent The parent classLoader;
72    */

73   public JJarClassLoader( java.lang.ClassLoader JavaDoc parent ) {
74     
75     super( parent );
76     
77     depList = new HashMap<String JavaDoc, String JavaDoc>();
78   }
79
80   /**
81    * Create a class loader that will read the files
82    * from the supplied zip/jar file
83    * @param strJarFile The Jar file that will be loaded;
84    * @param bLoadIt Loads the entire jar content flag;
85    * true - Open and load the jar;
86    * false - Only open the jar;
87    */

88   public JJarClassLoader( String JavaDoc strJarFile, boolean bLoadIt ) throws JarException {
89     
90     this();
91     
92     try {
93       open( strJarFile );
94       
95       if( bLoadIt )
96         if( !load() )
97           throw new JarException( "JJarClassLoader() - Exception in jar " + strJarFile + " file. The jar content could not be loaded" );
98     } catch( java.util.jar.JarException JavaDoc e ) {
99       throw new JarException( "JJarClassLoader() - Exception in jar " + strJarFile + " file " + e );
100     }
101   }
102
103   /**
104    * Add a class path object to this ClassLoder.
105    * @param classPath The class path object that will
106    * be added to this class;
107    */

108   public void addDependency( String JavaDoc strJarFile ) {
109     
110     if( !depList.containsKey( strJarFile ) )
111       depList.put( strJarFile, strJarFile );
112   }
113   
114   /**
115    * Gets a manifest file from
116    * specified jar.
117    * @param strJarFile The jar file that manifest
118    * will be retrieved;
119    */

120   public synchronized Manifest getManifestFromFile( String JavaDoc strJarFile ) throws JarException {
121
122     try {
123       
124       JarFile tmpJarFile = new JarFile( strJarFile );
125       return tmpJarFile.getManifest();
126       
127     } catch( java.io.IOException JavaDoc e ) {
128       throw new JarException( "JJarClassLoader.getManifestFromFile() - Exception in jar " + strJarFile + " file " + e );
129     }
130   }
131
132   /**
133    * open a specified Jar file.
134    * @param strJarFile The jar that will be loaded;
135    */

136   public synchronized void open( String JavaDoc strJarFile ) throws JarException {
137     
138     try {
139       close();
140       jarFile = new JarFile( strJarFile );
141       manifest = jarFile.getManifest();
142     } catch( java.io.IOException JavaDoc e ) {
143       throw new JarException( "JJarClassLoader.open() - Exception in jar " + strJarFile + " file " + e );
144     }
145   }
146
147   /**
148    * closes the Jar file.
149    */

150   public synchronized void close() throws JarException {
151     
152     try {
153       if( jarFile != null ) {
154         jarFile.close();
155         jarFile = null;
156         manifest = null;
157       }
158     } catch( java.io.IOException JavaDoc e ) {
159       throw new JarException( "JJarClassLoader.close() - " + e );
160     }
161   }
162
163   /**
164    * Load the entire content of jar to
165    * the system.
166    */

167   public synchronized boolean load() {
168     
169     if( jarFile != null ) {
170       java.util.Enumeration JavaDoc entries = jarFile.entries();
171       java.lang.String JavaDoc strName;
172     
173     
174       while( entries.hasMoreElements() ) {
175     
176         strName = ( ( JarEntry ) entries.nextElement() ).getName();
177
178         try {
179         
180           if( strName.endsWith( SUFFIX_CLASS ) )
181             loadClass( strName, true );
182
183         } catch( java.lang.ClassNotFoundException JavaDoc e ) {
184           System.err.println( "JJarClassLoader.load() - " + e );
185           return false;
186         }
187       }
188     
189       return true;
190     }
191     
192     return false;
193   }
194
195   /**
196    * Returns the manifest of this jar file
197    */

198   public Manifest getManifest() {
199     
200     return manifest;
201   }
202
203   /**
204    * Get the resource following the first JJarClassLoader rule.
205    * 1) Main jar file;
206    * @param strResName The Resource that will be retrived;
207    */

208   public URL getResource( String JavaDoc strResName ) {
209
210     try {
211       URL url = new URL( "jar:file:" + jarFile.getName() + "!/" + strResName );
212
213       return url;
214     } catch( MalformedURLException e ) {
215       System.err.println( "JJarClassloader.getResource() - " + e );
216       return null;
217     }
218   }
219   
220   /**
221    * Get the resource following the
222    * JJarClassLoader rules.
223    * 1) Main jar file;
224    * 2) Dependency libraries;
225    * 3) The parent ClassLoader
226    * 4) The System ClassLoader;
227    * @param strResName The Resource that will be retrived;
228    */

229   public InputStream getResourceAsStream( String JavaDoc strResName ) {
230     
231     System.err.println( "JJarClassLoader.getResourceAsStream() - Getting " + strResName );
232     
233     InputStream inStream = null;
234
235     
236     try {
237
238       JarEntry jarEntry = ( jarFile != null ? jarFile.getJarEntry( strResName ) : null );
239       
240       // Try the main jar file
241
if( jarEntry != null )
242         inStream = jarFile.getInputStream( jarEntry );
243       else {
244         
245         JarFile tmpJarFile = null;
246         java.lang.Object JavaDoc depArray[] = depList.values().toArray();
247         
248         
249         // Try to get in Dependency list
250
for( int nCount = 0; nCount < depArray.length; nCount++ ) {
251           try {
252             tmpJarFile = new JarFile( ( String JavaDoc ) depArray[nCount] );
253             jarEntry = tmpJarFile.getJarEntry( strResName );
254             
255             if( jarEntry != null ) {
256               inStream = tmpJarFile.getInputStream( jarEntry );
257               break;
258             }
259           } catch( java.io.IOException JavaDoc ioe ) {
260             System.err.println( "JJarClassLoader.getResourceAsStream() - " + ioe );
261           }
262         }
263
264         // Try the parent ClassLoader
265
if( inStream == null ) {
266           ClassLoader JavaDoc parent = getParent();
267         
268           if( parent != null )
269             inStream = parent.getResourceAsStream( strResName );
270           
271           // Try the System ClassLoader
272
if( inStream == null )
273             inStream = java.lang.ClassLoader.getSystemClassLoader().getResourceAsStream( strResName );
274         }
275       }
276     } catch( IOException e ) {
277       System.err.println( "JJarClassLoader.getResourceAsStream() - " + e );
278     }
279
280    return inStream;
281   }
282   
283   /**
284    * Replaces the class name from path/filename to
285    * dot separated class naming.
286    * @param strClassName The class name that will be
287    * replaced;
288    */

289   protected String JavaDoc replaceClassName( String JavaDoc strClassName ) {
290
291     int nLastIndex = strClassName.indexOf( SUFFIX_CLASS );
292
293     
294     if( nLastIndex < 0 )
295       return strClassName;
296     
297     java.lang.String JavaDoc strNewClassName = strClassName.substring( 0, nLastIndex );
298     
299     if( strNewClassName.indexOf( '/' ) >= 0 )
300       return strNewClassName.replace( '/', '.' );
301     else
302       if( strNewClassName.indexOf( '\\' ) >= 0 )
303         return strNewClassName.replace( '\\', '.' );
304       else
305         return strClassName;
306   }
307
308   /**
309    * Get a JarEntry object specifying the
310    * object entry in Jar file.
311    * @param strClassName The class name that will
312    * be returned (name dotted);
313    */

314   protected String JavaDoc replaceDottedName( String JavaDoc strClassName ) {
315
316     int nDotPos = strClassName.indexOf( '.' );
317
318     
319     if( nDotPos < 0 )
320       return strClassName;
321     
322     java.lang.String JavaDoc strClassEntry = strClassName.replace( '.', '/' ) + SUFFIX_CLASS;
323     
324     return strClassEntry;
325   }
326
327   /**
328    * Override the dfault findClass to find
329    * a class implementation.
330    *
331    * The search rule for requested class:
332    * 1) Dependency libraries;
333    * 2) Main jar file;
334    * 3) System class loader;
335    * 4) Parent class loader;
336    *
337    * @param See JDK java.lang.Class for help;
338    */

339   protected Class JavaDoc findClass( String JavaDoc strName ) throws ClassNotFoundException JavaDoc {
340
341     java.io.InputStream JavaDoc inStream = null;
342     JarEntry jarEntry = null;
343     JarFile tmpJarFile = null;
344     java.lang.Class JavaDoc theClass = null;
345
346     
347
348     strName = replaceClassName( strName );
349     theClass = findLoadedClass( strName );
350     
351     System.err.println( "JJarClassLoader.findClass() - " + strName + ( ( theClass == null ) ? " not " : " " ) + " in cache" );
352     
353     // The class was not found in cache
354
if( theClass == null ) {
355
356       // Try to get in Dependency list
357
java.lang.Object JavaDoc depArray[] = depList.values().toArray();
358           
359           
360       for( int nCount = 0; nCount < depArray.length; nCount++ ) {
361         try {
362           tmpJarFile = new JarFile( ( String JavaDoc ) depArray[nCount] );
363           jarEntry = tmpJarFile.getJarEntry( replaceDottedName( strName ) );
364             
365           if( jarEntry != null ) {
366             inStream = tmpJarFile.getInputStream( jarEntry );
367             break;
368           }
369           
370         } catch( java.io.IOException JavaDoc ioe ) {
371           System.err.println( "JJarClassLoader.findClass.findSystemClass() - " + ioe );
372         }
373       }
374
375       // Try the main jar file
376
if( jarEntry == null ) {
377         // Try to get from main jar file
378
jarEntry = ( jarFile != null ? jarFile.getJarEntry( replaceDottedName( strName ) ) : null );
379
380         if( jarEntry != null ) {
381           try {
382             inStream = jarFile.getInputStream( jarEntry );
383           } catch( java.io.IOException JavaDoc ioe ) {
384             System.err.println( "JJarClassLoader.findClass.findSystemClass() - " + ioe );
385             throw new ClassNotFoundException JavaDoc( strName );
386           }
387         }
388       }
389
390       if( jarEntry == null ) {
391         ClassLoader JavaDoc parent = getParent();
392
393         // Try the system ClassLoader
394
try {
395           return findSystemClass( strName );
396         } catch( java.lang.NoClassDefFoundError JavaDoc nce ) {
397           System.err.println( "JJarClassLoader.findClass.findSystemClass() - " + nce );
398
399           // Try the parent ClassLoader
400
if( parent != null ) {
401             try {
402               return parent.loadClass( strName );
403             } catch( java.lang.ClassNotFoundException JavaDoc e ) {
404               System.err.println( "JJarClassLoader.findClass.loadClass() - " + e );
405               throw new ClassNotFoundException JavaDoc( strName );
406             }
407           }
408         }
409       }
410
411       // Try get the class content from Jar file
412
try {
413         int nLen = ( int ) jarEntry.getSize();
414         byte byteCodes[] = new byte[nLen];
415         int nOffset = 0;
416         int nLoaded = 0;
417         
418
419         while( nLoaded < nLen ) {
420           nLen-=nLoaded;
421           nOffset+=nLoaded;
422           
423           nLoaded = inStream.read( byteCodes, nOffset, nLen );
424           
425           if( nLoaded == -1 ) {
426             inStream.close();
427             throw new java.lang.ClassNotFoundException JavaDoc( strName );
428           }
429         }
430         
431         inStream.close();
432         
433         // CLoses all temporary Jar files
434
if( tmpJarFile != null ) {
435           tmpJarFile.close();
436           tmpJarFile = null;
437         }
438         
439         try {
440           theClass = defineClass( strName, byteCodes, 0, byteCodes.length );
441         } catch( java.lang.ClassFormatError JavaDoc e ) {
442           System.err.println( "JJarClassLoader.findClass.defineClass() - " + e );
443         }
444
445       } catch( java.io.IOException JavaDoc e ) {
446         System.err.println( "JJarClassLoader.findClass.getInputStream - " + e );
447         theClass = null;
448       }
449     }
450
451     if( theClass == null )
452       throw new ClassNotFoundException JavaDoc( strName );
453     else
454       return theClass;
455   }
456 }
457
458 // JJarClassLoader class
Popular Tags