1 package org.ibex.jinetd;
2 import org.ibex.util.*;
5 import java.util.zip.*;
7 /** represents a file or directory which is scanned for updates */
8 public class Loader extends Watcher {
10 public Loader(String path) { super(path); }
12 private TreeClassLoader classloader = new TreeClassLoader();
13 public ClassLoader getClassLoader() {
14 ClassLoader classloader = this.classloader;
15 if (classloader == null) {
16 classloader = this.classloader = new TreeClassLoader();
17 Log.warn(this, "getting classloader...");
20 } catch (Exception e) {
27 private void fill(Vec vec, File dir) {
28 if (!dir.exists()) return;
29 if (!dir.isDirectory()) {
30 if (!dir.getPath().endsWith(".java")) return;
31 vec.addElement(dir.getAbsolutePath());
33 String[] list = dir.list();
34 for(int i=0; i<list.length; i++)
35 fill(vec, new File(dir.getAbsolutePath() + File.separatorChar + list[i]));
38 private void compileSource() throws Exception {
39 File srcdir = new File(this.path + File.separatorChar + "SRC");
40 if (!srcdir.exists()) return;
41 if (new File("/usr/bin/jikes").exists()) {
42 File bindir = new File(this.path + File.separatorChar + "BIN"); bindir.mkdirs();
43 File libdir = new File(this.path + File.separatorChar + "LIB");
44 String classpath = System.getProperty("java.class.path");
45 String [] l = new File("/jinetd/LIB/").list();
46 for(int i=0; i<l.length; i++) {
47 if (!l[i].endsWith(".jar")) continue;
48 classpath += File.pathSeparatorChar;
49 classpath += "/jinetd/LIB/" + l[i];
51 String bootclasspath = System.getProperty("sun.boot.class.path", "");
53 args.addElement("/usr/bin/jikes");
54 args.addElement("+E");
55 args.addElement("-nowarn");
56 args.addElement("-bootclasspath");
57 args.addElement(bootclasspath);
58 args.addElement("-extdirs");
59 args.addElement(libdir.getAbsolutePath());
60 args.addElement("-classpath");
61 args.addElement(classpath);
62 args.addElement("-sourcepath");
63 args.addElement(srcdir.getAbsolutePath());
64 args.addElement("-d");
65 args.addElement(bindir.getAbsolutePath());
67 String[] all = new String[args.size()];
69 Log.info(this, "invoking jikes");
70 for(int i=0; i<all.length; i++) Log.info(this, " " + all[i]);
71 final Process jikes = Runtime.getRuntime().exec(all);
72 final BufferedReader out = new BufferedReader(new InputStreamReader(jikes.getInputStream()));
73 final BufferedReader err = new BufferedReader(new InputStreamReader(jikes.getErrorStream()));
74 new Thread() { public void run() {
75 try { for(String s = out.readLine(); s != null; s = out.readLine()) Log.info("jikes[stdout]", s); }
76 catch (Exception e) { Log.warn("jikes", e); } } }.start();
77 new Thread() { public void run() {
78 try { for(String s = err.readLine(); s != null; s = err.readLine()) Log.info("jikes[stderr]", s); }
79 catch (Exception e) { Log.warn("jikes", e); } } }.start();
82 Log.error(this, "ACK! jikes not found, javac not (yet) supported");
86 // only watch SRC and LIB for changes
87 public Watched slash(String path) {
88 return (path.equals("LIB") ||
91 path.endsWith(".jar") ) ? super.slash(path) : null; }
94 // dump the classloader if anything changes
95 public void changed(Watched w) {
96 if (w.path.indexOf("BIN") != -1) return;
97 if (classloader != null) {
98 Log.info(this, "Reloading all classes: " + path);
103 private class TreeClassLoader extends ClassLoader {
104 private Hashtable cache = new Hashtable();
106 private synchronized Class defineClass(String name) {
107 // first see if it's just sitting there
108 File classFile = slash("BIN").slash(name.replace('.', File.separatorChar) + ".class");
109 if (classFile.exists()) {
111 byte[] b = InputStreamToByteArray.convert(new FileInputStream(classFile));
112 Log.debug(this, " loading " + name + " from " + classFile.getAbsolutePath());
113 return defineClass(b, 0, b.length);
114 } catch (Exception e) {
119 // then scan the jarfiles for it
120 File lib = slash("LIB");
121 if (lib.exists() && lib.isDirectory()) {
123 String[] paths = lib.list();
124 for(int i=0; i<paths.length; i++) {
125 if (paths[i].endsWith(".jar")) {
126 File f = new File(getAbsolutePath()+File.separatorChar+"LIB"+File.separatorChar+paths[i]);
127 //Log.debug(this, " scanning " + f.getAbsolutePath());
128 ZipFile zf = new ZipFile(f);
129 ZipEntry ze = zf.getEntry(name.replace('.', File.separatorChar) + ".class");
131 byte[] b = InputStreamToByteArray.convert(zf.getInputStream(ze));
132 Log.debug(this, " loading " + name + " from " + f.getAbsolutePath());
133 return defineClass(b, 0, b.length);
137 } catch (Exception e) {
141 // finally scan ourselves
143 String[] paths = list();
144 for(int i=0; i<paths.length; i++) {
145 if (paths[i].endsWith(".jar")) {
146 File f = new File(getAbsolutePath()+File.separatorChar+paths[i]);
147 //Log.debug(this, " scanning " + f.getAbsolutePath());
148 ZipFile zf = new ZipFile(f);
149 ZipEntry ze = zf.getEntry(name.replace('.', File.separatorChar) + ".class");
151 byte[] b = InputStreamToByteArray.convert(zf.getInputStream(ze));
152 Log.debug(this, " loading " + name + " from " + f.getAbsolutePath());
153 return defineClass(b, 0, b.length);
157 } catch (Exception e) {
163 // finally, resort to compiling it if we have to
164 //File src = new File(getAbsolutePath() + File.separatorChar + "SRC");
166 //if (!sourcebuilt) buildSource();
170 public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
172 Class c = findSystemClass(name);
173 if (c != null) { if (resolve) resolveClass(c); return c; }
174 } catch (ClassNotFoundException e) { /* DELIBERATE */ }
175 Class c = (Class)cache.get(name);
177 //Log.info(this, "looking for class " + name);
178 c = defineClass(name);
179 if (c == null) throw new ClassNotFoundException();
182 if (resolve) resolveClass(c);