Note that there are some explanatory texts on larger screens.

plurals
  1. POhow to make a dynamically loaded plugin web application-aware
    primarykey
    data
    text
    <p>I decided to implement dynamic class loading in my glassfish web application, as a way of trying it out and to support small plugins that could be loaded and executed by the web app at runtime. </p> <p>I added the following class:</p> <pre><code>public class PluginManager { private static final String dropBoxDir = "file:///path/to/dropbox/"; private static final URLClassLoader dropBoxClassLoader; static { try { URL dropBoxURL = new URL(dropBoxDir); dropBoxClassLoader = URLClassLoader.newInstance(new URL[]{dropBoxURL}); } catch (MalformedURLException mue) { throw new RuntimeException("MalformedURLException thrown during PluginManager initialization - the hardcoded URL " + dropBoxDir + " must be invalid.", mue); } } //this method is called by a web service public static void runPluginFromDropBox(String fullClassName) { try { //load the plugin class Class&lt;?&gt; pluginClass = dropBoxClassLoader.loadClass(fullClassName); //instantiate it Runnable plugin = (Runnable)pluginClass.newInstance(); //call its run() method plugin.run(); } catch (ClassNotFoundException cnfe) { throw new RuntimeException("The class file for " + fullClassName + " could not be located at the designated directory (" + dropBoxDir + "). Check that the specified class name is correct, and that its file is in the right location.", cnfe); } catch (InstantiationException ie) { throw new RuntimeException("InstantiationException thrown when attempting to instantiate the plugin class " + fullClassName + " - make sure it is an instantiable class with a no-arg constructor.", ie); } catch (IllegalAccessException iae) { throw new RuntimeException("IllegalAccessException thrown when attempting to instantiate the plugin class " + fullClassName + " - make sure the class and its no-arg constructor have public access.", iae); } catch (ClassCastException cce) { throw new RuntimeException("Plugin instance could not be cast to Runnable - plugin classes must implement this interface.", cce); } } } </code></pre> <p>Then in a separate project, I created a test plugin:</p> <pre><code>public class TestPlugin implements Runnable { @Override public void run() { System.out.println("plugin code executed"); } } </code></pre> <p>I deployed the web application, then compiled <code>TestPlugin</code> into a <code>.class</code> file and dropped it into the designated folder. I called a web service that hits <code>runPluginFromDropBox()</code> with the class name and got the expected output.</p> <p>This all worked as a proof of concept, but my plugin is effectively useless unless it can be made aware of my web application's classes. I've since read that <code>.war</code> is intended only as a standalone application, and not meant to be on other libraries' classpaths, which doesn't bode well for this little side-project.</p> <p>I had a look at this discussion: <a href="https://stackoverflow.com/questions/169329/extending-java-web-applications-with-plugins">Extending Java Web Applications with plugins</a> and get the feeling I'm wading into a swamp of design challenges for no huge reason and should turn around. However that post is kind of old and is Tomcat-specific, so I just thought I'd ask if there's any straightforward way for me to approach this without some elaborate third party framework.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload