[MOBY-guts] biomoby commit

Paul Gordon gordonp at dev.open-bio.org
Wed Nov 1 23:45:36 UTC 2006


gordonp
Wed Nov  1 18:45:36 EST 2006
Update of /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/util
In directory dev.open-bio.org:/tmp/cvs-serv896/src/main/ca/ucalgary/seahawk/util

Modified Files:
	MinJarMaker.java 
Log Message:
Changes to allow the ClassLoader to extract classes from JARs in the minnow classpath variable
moby-live/Java/src/main/ca/ucalgary/seahawk/util MinJarMaker.java,1.1,1.2
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/util/MinJarMaker.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/util/MinJarMaker.java	2006/10/30 15:56:19	1.1
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/util/MinJarMaker.java	2006/11/01 23:45:36	1.2
@@ -45,7 +45,7 @@
 
     // For the class loading interface, keep track of what we've loaded
     private Set loadedClasses =
-      Collections.synchronizedSet( new HashSet() );
+      Collections.synchronizedSet( new LinkedHashSet() );
 
     static public void main( String args[] ) throws Exception {
 	// Check arguments
@@ -254,6 +254,11 @@
     }
     
     static protected String truncateURL(URL fullURL){
+	int jarSpecIndex = fullURL.toString().indexOf("!/");
+	if(jarSpecIndex != -1){
+	    return fullURL.toString().substring(jarSpecIndex+2);
+	}
+
 	StringTokenizer classPathTokens = new StringTokenizer(System.getProperty("jarmaker.class.path"), File.pathSeparator);
 	while(classPathTokens.hasMoreElements()){
 	    String classPathElement = classPathTokens.nextToken();
@@ -273,49 +278,86 @@
 	return null;
     }
     
-    protected String classToPath( String name ) {
+    protected byte[] getClassBytes( String name ) throws IOException {
 	// Check all of the run-time specified class path dirs for the 
 	// class file in question
-	StringTokenizer classPathTokens = new StringTokenizer(System.getProperty("jarmaker.class.path"), File.pathSeparator);
+	StringTokenizer classPathTokens = new StringTokenizer(System.getProperty("jarmaker.class.path"), 
+							      File.pathSeparator);
 	while(classPathTokens.hasMoreElements()){
-	    String path = classPathTokens.nextToken() + File.separator + name.replace( '.', File.separatorChar);
-	    path += ".class";
+	    String pathElement = classPathTokens.nextToken();
+	    // Turn package.class name into a relative path of a class resource
+	    String pathSuffix = name.replace('.', File.separatorChar) + ".class";
+	    String path = pathElement + File.separator + pathSuffix;
 	    File classFile = new File(path);
-	    if(classFile.exists()){
-		return path;
+	    if(classFile.isFile()){
+		long len = classFile.length();
+		byte data[] = new byte[(int)len];
+		FileInputStream fin = new FileInputStream(classFile);
+		int r = fin.read(data);
+		if (r != len){
+		    throw new IOException( "Could only read "+r+" of "+len+" bytes from "+classFile );
+		}
+		fin.close();
+		return data;
+	    }
+	    else{
+		// If it's not a file, maybe it's in a JAR
+		File f = new File(pathElement);
+		if(f.isFile()){
+		    JarFile jarFile = null;
+		    try{
+			jarFile = new JarFile(f);
+		    }
+		    catch(Exception e){
+			System.err.println("Class path element " + pathElement + 
+					   " was not a directory, or a valid JAR file");
+			continue;
+		    }
+
+		    JarEntry je = jarFile.getJarEntry(pathSuffix);
+		    if(je == null){
+			continue;
+		    }
+		    long classSize = je.getSize();
+
+		    InputStream classStream = jarFile.getInputStream(je);
+		    byte[] classBytes = null;
+		    if(classSize != -1){ // We know the size of the class already
+
+			classBytes = new byte[(int) classSize]; //classes better not be bigger than 2 GB!
+			// Slurp it up in one shot
+			classStream.read(classBytes, 0, (int) classSize); 
+			return classBytes;
+		    }
+		    else{
+
+			byte[] byteBufferChunk = new byte[1024];
+			ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
+			for(int r = classStream.read(byteBufferChunk, 0, 1024);
+			    r != -1; 
+			    r = classStream.read(byteBufferChunk, 0, 1024)){
+			    byteBuffer.write(byteBufferChunk, 0, r);
+			}
+			return byteBuffer.toByteArray();
+		    }
+		}
+		
 	    }
 	}
 	
 	return null; 
     }
     
-   protected byte[] readFile( String filename ) throws IOException {
-	File file = new File( filename );
-	long len = file.length();
-	byte data[] = new byte[(int)len];
-	FileInputStream fin = new FileInputStream( file );
-	int r = fin.read( data );
-	if (r != len)
-	throw new IOException( "Could only read "+r+" of "+len+" bytes from "+file );
-	fin.close();
-	return data;
-    }
-    
-    protected byte[] getClassBytes( String name ) throws IOException {
-	String path = classToPath( name );
-	if(path == null)
-	return null;
-	return readFile( path );
-    }
-    
-     protected URL getResourceURL(String name){
+    protected URL getResourceURL(String name){
 	// Check all of the run-time specified class path dirs for the 
 	// properties file in question
-	StringTokenizer classPathTokens = new StringTokenizer(System.getProperty("jarmaker.class.path"), File.pathSeparator);
+	StringTokenizer classPathTokens = new StringTokenizer(System.getProperty("jarmaker.class.path"), 
+							      File.pathSeparator);
 	while(classPathTokens.hasMoreElements()){
-	    String path = classPathTokens.nextToken() + File.separator + name;
+	    String pathElement = classPathTokens.nextToken();
+	    String path = pathElement + File.separator + name;
 	    File resourceFile = new File(path);
-	    if(resourceFile.exists()){
+	    if(resourceFile.isFile()){
 		try{
 		    return resourceFile.toURL();
 		}
@@ -324,6 +366,43 @@
 				       path + " as URL, but could not: " + e);
 		}
 	    }
+	    else{
+		// If it's not a file, maybe it's in a JAR
+		File f = new File(pathElement);
+		if(f.isFile()){
+		    JarFile jarFile = null;
+		    try{
+			jarFile = new JarFile(f);
+		    }
+		    catch(Exception e){
+			System.err.println("Class path element " + pathElement + 
+					   " was not a directory, or a valid JAR file");
+			continue;
+		    }
+
+		    JarEntry je = jarFile.getJarEntry(name);
+		    try{
+			jarFile.close();
+		    }
+		    catch(IOException ioe){
+			System.err.println("Couldn't close JAR file: " + pathElement);
+		    }
+		    if(je == null){
+			continue;
+		    }
+		    else{
+			try{
+			    return new URL("jar:"+f.toURL().toString()+"!/"+name);
+			} catch(java.net.MalformedURLException murle){
+			    try{
+				System.err.println("URL jar:"+f.toURL().toString()+"!"+name + 
+						   " was invalid: " +murle);}catch(Exception e){}
+			    return null;
+			}
+		    }
+		}
+				
+	    }
 	}
 	return null;
     }
@@ -341,6 +420,11 @@
 	}
     }
     
+    protected void copyFile( OutputStream out, byte[] buffer )
+	throws IOException {	
+	out.write(buffer);
+    }
+    
     protected void copyFile( OutputStream out, String infile )
 	throws IOException {
 	FileInputStream fin = new FileInputStream( infile );
@@ -400,11 +484,11 @@
 		    }
 		}
 
