import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.JarURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.jar.Attributes; public class JarRunner implements Runnable { String theURL; public JarRunner(String thisURL){ theURL=thisURL; } public static void main(String[] args ) { (new Thread(new JarRunner("http://www.umsl.edu/~siegelj/CS4010/Threads/java/Hanoi.jar"))).start(); } public int stop_thread(){ return 0; } public void run() { URL url = null; try { url = new URL(theURL); } catch (MalformedURLException e) { fatal("Invalid URL: " + theURL); } // Create the class loader for the application jar file JarClassLoader cl = new JarClassLoader(url); // Get the application's main class name String name = null; try { name = cl.getMainClassName(); } catch (IOException e) { System.err.println("I/O error while loading JAR file:"); e.printStackTrace(); System.exit(1); } if (name == null) { fatal("Specified jar file does not contain a 'Main-Class'" + " manifest attribute"); } // Get arguments for the application String[] newArgs = new String[1];//[args.length - 1]; // System.arraycopy(args, 1, newArgs, 0, newArgs.length); // Invoke application's main class newArgs[0]="Hanoi has no arguments"; try { cl.invokeClass(name, newArgs); } catch (ClassNotFoundException e) { fatal("Class not found: " + name); } catch (NoSuchMethodException e) { fatal("Class does not define a 'main' method: " + name); } catch (InvocationTargetException e) { e.getTargetException().printStackTrace(); System.exit(1); } } private static void fatal(String s) { System.err.println(s); System.exit(1); } private static void usage() { fatal("Usage: java JarRunner url [args..]"); } } /** * A class loader for loading jar files, both local and remote. */ class JarClassLoader extends URLClassLoader { private URL url; /** * Creates a new JarClassLoader for the specified url. * * @param url * the url of the jar file */ public JarClassLoader(URL url) { super(new URL[] { url}); this.url = url; } /** * Returns the name of the jar file main class, or null if no "Main-Class" * manifest attributes was defined. */ public String getMainClassName() throws IOException { URL u = new URL("jar", "", url + "!/"); JarURLConnection uc = (JarURLConnection) u.openConnection(); Attributes attr = uc.getMainAttributes(); return attr != null ? attr.getValue(Attributes.Name.MAIN_CLASS) : null; } /** * Invokes the application in this jar file given the name of the main class * and an array of arguments. The class must define a static method "main" * which takes an array of String arguemtns and is of return type "void". * * @param name * the name of the main class * @param args * the arguments for the application * @exception ClassNotFoundException * if the specified class could not be found * @exception NoSuchMethodException * if the specified class does not contain a "main" method * @exception InvocationTargetException * if the application raised an exception */ public void invokeClass(String name, String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException { Class<?> c = loadClass(name); System.out.println(c.toString()); Method m = c.getMethod("main", new Class[] { args.getClass()}); m.setAccessible(true); int mods = m.getModifiers(); if (m.getReturnType() != void.class || !Modifier.isStatic(mods) || !Modifier.isPublic(mods)) { throw new NoSuchMethodException("main"); } try { m.invoke(null, new Object[] { args}); } catch (IllegalAccessException e) { // This should not happen, as we have disabled access checks } } } /* From http://java.sun.com/docs/books/tutorial/index.html */ /* * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * -Redistribution of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed, licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ /*Modified by Jerrold Siegel 2/12/2016 Converted to Runnable Thread. Disabled passing of arguments. One small change to avoid a raw type warning used Class<?> rather than Class and added a println to show the name of class being loaded Class<?> c = loadClass(name); System.out.println(c.toString()); */