KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > yagga > util > JarClassLoader


1 /*
2  * This file is part of MiniInstaller, a self installer builder for Java
3  * Copyright (C) 2002 Walter Gamba
4  * mailto:walter@yagga.net
5  * http://www.yagga.net/java/miniinstaller
6  *
7  * MiniInstaller is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * MiniInstaller is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  *
21  * As the time of writing, the GNU General Public Licene can be
22  * found at http://www.gnu.org/licenses/gpl.txt
23  *
24  */

25
26 package net.yagga.util;
27
28 import java.net.URL JavaDoc;
29 import java.net.URLClassLoader JavaDoc;
30 import java.net.JarURLConnection JavaDoc;
31 import java.lang.reflect.Method JavaDoc;
32 import java.lang.reflect.Modifier JavaDoc;
33 import java.lang.reflect.InvocationTargetException JavaDoc;
34 import java.util.jar.Attributes JavaDoc;
35 import java.io.IOException JavaDoc;
36 //import net.yagga.util.*;
37
import java.util.jar.*;
38 import java.util.*;
39 import java.io.*;
40 /**
41  * A class loader for loading jar files, both local and remote.
42  */

43 class JarClassLoader extends ClassLoader JavaDoc
44 {
45   private String JavaDoc jarFile;
46     private Hashtable htSizes=new Hashtable();
47
48   public JarClassLoader(String JavaDoc jarF) {
49     super();
50     this.jarFile = jarF;
51   }
52
53   /**
54   * Returns the name of the jar file main class, or null if
55   * no "Main-Class" manifest attributes was defined.
56   */

57   public String JavaDoc getMainClassName() throws IOException JavaDoc
58   {
59     JarFile jf=new JarFile(jarFile);
60     Manifest mf = jf.getManifest();
61     return mf != null ? mf.getMainAttributes().getValue(Attributes.Name.MAIN_CLASS) : null;
62   }
63
64   /**
65   * Invokes the application in this jar file given the name of the
66   * main class and an array of arguments. The class must define a
67   * static method "main" which takes an array of String arguemtns
68   * and is of return type "void".
69   */

70   public void invokeClass(String JavaDoc name, String JavaDoc[] args)
71   throws ClassNotFoundException JavaDoc,
72          NoSuchMethodException JavaDoc,
73          InvocationTargetException JavaDoc
74   {
75     Class JavaDoc c = loadClass(name);
76
77     //Ut.error("Class is "+c);
78
Method JavaDoc m = c.getMethod("main", new Class JavaDoc[] { args.getClass() });
79     //Ut.error("Method is "+m);
80
m.setAccessible(true);
81     int mods = m.getModifiers();
82     if (m.getReturnType() != void.class || !Modifier.isStatic(mods) ||
83       !Modifier.isPublic(mods)) {
84       throw new NoSuchMethodException JavaDoc("main");
85     }
86     try {
87       m.invoke(null, new Object JavaDoc[] { args });
88     } catch (IllegalAccessException JavaDoc e) {
89     // This should not happen, as we have disabled access checks
90
}
91   }
92
93
94   protected Class JavaDoc findClass(String JavaDoc className) throws ClassNotFoundException JavaDoc
95   {
96     String JavaDoc urlName=className.replace('.', '/') + ".class";
97     Ut.infoln("findClass1 :"+className);
98     byte[] b1=getClassFromJar(urlName);
99     try{
100       return defineClass(className,b1,0,b1.length);
101     }catch(ClassFormatError JavaDoc cfe){
102       Ut.error("'"+className+"':"+cfe);
103     }
104     return null;
105   }
106
107     private void initSizes()
108     {
109         try{
110       JarFile zf=new JarFile(jarFile);
111       Enumeration e=zf.entries();
112       while (e.hasMoreElements())
113       {
114         JarEntry ze=(JarEntry)e.nextElement();
115         htSizes.put(ze.getName(),new Integer JavaDoc((int)ze.getSize()));
116       }
117       zf.close();
118     }
119     catch(IOException JavaDoc ioe){
120       Ut.error("Error reading sizes in '"+jarFile+"':"+ioe);
121     }
122   }
123
124     public byte[] getClassFromJar(String JavaDoc cl)
125     {
126     initSizes();
127     try
128     {
129       // extract resources and put them into the hashtable.
130
JarInputStream zis=getJIS(jarFile);
131       JarEntry ze=null;
132       while ((ze=zis.getNextJarEntry())!=null)
133       {
134         if (ze.isDirectory())
135           continue;
136
137         int size=(int)ze.getSize();
138         if (size==-1)
139           size=((Integer JavaDoc)htSizes.get(ze.getName())).intValue();
140
141         if(ze.getName().equals(cl))
142         {
143           byte[] b=new byte[(int)size];
144           int rb=0;
145           int chunk=0;
146           while (((int)size - rb) > 0)
147           {
148             chunk=zis.read(b,rb,(int)size - rb);
149             if (chunk==-1)
150               break;
151             rb+=chunk;
152           }
153           return b;
154         }
155       }
156     }
157     catch (NullPointerException JavaDoc e) {
158       Ut.error("'"+jarFile+"':(done)"+e);
159     } catch (FileNotFoundException e) {
160       Ut.error("'"+jarFile+"':"+e);
161     } catch (IOException JavaDoc e) {
162       Ut.error("'"+jarFile+"':"+e);
163     }
164     return null;
165   }
166
167
168   private JarInputStream getJIS(String JavaDoc jarFile)
169   {
170     try{
171       InputStream is=ResourceMgr.openResource(jarFile);
172       return new JarInputStream(is);
173     }catch(IOException JavaDoc io){
174         Ut.error("IOE..."+io);
175     }
176     return null;
177   }
178
179   private InputStream openResource(String JavaDoc filename)
180     {
181         try
182         {
183       InputStream is=ResourceMgr.class.getResourceAsStream("/"+filename);
184       is.available();//to generate null ptr exceptio
185
return is;
186         }
187         catch (java.io.IOException JavaDoc e)
188         {
189             Ut.error("RM2: file not found:"+filename);
190             System.exit(1);
191         }
192         catch(NullPointerException JavaDoc e2){
193             Ut.error("RM2: file not found!"+filename);
194             System.exit(1);
195         }
196         return null;
197     }
198
199 }
200
201 /*********************
202  vecchia versione / old version
203 ***********************/