-		// Store the class
-		String path = classToPath( classname );
+		// Store the class, TODO: be updated since JAR class origins allowed
+		byte[] classBytes = getClassBytes(classname);
                 String relativePath = null;
-                if(path != null){ // Found it
-                  relativePath = truncatePath(path);
+                if(classBytes != null){ // Found it
+                  relativePath = classname.replaceAll("\\.", File.separator)+".class";
                   if(savedClasses.containsKey(relativePath)){
                     continue;  //already saved
                   }
@@ -412,14 +496,18 @@
 		  //System.out.println( "Adding class "+path );
 		  JarEntry je = new JarEntry(relativePath);
 		  jout.putNextEntry( je );
-		  copyFile( jout, path );
+		  copyFile(jout, classBytes);
 		  jout.closeEntry();
                 }
                 else {  // A resource, not a class?
                   java.net.URL resourceURL = getResourceURL(classname);
                   if(resourceURL != null){
                     relativePath = truncateURL(resourceURL);
-                    if(savedClasses.containsKey(relativePath)){
+		    if(relativePath == null){
+			System.err.println("Could not create relative path for "+ resourceURL + ", excluding from JAR");
+			continue;
+		    }
+                    else if(savedClasses.containsKey(relativePath)){
                       continue;  //already saved
                     }
 
@@ -430,7 +518,7 @@
 		    jout.closeEntry();
                   }
                   else{
-                    System.err.println("Warning: Could not find class or resource file for " + classname);
+                    System.err.println("Warning: Could not find class or resource file for " + classname + ", excluding from JAR" );
                     continue;
                   }
                 }




More information about the MOBY-guts mailing list