import java.io.File; import java.io.InputStream; import java.io.FileOutputStream; import java.util.StringTokenizer; import java.util.zip.ZipFile; import java.util.zip.ZipEntry; import java.lang.reflect.Method; public class Boot { public static String bootFile = null; public static String findInPath(String path, String fn) { StringTokenizer st = new StringTokenizer(path, File.pathSeparator); while (st.hasMoreTokens()) { String dirname=st.nextToken(); try { File f = new File(dirname+File.separator+fn); if (f.isFile()) return f.getPath(); } catch (Exception fex) {} } return null; } public static String findNativeLibrary(String basename, boolean internalFirst) { String libName = "lib"+basename; String ext = ".so"; String os = System.getProperty("os.name"); if (os.startsWith("Win")) { os = "Win"; ext= ".dll"; libName=basename; } if (os.startsWith("Mac")) { os = "Mac"; ext= ".jnilib"; } String fullName = libName+ext; // first, try the system path unless instructed otherwise if (!internalFirst) { try { String r = findInPath("."+File.pathSeparator+System.getProperty("java.library.path"), fullName); if (r != null) return r; } catch (Exception ex1) {} } // second, try to locate in on the class path (in the JAR file or in one of the directories) String cp = System.getProperty("java.class.path"); StringTokenizer st = new StringTokenizer(cp, File.pathSeparator); while (st.hasMoreTokens()) { String dirname=st.nextToken(); try { File f = new File(dirname); if (f.isFile()) { // look in a JAR file and extract it if necessary ZipFile jf = new ZipFile(f); ZipEntry ze = jf.getEntry(fullName); if (ze != null) { // found it inside a JAR file try { bootFile = f.toString(); File tf = File.createTempFile(basename,ext); System.out.println("Boot.findNativeLibrary: found in a JAR ("+jf+"), extracting into "+tf); InputStream zis = jf.getInputStream(ze); FileOutputStream fos = new FileOutputStream(tf); byte b[] = new byte[65536]; while (zis.available()>0) { int n = zis.read(b); if (n>0) fos.write(b, 0, n); } zis.close(); fos.close(); tf.deleteOnExit(); return tf.getPath(); } catch (Exception foo) { } } } else if (f.isDirectory()) { File ff = new File(dirname+File.separator+fullName); if (ff.isFile()) return ff.getPath(); } } catch(Exception ex2) {} } // third, try the system path if we didn't look there before if (internalFirst) { try { String r = findInPath("."+File.pathSeparator+System.getProperty("java.library.path"), fullName); if (r != null) return r; } catch (Exception ex3) {} } return null; } public static void main(String[] args) { // 1) instantiate master class loader JRIClassLoader mcl = JRIClassLoader.getMainLoader(); // 2) locate boot JNI library String nl = findNativeLibrary("boot", false); if (nl == null) { System.err.println("ERROR: Unable to locate native bootstrap library."); System.exit(1); } // register boot library with MCL mcl.registerLibrary("boot", new File(nl)); // add path necessary for loading JRIBootstrap to MCL String cp = System.getProperty("java.class.path"); StringTokenizer st = new StringTokenizer(cp, File.pathSeparator); while (st.hasMoreTokens()) { String p = st.nextToken(); mcl.addClassPath(p); // we assume that the first file on the CP is us (FIXME: verify this!) if (bootFile==null && (new File(p)).isFile()) bootFile=p; } // call static bootstrap method try { // force the use of the MCL even if the system loader could find it Class stage2class = mcl.findAndLinkClass("JRIBootstrap"); Method m = stage2class.getMethod("bootstrap", new Class[] { String[].class }); m.invoke(null, new Object[] { args }); } catch (Exception rtx) { System.err.println("ERROR: Unable to invoke bootstrap method in JRIBootstrap! ("+rtx+")"); rtx.printStackTrace(); System.exit(2); } } }