[MOBY-guts] biomoby commit

Paul Gordon gordonp at dev.open-bio.org
Thu Feb 3 22:03:23 UTC 2011


gordonp
Thu Feb  3 17:03:23 EST 2011
Update of /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/util
In directory dev.open-bio.org:/tmp/cvs-serv21432/src/main/ca/ucalgary/util

Modified Files:
	SingletonApplication.java 
Log Message:
Added support for jar-based app launching
moby-live/Java/src/main/ca/ucalgary/util SingletonApplication.java,1.1,1.2
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/util/SingletonApplication.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/util/SingletonApplication.java	2010/05/19 17:38:56	1.1
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/util/SingletonApplication.java	2011/02/03 22:03:23	1.2
@@ -12,26 +12,48 @@
  * Utility to launch a Java application if not running, or pass a new file for 
  * opening if the app is already open (per user).  To use this class, call it as your 
  * main class, and pass the real main class name as the first argument.  Subsequent 
- * arguments are passed to the real main class's main(argv) method.
+ * arguments are passed to the real main class's main(argv) method.  If you are
+ * launching the app using the java -jar myapp.jar technique, you should define 
+ * this class as thr Main-Class in <code>META-INF/MANIFEST.MF</code>, and specify your app's main class
+ * in the file <code>META-INF/services/ca.ucalgary.util.SingletonApplication</code>.
+ *
+ * The modifications required to the atrget application are as follows:
+ * <ol><li>Call the static method SingletonApplication.setArgumentListener(ArgumentListener) 
+ *         in your app's static void main() method.</li>
+ *     <li>Have whatever class that opens files/URLs/etc in your app implement the method 
+ *          processArgument(String), and hence the interface ArgumentListener.</li></ol>
+ *
+ * @author Paul Gordon (gordonp at ucagary.ca)
  */
 public class SingletonApplication{
     private static ListenerThread listenerThread;
 
     public static void main(String[] args){
-        if(args.length == 0 || args[0].matches("-{1,2}(h(elp)?)?")){
+        if(args.length > 0 && args[0].matches("-{1,2}(h(elp)?)?")){
 	    System.err.println("Usage: java "+SingletonApplication.class.getName()+
 			       " <main class name> [file name or url to open #1] ...");
 	    System.exit(1);
         }
 
 	// Get the main class of the target program
-	Class mainClass = null;
-        try{
-            mainClass = Class.forName(args[0]);
-        } catch(Exception e){
-	    System.err.println("Could not find main class "+args[0]);
-	    System.exit(2);
-        }
+	Class mainClass = findMainClass(args.length == 0);
+	if(mainClass == null && args.length == 0){
+	    System.err.println("Usage: java "+SingletonApplication.class.getName()+
+			       " <main class name> [file name or url to open #1] ...");
+	    System.exit(15);
+	}
+	if(mainClass == null){
+	    try{
+		mainClass = Class.forName(args[0]);
+	    } catch(Exception e){
+		System.err.println("Could not find main class "+args[0]);
+		System.exit(2);
+	    }
+	    // Pass along all args except the first, the main class name
+	    String programArgs[] = new String[args.length-1];
+	    System.arraycopy(args, 1, programArgs, 0, programArgs.length);
+	    args = programArgs;
+	}
        	Class mainArgs[] = {String[].class};
 	Method main = null;
 	try{
@@ -65,19 +87,6 @@
  	    System.exit(10);
  	}
  
-	// Pass along all args except the first, the main class name
-	String programArgs[] = new String[args.length-1];
-	System.arraycopy(args, 1, programArgs, 0, programArgs.length);
-
-//         FileOutputStream fos = null;
-// 	try{
-// 	    fos = new FileOutputStream(lockFile);
-// 	} catch(Exception e){
-// 	    System.err.println("Failed to get output stream for file " + lockFile.getAbsolutePath()+": "+e.getMessage());
-// 	    e.printStackTrace();
-// 	    System.exit(12);
-// 	}
-
 	FileLock lock = null;
 	try{
 	    lock = lockFile.getChannel().tryLock();
@@ -106,7 +115,7 @@
 			System.exit(4);
 		    }
 		    try{
-			callOpen(port, programArgs);
+			callOpen(port, args);
 		    } catch(Exception e){
 			System.err.println("While calling open on existing "+main.getName()+" process: " + e.getMessage());
 			e.printStackTrace();
@@ -127,7 +136,7 @@
 	// first instance, or the app doesn't implement the right interface (why are you using this, then?)
 	(new File(lockFileAbsolutePath)).deleteOnExit();
 	try{
-	    callMain(main, programArgs, lock);
+	    callMain(main, args, lock);
 	} catch(Exception e){
 	    System.err.println("While calling main method of "+main.getName()+": " + e.getMessage());
 	    e.printStackTrace();
@@ -135,6 +144,49 @@
 	}
     }
 
+    private static Class findMainClass(boolean require){
+	String className = null;
+	ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+	String resourceName = "META-INF/services/"+SingletonApplication.class.getName();
+	URL resURL = classLoader.getResource(resourceName);
+	if(resURL == null){
+	    if(require){
+		System.err.println("NNo command line arg for the main class was provided, and the "+
+				   "resource " + resourceName + " could not be found");
+		System.exit(16);
+	    }
+	    else{
+		return null;
+	    }
+	}
+	try{
+	    LineNumberReader reader = new LineNumberReader(new InputStreamReader(resURL.openStream()));
+	    for(String line = reader.readLine(); line != null; line = reader.readLine()){
+		if(!line.trim().startsWith("#")){
+		    className = line.trim();
+		    break;
+		}
+	    }
+	} catch(Exception e){
+	    System.err.println("Error reading " + resURL+": "+e.getMessage());
+	    e.printStackTrace();
+	    System.exit(14);
+	}
+	if(className == null){
+	    System.err.println("Could not find main class name in " + resURL);
+	    System.exit(15);
+	}
+
+	try{
+	    return Class.forName(className);
+	} catch(Exception e){
+	    System.err.println("Could not load class " + className + ": " + e.getMessage());
+	    e.printStackTrace();
+	    System.exit(15);
+	}
+	return null;  //should never get here
+    }
+
     // Start the target program, passing the command-line arguments
     private static void callMain(Method main, String[] programArgs, FileLock lock) throws Exception{
 	// Write to the lock file the port on which we'll listen for "file open" requests




More information about the MOBY-guts mailing list