{"id":372,"date":"2007-10-21T00:00:00","date_gmt":"2007-10-21T00:00:00","guid":{"rendered":"http:\/\/www.strongd.net\/?p=372"},"modified":"2007-10-21T00:00:00","modified_gmt":"2007-10-21T00:00:00","slug":"The JarRunner Class","status":"publish","type":"post","link":"https:\/\/www.strongd.net\/?p=372","title":{"rendered":"The JarRunner Class"},"content":{"rendered":"<p><DIV><br \/>\n<DIV id=PageTitle>The JarRunner Class<\/DIV><br \/>\n<BLOCKQUOTE>The JarRunner application is launched with a command of this form:<br \/>\n<BLOCKQUOTE><PRE>java JarRunner <I>url [arguments]<\/I><br \/>\n<\/PRE><\/BLOCKQUOTE>In the previous section, we&#8217;ve seen how <TT>JarClassLoader<\/TT> is able to identify and load the main class of a JAR-bundled application from a given URL. To complete the JarRunner application, therefore, we need to be able to take a URL and any arguments from the command line, and pass them to an instance of <TT>JarClassLoader<\/TT>. These tasks belong to the <TT>JarRunner<\/TT> class, the entry point of the JarRunner application.<br \/>\n<P>It begins by creating a <TT>java.net.URL<\/TT> object from the URL specified on the command line: <\/P><br \/>\n<BLOCKQUOTE><PRE>public static void main(String[] args) {<br \/>\n    if (args.length &lt; 1) {<br \/>\n        usage();<br \/>\n    }<br \/>\n    URL url = null;<br \/>\n    try {<br \/>\n        url = new URL(args[0]);<br \/>\n    } catch (MalformedURLException e) {<br \/>\n        fatal(&#8220;Invalid URL: &#8221; + args[0]);<br \/>\n    }<br \/>\n    &#8230;<br \/>\n<\/PRE><\/BLOCKQUOTE>If <TT>args.length&nbsp;&lt;&nbsp;1<\/TT>, that means no URL was specified on the command line, so a usage message is printed. If the first command-line argument is a good URL, a new <TT>URL<\/TT> object is created to represent it.<br \/>\n<P>Next, JarRunner creates a new instance of <TT>JarClassLoader<\/TT>, passing to the constructor the URL that was specified on the command-line: <\/P><br \/>\n<BLOCKQUOTE><PRE>JarClassLoader cl = new JarClassLoader(url);<br \/>\n<\/PRE><\/BLOCKQUOTE>As we saw in the previous section, it&#8217;s through <TT>JarClassLoader<\/TT> that JarRunner taps into the JAR-handling APIs.<br \/>\n<P>The URL that&#8217;s passed to the <TT>JarClassLoader<\/TT> constructor is the URL of the JAR-bundled application that you want to run. JarRunner next calls the class loader&#8217;s <TT>getMainClassName<\/TT> method to identify the entry-point class for the application: <\/P><br \/>\n<BLOCKQUOTE><PRE>String name = null;<br \/>\ntry {<br \/>\n    <B>name = cl.getMainClassName();<\/B><br \/>\n} catch (IOException e) {<br \/>\n    System.err.println(&#8220;I\/O error while loading JAR file:&#8221;);<br \/>\n    e.printStackTrace();<br \/>\n    System.exit(1);<br \/>\n}<br \/>\nif (name == null) {<br \/>\n    fatal(&#8220;Specified jar file does not contain a &#8216;Main-Class'&#8221; +<br \/>\n          &#8221; manifest attribute&#8221;);<br \/>\n}<br \/>\n<\/PRE><\/BLOCKQUOTE>The key statement is highlighted in bold. The other statements are for error handling.<br \/>\n<P>Once <TT>JarRunner<\/TT> has identified the application&#8217;s entry-point class, only two steps remain: passing any arguments to the application and actually launching the application. <TT>JarRunner<\/TT> performs these steps with this code: <\/P><br \/>\n<BLOCKQUOTE><PRE>\/\/ Get arguments for the application<br \/>\nString[] newArgs = new String[args.length &#8211; 1];<br \/>\n<B>System.arraycopy(args, 1, newArgs, 0, newArgs.length);<\/B><br \/>\n\/\/ Invoke application&#8217;s main class<br \/>\ntry {<br \/>\n    cl.invokeClass(name, newArgs);<br \/>\n} catch (ClassNotFoundException e) {<br \/>\n    fatal(&#8220;Class not found: &#8221; + name);<br \/>\n} catch (NoSuchMethodException e) {<br \/>\n    fatal(&#8220;Class does not define a &#8216;main&#8217; method: &#8221; + name);<br \/>\n} catch (InvocationTargetException e) {<br \/>\n    e.getTargetException().printStackTrace();<br \/>\n    System.exit(1);<br \/>\n}<br \/>\n<\/PRE><\/BLOCKQUOTE>Recall that the first command-line argument was the URL of the JAR-bundled application. Any arguments to be passed to that application are therefore in element <TT>1<\/TT> and beyond in the <TT>args<\/TT> array. <TT>JarRunner<\/TT> takes those elements, and creates a new array called <TT>newArgs<\/TT> to pass to the application (bold line above). <TT>JarRunner<\/TT> then passes the entry-point&#8217;s class name and the new argument list to the <TT>invokeClass<\/TT> method of <TT>JarClassLoader<\/TT>. As we saw in the previous section, <TT>invokeClass<\/TT> will load the application&#8217;s entry-point class, pass it any arguments, and launch the application.<\/BLOCKQUOTE><\/DIV><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The JarRunner Class The JarRunner application is launched with a command of this form: java JarRunner url [arguments] In the previous section, we&#8217;ve seen how JarClassLoader is able to identify and load the main class of a JAR-bundled application from a given URL. To complete the JarRunner application, therefore, we need to be able to &hellip; <a href=\"https:\/\/www.strongd.net\/?p=372\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">The JarRunner Class<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-372","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/www.strongd.net\/index.php?rest_route=\/wp\/v2\/posts\/372","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.strongd.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.strongd.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.strongd.net\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.strongd.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=372"}],"version-history":[{"count":0,"href":"https:\/\/www.strongd.net\/index.php?rest_route=\/wp\/v2\/posts\/372\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.strongd.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=372"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.strongd.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=372"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.strongd.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=372"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}