{"id":980,"date":"2008-11-22T13:02:30","date_gmt":"2008-11-22T20:02:30","guid":{"rendered":"http:\/\/www.gubatron.com\/blog\/?p=980"},"modified":"2008-11-22T13:02:30","modified_gmt":"2008-11-22T20:02:30","slug":"javareflection-notes-invoking-a-static-main-method-from-a-dinamically-loaded-class","status":"publish","type":"post","link":"https:\/\/www.gubatron.com\/blog\/javareflection-notes-invoking-a-static-main-method-from-a-dinamically-loaded-class\/","title":{"rendered":"Java\/Reflection notes: Invoking a static main() method from a dinamically loaded class."},"content":{"rendered":"<p><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/farm4.static.flickr.com\/3009\/3050249135_841fd90b5b_m.jpg?w=640\" class=\"alignleft\"\/>Maybe for some wild reason, your Java application will need to execute a pre launcher that won&#8217;t know about the Main class it&#8217;s supposed to invoke until it&#8217;s being executed. For example, you have distributed your Java application but you used pack200 to compress your jars, and your new application launcher will unpack everything, but up to this point, it can&#8217;t do an import of the main class, since the jar that contained it, wasn&#8217;t available to the virtual machine when java was invoked.<\/p>\n<p>So, your launcher class, finishes unpacking your jars, adds the jars to the current classloader, and now you need to invoke your <strong>Main.main(String[] args)<\/strong>. <\/p>\n<p>This is how I managed to do it, using Java&#8217;s reflection mechanisms<\/p>\n<p>[java]<br \/>\n    public final void startMain(String[] args) {<br \/>\n        \/\/this will create a new class loader out of all jars available, see below on next<br \/>\n        \/\/code section of this blog post<br \/>\n        addJars2Classpath();<\/p>\n<p>        try {<br \/>\n            \/\/Instantiate the main class, and execute it&#8217;s static main method<br \/>\n            Class clazz = jarsClassloader.loadClass(&quot;com.mycomp.somepackage.Main&quot;);<br \/>\n            Class[] argTypes = { args.getClass(), };<br \/>\n            Object[] passedArgs = { args };<br \/>\n            Method main = clazz.getMethod(&quot;main&quot;,argTypes);<br \/>\n            main.invoke(null, passedArgs);<br \/>\n        } catch (Exception e) {<br \/>\n            \/\/oh oh<br \/>\n            e.printStackTrace();<br \/>\n        }<\/p>\n<p>    } \/\/startMain<br \/>\n[\/java]<\/p>\n<p>In case you&#8217;re interested in how to add new Jars to the classpath during runtime, this is how I managed to do it:<\/p>\n<p>[java]<br \/>\n    \/**<br \/>\n     * Adds all the newly available jars to the classpath<br \/>\n     *\/<br \/>\n    public final void addJars2Classpath() throws Exception {<br \/>\n        \/\/Create a new class loader with all the jars.<br \/>\n        Object[] jars = getFiles(getApplicationResourcesJavaFolder(), &quot;.jar&quot;);<br \/>\n        URL[] jarUrls = new URL[jars.length];<\/p>\n<p>        for (int i=0; i &lt; jars.length; i++) {<br \/>\n            URL jarURL = null;<\/p>\n<p>            try {<br \/>\n                jarURL = new URL(&quot;jar:file:&quot;+(String) jars[i]+&quot;!\/&quot;);<br \/>\n            } catch (Exception e) {<br \/>\n                \/\/LOG.error(&quot;Bad URL for jar (&quot;+jarFile+&quot;):n&quot;+e.toString()+&quot; (&quot;+jarURL+&quot;)n&quot;);<br \/>\n                return;<br \/>\n            }<\/p>\n<p>            jarUrls[i] = jarURL;<br \/>\n        }<\/p>\n<p>        \/\/and this guy here, is the classloader used to load<br \/>\n        jarsClassloader = URLClassLoader.newInstance(jarUrls);<br \/>\n      } \/\/addJar2Classpath<\/p>\n<p>    \/**<br \/>\n     * Get a Object&lt;String&gt; array that contains the names of the files<br \/>\n     * that end with &#8216;type&#8217; on the given folderPath<br \/>\n     *<br \/>\n     * e.g<br \/>\n     *<br \/>\n     * String[] jarFiles = getFiles(&quot;.&quot;,&quot;.jar&quot;);<br \/>\n     *<br \/>\n     *\/<br \/>\n    public final Object[] getFiles(String folderPath, String type) {<br \/>\n        File f = new File(folderPath);<\/p>\n<p>        String[] files = f.list();<\/p>\n<p>        Vector results = new Vector();<\/p>\n<p>        for (int i=0; i &lt; files.length; i++) {<br \/>\n            if (files[i].endsWith(type)) {<br \/>\n                results.add((String) files[i]);<br \/>\n            }<br \/>\n        }<\/p>\n<p>        if (results.size() == 0)<br \/>\n            return null;<\/p>\n<p>        return results.toArray();<br \/>\n    } \/\/getFiles<br \/>\n[\/java] <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Maybe for some wild reason, your Java application will need to execute a pre launcher that won&#8217;t know about the Main class it&#8217;s supposed to invoke until it&#8217;s being executed. For example, you have distributed your Java application but you used pack200 to compress your jars, and your new application launcher will unpack everything, but [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[15],"tags":[583,832],"class_list":["post-980","post","type-post","status-publish","format-standard","hentry","category-code","tag-java","tag-reflection"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p5Unzf-fO","jetpack-related-posts":[{"id":3020,"url":"https:\/\/www.gubatron.com\/blog\/how-to-avoid-android-compilationbuilding-issues-setting-up-the-eclipse-buildpath-correctly\/","url_meta":{"origin":980,"position":0},"title":"How to avoid Android compilation\/building issues &#8211; Setting up the Eclipse Buildpath correctly","author":"gubatron","date":"May 21, 2013","format":false,"excerpt":"This post is the product of about 48 hours of not being able to work on what I was supposed to be working because I had to deal with build issues in Eclipse. Hopefully If you follow these steps you will be able to solve some of the issues you\u2026","rel":"","context":"In &quot;Android&quot;","block_context":{"text":"Android","link":"https:\/\/www.gubatron.com\/blog\/category\/android\/"},"img":{"alt_text":"Screen Shot 2013-05-21 at 12.13.46 PM","src":"https:\/\/i0.wp.com\/www.gubatron.com\/blog\/wp-content\/uploads\/2013\/05\/Screen-Shot-2013-05-21-at-12.13.46-PM.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.gubatron.com\/blog\/wp-content\/uploads\/2013\/05\/Screen-Shot-2013-05-21-at-12.13.46-PM.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.gubatron.com\/blog\/wp-content\/uploads\/2013\/05\/Screen-Shot-2013-05-21-at-12.13.46-PM.png?resize=525%2C300 1.5x"},"classes":[]},{"id":1269,"url":"https:\/\/www.gubatron.com\/blog\/how-to-make-a-quick-dirty-hexviewer-updated\/","url_meta":{"origin":980,"position":1},"title":"How to make a Quick &#038; Dirty HexViewer &#8211; Updated","author":"gubatron","date":"April 20, 2009","format":false,"excerpt":"After I received comments from ispak on Flickr I made a few fixes. ispak pointed out that it was a bad idea reading one byte at the time, also I had a gay ass try\/catch that didn't catch any exception :p So now I read 16 byte chunks, and I\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/www.gubatron.com\/blog\/category\/code\/"},"img":{"alt_text":"HexViewer - r2","src":"https:\/\/i0.wp.com\/farm4.static.flickr.com\/3486\/3458529439_31357e0afe_o.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/farm4.static.flickr.com\/3486\/3458529439_31357e0afe_o.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/farm4.static.flickr.com\/3486\/3458529439_31357e0afe_o.png?resize=525%2C300 1.5x"},"classes":[]},{"id":3699,"url":"https:\/\/www.gubatron.com\/blog\/how-to-run-your-kotlin-gradle-built-app-from-the-command-line\/","url_meta":{"origin":980,"position":2},"title":"How to run your Kotlin gradle built app from the command line","author":"gubatron","date":"July 20, 2017","format":false,"excerpt":"So you build your Kotlin app, you went through the trouble of creating a build.gradle script that you build with gradle assemble this outputs a a \"build\/libs\/kotlin.jar\" .jar file, but you have no clue how to run your Kotlin code from the command line. Doing it by hand with \"java\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/www.gubatron.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":156,"url":"https:\/\/www.gubatron.com\/blog\/portscanner-only-60-lines-of-code\/","url_meta":{"origin":980,"position":3},"title":"PortScanner &#8211; Only 60 lines of code","author":"gubatron","date":"May 19, 2005","format":false,"excerpt":"Hi, here's a simple port scanner I wrote today in Java. I needed to see something on my server, perhaps you can find it useful. I would say its pretty fast, you can tweak the number of threads and timeouts to adjust to your server\/connection. I did't do much testing\u2026","rel":"","context":"In &quot;Gubatron&quot;","block_context":{"text":"Gubatron","link":"https:\/\/www.gubatron.com\/blog\/category\/gubatron\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2792,"url":"https:\/\/www.gubatron.com\/blog\/java-have-a-jtables-column-preferred-width-adjusted-to-perfectly-to-the-size-of-the-longest-string-in-the-model\/","url_meta":{"origin":980,"position":4},"title":"Java: Have a JTable&#8217;s column preferred width adjusted perfectly to the size of the longest string in the model","author":"gubatron","date":"October 30, 2012","format":false,"excerpt":"Here's a utility method I've coded for FrostWire's partial download dialog. With it I'm able to adjust a JTable's column by iterating over the table's column model data and calculating the exact dimensions required to render the longest string found. You can specify a maximum width (to avoid some really\u2026","rel":"","context":"In \"java\"","block_context":{"text":"java","link":"https:\/\/www.gubatron.com\/blog\/tag\/java\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2926,"url":"https:\/\/www.gubatron.com\/blog\/how-to-check-if-a-java-process-is-running-on-any-local-virtual-machine-programatically\/","url_meta":{"origin":980,"position":5},"title":"How to check if a Java Process is running on any local Virtual Machine programmatically","author":"gubatron","date":"January 30, 2013","format":false,"excerpt":"Quick and dirty way to check if a Java Process is already running. Useful if you need to run cronjobs periodically and you don't know how long they might take, you can add this check at the beginning of your main, and it'll look for all the local virtual machines\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/www.gubatron.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/posts\/980","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/comments?post=980"}],"version-history":[{"count":0,"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/posts\/980\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/media?parent=980"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/categories?post=980"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/tags?post=980"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}