{"id":2932,"date":"2007-12-06T16:10:46","date_gmt":"2007-12-06T14:10:46","guid":{"rendered":"http:\/\/fdt.powerflasher.com\/blog\/?p=35"},"modified":"2007-12-06T16:10:46","modified_gmt":"2007-12-06T14:10:46","slug":"loading-jars-at-runtime","status":"publish","type":"post","link":"https:\/\/fdt.powerflasher.com\/blog\/2007\/12\/loading-jars-at-runtime\/","title":{"rendered":"Loading jars at runtime"},"content":{"rendered":"<p>During the implementation of a feature of FDT we face the problem to load a jar at runtime. You can find many posts about how to do it. Basicly you use a URLClassLoader, tells him which jars to load and use reflection to instanciate the classes. But a problem arise if you load multiple jars and one of the jars try to access classes from an other jar. In this case you get ClassNotFoundExceptions, even if the same class loader is used to load the jars.<\/p>\n<p>Finaly we find a <a href=\"http:\/\/tech.puredanger.com\/2006\/11\/09\/classloader\/\" title=\"blog post\">blog post<\/a> that solves this problem (thank you <a href=\"http:\/\/spicefactory.org\/\" title=\"Jens\">Jens<\/a>!). The trick is to define your own classloader and override &#8220;loadClass&#8221; such that it first searches locally for the classes in the jars and then delegates to the parent class loader.<\/p>\n<p>To illustrate this here is a small example.  We define a main program and a plugin for this program. The plugin uses a class from an other jar. Both, the plugin and the extra jar are loaded at runtime.<\/p>\n<p>The main program constist of a class <strong>Main<\/strong>, an interface <strong>IPlugin<\/strong> and a custom class loader <strong>PluginClassLoader<\/strong>. All are packaged in an <strong>main.jar<\/strong>.<\/p>\n<ul>\n<li>\n<pre>package test;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.net.URL;\n\npublic class Main {\n  private PluginClassLoader urlLoader;\n\n  public static void main(String[] args) {\n    new Main();\n  }\n\n  public Main() {\n    try {\n      String[] stringURLs = new String[] {\n          \"C:\/Test\/extra.jar\",\n          \"C:\/Test\/plugin.jar\" };\n      URL[] urls = new URL[stringURLs.length];\n      for (int n = 0; n &lt; stringURLs.length; n++)\n        urls[n] = new File(stringURLs[n]).toURL();\n      urlLoader = new PluginClassLoader(urls,\n          Main.class.getClassLoader());\n      IPlugin fcsh = (IPlugin) urlLoader.loadClass(\n          \"plugin.ConcretePlugin\").newInstance();\n      fcsh.perform();\n    } catch (IOException e) {\n      e.printStackTrace();\n    } catch (IllegalAccessException e) {\n      e.printStackTrace();\n    } catch (SecurityException e) {\n      e.printStackTrace();\n    } catch (IllegalArgumentException e) {\n      e.printStackTrace();\n    } catch (InstantiationException e) {\n      e.printStackTrace();\n    } catch (ClassNotFoundException e) {\n      e.printStackTrace();\n    }\n  }\n}<\/pre>\n<\/li>\n<\/ul>\n<pre><\/pre>\n<ul>\n<li>\n<pre>package test;\n\npublic interface IPlugin {\n  void perform();\n}<\/pre>\n<\/li>\n<\/ul>\n<ul>\n<li>\n<pre>package test;\n\nimport java.net.URL;\nimport java.net.URLClassLoader;\n\npublic class PluginClassLoader extends URLClassLoader {\n  public PluginClassLoader(URL[] urls, ClassLoader parent) {\n    super(urls, parent);\n  }\n\n  public Class&lt;?&gt; loadClass(String name)\n      throws ClassNotFoundException {\n    Class loadedClass = findLoadedClass(name);\n    if (loadedClass == null) {\n      try {\n        loadedClass = findClass(name);\n      } catch (ClassNotFoundException e) {\n        \/\/ Swallow exception\n        \/\/does not exist locally\n      }\n\n      if (loadedClass == null) {\n        loadedClass = super.loadClass(name);\n      }\n    }\n    return loadedClass;\n  }\n\n}<\/pre>\n<\/li>\n<\/ul>\n<p>The plugin constist of a class <strong>ConcretePlugin<\/strong>, and is packaged as <strong>plugin.jar<\/strong>. On its classpath is the <strong>main.jar<\/strong> and the <strong>extra.jar<\/strong>.<\/p>\n<ul>\n<li>\n<pre>package plugin;\n\nimport extra.Extra;\nimport test.IPlugin;\n\npublic class ConcretePlugin implements IPlugin {\n  public void perform() {\n    Extra e = new Extra();\n    System.out.println(\"perform: \" + e);\n  }\n}<\/pre>\n<\/li>\n<\/ul>\n<p>The <strong>extra.jar <\/strong>contains the class <strong>Extra<\/strong>.<\/p>\n<ul>\n<li>\n<pre>package extra;\n\npublic class Extra {\n  public String toString() {\n    return \"Extra works!\";\n  }\n}<\/pre>\n<\/li>\n<\/ul>\n<p>Now you are able to replace the <strong>extra.jar<\/strong> with an other version of that jar and load this at runtime. Hope this  will save some java developers some time.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>During the implementation of a feature of FDT we face the problem to load a jar at runtime. You can find many posts about how to do it. Basicly you use a URLClassLoader, tells him which jars to load and use reflection to instanciate the classes. But a problem arise if you load multiple jars [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4,11],"tags":[65,87,160,161,249,297],"_links":{"self":[{"href":"https:\/\/fdt.powerflasher.com\/blog\/wp-json\/wp\/v2\/posts\/2932"}],"collection":[{"href":"https:\/\/fdt.powerflasher.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fdt.powerflasher.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fdt.powerflasher.com\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/fdt.powerflasher.com\/blog\/wp-json\/wp\/v2\/comments?post=2932"}],"version-history":[{"count":0,"href":"https:\/\/fdt.powerflasher.com\/blog\/wp-json\/wp\/v2\/posts\/2932\/revisions"}],"wp:attachment":[{"href":"https:\/\/fdt.powerflasher.com\/blog\/wp-json\/wp\/v2\/media?parent=2932"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fdt.powerflasher.com\/blog\/wp-json\/wp\/v2\/categories?post=2932"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fdt.powerflasher.com\/blog\/wp-json\/wp\/v2\/tags?post=2932"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}