204 /*
205  class JarClassLoader extends URLClassLoader {
206     private URL url;
207
208     //pig-like thing: I store a second jarClassLoader in case I'm inquiring about a
209     //JAR inside a JAR file
210     private JarClassLoader2 jcl=null;
211     private File jarInJarFile=null;
212
213     public File getJarInJar(){
214       return jarInJarFile;
215     }
216     public JarClassLoader2(URL url) {
217         super(new URL[] { url });
218         this.url = url;
219     }
220
221     public String getMainClassName() throws IOException {
222
223       URL u=null;
224       if(url.getProtocol().equals("jar"))
225       {
226         //meta jar...
227         String main="";
228         try{
229         u=url;
230         //first.. decompress jar jar file in tmp dir
231         File tmp1=File.createTempFile("ttt",null);
232         String dir=tmp1.getParent();
233         //Ut.infoln("TMP dir is :"+dir);
234         //delete temp file...
235         tmp1.delete();
236
237         //write jar entry (the jar file) in temp dir
238         JarURLConnection uc = (JarURLConnection)u.openConnection();
239         //Ut.infoln("2 :");
240         String jarFile=uc.getJarFileURL().getFile();
241         //get resource...
242         JarEntry je=uc.getJarEntry();
243         //Ut.infoln("Jar entry is:"+je);
244
245         /////////////
246         ///////////////
247         //Ut.infoln("QUI!!");
248         //copy jar entry (a jar file itself!) into tmp dir!
249
250         InputStream is=ResourceMgr.openResource(je.getName());
251         jarInJarFile=new File(dir,je.getName());
252         FileOutputStream fout=new FileOutputStream(jarInJarFile.getCanonicalPath());
253         int c=0;
254         while((c=is.read())!=-1)
255           fout.write(c);
256         fout.close();
257         fout=null;
258         //Ut.infoln("written to:"+jarInJarFile.getCanonicalPath());
259
260
261         //now connect to it..
262         //
263         URL ur=jarInJarFile.toURL();//JarClassLoader.class.getResource("/"+tmp.getCanonicalPath());
264         jcl=new JarClassLoader(ur);
265         main=jcl.getMainClassName();
266         }
267         catch(Exception e){
268           Ut.error("Errore jarjar:"+e);
269         }
270         return main;
271       }
272       else{
273         u = new URL("jar", "", url + "!/");
274
275         //Ut.infoln("1)"+u);
276         JarURLConnection uc = (JarURLConnection)u.openConnection();
277         //Ut.infoln("2)"+uc.getJarFileURL());
278         Attributes attr = uc.getMainAttributes();
279         //Ut.infoln("3)");
280         return attr != null ? attr.getValue(Attributes.Name.MAIN_CLASS) : null;
281       }
282     }
283
284     public void invokeClass(String name, String[] args)
285         throws ClassNotFoundException,
286                NoSuchMethodException,
287                InvocationTargetException
288     {
289         if(jcl!=null){
290           jcl.invokeClass(name,args);
291           try{
292           Ut.infoln("deleting jarjarfle:"+jarInJarFile.delete());
293           jarInJarFile.deleteOnExit();
294           FilePermission fp=new FilePermission(jarInJarFile.getCanonicalPath(),"delete");
295           Ut.infoln("deleting is possible?:"+fp.getActions());
296
297           Ut.infoln("deleting jarjarfle:"+jarInJarFile.delete());
298           File f=new File(jarInJarFile.getCanonicalPath());
299           Ut.infoln("deleting jarjarfle2:"+f.delete());
300           f.deleteOnExit();
301
302           }catch(Exception e){
303             Ut.error("Exc deleting:"+e);
304           }
305           return;
306         }
307         Class c = loadClass(name);
308         Method m = c.getMethod("main", new Class[] { args.getClass() });
309         m.setAccessible(true);
310         int mods = m.getModifiers();
311         if (m.getReturnType() != void.class || !Modifier.isStatic(mods) ||
312             !Modifier.isPublic(mods)) {
313             throw new NoSuchMethodException("main");
314         }
315         try {
316             m.invoke(null, new Object[] { args });
317         } catch (IllegalAccessException e) {
318             // This should not happen, as we have disabled access checks
319         }
320     }
321
322     protected void finalize() throws Throwable{
323       super.finalize();
324       Ut.infoln("FINAL");
325       if(jarInJarFile!=null)
326           Ut.infoln("deleting jarjarfle:"+jarInJarFile.delete());
327     }
328 }
329 */

330
331
Popular Tags