<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SolitaryGeek &#187; application</title>
	<atom:link href="http://solitarygeek.com/tag/application/feed" rel="self" type="application/rss+xml" />
	<link>http://solitarygeek.com</link>
	<description>James Selvakumar&#039;s Blog</description>
	<lastBuildDate>Tue, 21 Dec 2010 04:35:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Developing A Simple Pluggable Java Application</title>
		<link>http://solitarygeek.com/java/a-simple-pluggable-java-application</link>
		<comments>http://solitarygeek.com/java/a-simple-pluggable-java-application#comments</comments>
		<pubDate>Sun, 20 Sep 2009 15:23:12 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[NetBeans]]></category>
		<category><![CDATA[application]]></category>
		<category><![CDATA[pluggable]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.solitarygeek.com/java/a-simple-pluggable-java-application/</guid>
		<description><![CDATA[<p>Most of the applications we use on daily basis are pluggable. Popular applications like Firefox, Eclipse, NetBeans, JEdit, WordPress, Hudson are all pluggable. In fact, pluggability has played a major part in the success of most of these applications. Why not make the Java applications we develop pluggable as well? Yes, we get pluggability out of the box, if our applications are based on a rich client platform like NetBeans or Eclipse. But for some reasons if you decide not to use those platforms, it doesn&#8217;t mean that they should not be pluggable. In this article, we will learn how <span style="color:#777"> . . . &#8594; Read More: <a href="http://solitarygeek.com/java/a-simple-pluggable-java-application">Developing A Simple Pluggable Java Application</a></span>]]></description>
			<content:encoded><![CDATA[<p>Most of the applications we use on daily basis are pluggable. Popular applications like Firefox, Eclipse, NetBeans, JEdit, WordPress, Hudson are all pluggable. In fact, pluggability has played a major part in the success of most of these applications. Why not make the Java applications we develop pluggable as well? Yes, we get pluggability out of the box, if our applications are based on a rich client platform like NetBeans or Eclipse. But for some reasons if you decide not to use those platforms, it doesn&#8217;t mean that they should not be pluggable. In this article, we will learn how to write a simple pluggable application that will load it&#8217;s plugins dynamically.</p>
<p><strong>The API<br />
</strong>First, let us define a plugin interface that should be implemented by all the plugins of our application. We are going to keep it very simple. Create a project called &#8220;plugin-api&#8221; in your favorite IDE and create the interface &#8220;ApplicationPlugin&#8221;.</p>
<p><img style="max-width: 800px;" src="http://solitarygeek.com/blog/wp-content/uploads/2009/09/screenshot1-p2.png" alt="" /></p>
<pre class="brush: java; title: ; notranslate">

package com.pluggableapp.plugins.api;

public interface ApplicationPlugin
{
    String getName();
    void init();
}
</pre>
<p><span id="more-464"></span></p>
<p><strong>The Plugins</strong></p>
<p>Writing the plugins now is very easy. Our plugins need to implement the plugin interface and follow a simple convention to make it easy for our applications to find them later. Create a project called &#8220;plugin-a&#8221; and develop our first plugin.</p>
<pre class="brush: java; title: ; notranslate">

package com.pluggableapp.plugins;

import com.pluggableapp.plugins.api.ApplicationPlugin;
import java.util.logging.Logger;

public class PluginA implements ApplicationPlugin
{
    private static Logger logger = Logger.getLogger(PluginA.class.getName());

    public String getName()
    {
        return &quot;Plugin A&quot;;
    }

    public void init()
    {
        logger.info(getName() + &quot; initialized!&quot;);
    }
}
</pre>
<p>Now create a directory called &#8220;META-INF/services&#8221; inside the source directory and create a file with the name &#8220;com.pluggableapp.plugins.api.ApplicationPlugin&#8221; (This is the fully qualified name of the plugin interface). The file should contain the name of the actual plugin inside it. In our case, the text is &#8220;com.pluggableapp.plugins.PluginA&#8221;.</p>
<p><img style="max-width: 800px;" src="http://solitarygeek.com/blog/wp-content/uploads/2009/09/screenshot4-p.png" alt="" /></p>
<p>Repeat these steps to create PluginB.</p>

<p><strong>The Application</strong></p>
<p>It&#8217;s time to create the application that will consume the plugins we created. First let us create a class to add the plugin jars to the classpath dynamically.</p>
<pre class="brush: java; title: ; notranslate">

package com.pluggableapp;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.logging.Logger;

public class ClasspathUtils
{

 private static Logger logger = Logger.getLogger(ClasspathUtils.class.getName());
 // Parameters
 private static final Class[] parameters = new Class[]
 {
     URL.class
 };

 /**
 * Adds the jars in the given directory to classpath
 * @param directory
 * @throws IOException
 */
 public static void addDirToClasspath(File directory) throws IOException
 {
     if (directory.exists())
     {
         File[] files = directory.listFiles();
         for (int i = 0; i &lt; files.length; i++)
         {
             File file = files[i];
             addURL(file.toURI().toURL());
         }
     }
     else
     {
         logger.warning(&quot;The directory \&quot;&quot; + directory + &quot;\&quot; does not exist!&quot;);
     }
}

 /**
 * Add URL to CLASSPATH
 * @param u URL
 * @throws IOException IOException
 */
 public static void addURL(URL u) throws IOException
 {
     URLClassLoader sysLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
     URL urls[] = sysLoader.getURLs();
     for (int i = 0; i &lt; urls.length; i++)
     {
         if (urls[i].toString().equalsIgnoreCase(u.toString()))
         {
             logger.info(&quot;URL &quot; + u + &quot; is already in the CLASSPATH&quot;);
             return;
         }
     }
     Class sysclass = URLClassLoader.class;
     try
     {
         Method method = sysclass.getDeclaredMethod(&quot;addURL&quot;, parameters);
         method.setAccessible(true);
         method.invoke(sysLoader, new Object[]
         {
             u
         });
     } catch (Throwable t)
     {
         t.printStackTrace();
         throw new IOException(&quot;Error, could not add URL to system classloader&quot;);
     }
  }
}
</pre>
<p>Now create an interface called &#8220;PluginService&#8221; to define the methods needed to load and initialize the plugins.</p>
<pre class="brush: java; title: ; notranslate">

package com.pluggableapp;

import com.pluggableapp.plugins.api.ApplicationPlugin;
import java.util.Iterator;

public interface PluginService
{
    Iterator&lt;ApplicationPlugin&gt; getPlugins();
    void initPlugins();
}
</pre>
<p>As of version 1.6, the Java runtime ships with a class called &#8220;ServiceLoader&#8221; to easily find and load plugins. Let us now write a implementation called &#8220;StandardPluginService&#8221; and make use of the facilities built into the java runtime.</p>
<pre class="brush: java; title: ; notranslate">

package com.pluggableapp;

import com.pluggableapp.PluginService;
import com.pluggableapp.plugins.api.ApplicationPlugin;
import java.util.Iterator;
import java.util.ServiceLoader;
import java.util.logging.Logger;

public class StandardPluginService implements PluginService
{
    private static StandardPluginService pluginService;
    private ServiceLoader&lt;ApplicationPlugin&gt; serviceLoader;
    private Logger logger = Logger.getLogger(getClass().getName());

    private StandardPluginService()
    {
        //load all the classes in the classpath that have implemented the interface
        serviceLoader = ServiceLoader.load(ApplicationPlugin.class);
    }

    public static StandardPluginService getInstance()
    {
        if(pluginService == null)
        {
            pluginService = new StandardPluginService();
        }
        return pluginService;
    }

    public Iterator&lt;ApplicationPlugin&gt; getPlugins()
    {
        return serviceLoader.iterator();
    }

    public void initPlugins()
    {
        Iterator&lt;ApplicationPlugin&gt; iterator = getPlugins();
        if(!iterator.hasNext())
        {
            logger.info(&quot;No plugins were found!&quot;);
        }
        while(iterator.hasNext())
        {
            ApplicationPlugin plugin = iterator.next();
            logger.info(&quot;Initializing the plugin &quot; + plugin.getName());
            plugin.init();
        }
    }
}
</pre>
<p>Feel free to write your own implementation if needed. For example you can easily write an implementation based on the NetBeans API.</p>
<p>Write a factory class named &#8220;PluginServiceFactory&#8221; to create &#8220;PluginService&#8221; objects.</p>
<pre class="brush: java; title: ; notranslate">

package com.pluggableapp;

import com.pluggableapp.*;
import com.pluggableapp.StandardPluginService;
import com.pluggableapp.PluginService;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class PluginServiceFactory
{
    public static PluginService createPluginService()
    {
        addPluginJarsToClasspath();
        return StandardPluginService.getInstance();
    }

    private static void addPluginJarsToClasspath()
    {
        try
        {
            //add the plugin directory to classpath
            ClasspathUtils.addDirToClasspath(new File(&quot;plugins&quot;));
        } catch (IOException ex)
        {
            Logger.getLogger(PluginServiceFactory.class.getName()).log(
                Level.SEVERE, null, ex);
        }
    }
}
</pre>
<p>That&#8217;s it. All we need to do now is to write a class that will invoke the &#8220;PluginServiceFactory&#8221;.</p>
<pre class="brush: java; title: ; notranslate">

package com.pluggableapp;

import com.pluggableapp.plugins.api.ApplicationPlugin;
import java.util.Iterator;
import java.util.logging.Logger;

public class Main
{

    private static Logger logger = Logger.getLogger(Main.class.getName());

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args)
    {
        loadPlugins();
    }

    private static void loadPlugins()
    {
        PluginService pluginService = PluginServiceFactory.createPluginService();
        pluginService.initPlugins();
    }
}
</pre>
<p>Before we build and see the application in action, create a directory called &#8220;plugins&#8221; and put all plugin jars there.</p>
<p><img style="max-width: 800px;" src="http://solitarygeek.com/blog/wp-content/uploads/2009/09/screenshot3-p1.png" alt="" /></p>
<p>And this is what you might see when you run our pluggable application.</p>
<p><img style="max-width: 800px;" src="http://solitarygeek.com/blog/wp-content/uploads/2009/09/screenshot2-p1.png" alt="" /></p>
<p>Now feel free to create as many plugins you want to write and just drop them in the &#8220;plugins&#8221; directory and restart the &#8220;pluggable&#8221; application to see your &#8220;home grown&#8221; plugins in action!</p>
<p><strong>Resources</strong></p>
<p><a href="http://java.sun.com/developer/technicalArticles/javase/extensible/index.html">Creating Extensible Applications With the Java Platform</a> &#8211; <em>John O&#8217;Conner</em></p>
<p><a href="http://twit88.com/blog/2007/10/07/develop-a-java-plugin-framework/">Developing a Java Plugin Framework </a></p>
<p><a href="http://java.dzone.com/news/how-create-pluggable-photo-alb">How to Create a Pluggable Photo Album in Java</a> &#8211; <em>Geertjan</em></p>
<div class="zemanta-pixie"><img class="zemanta-pixie-img" src="http://img.zemanta.com/pixy.gif?x-id=d7d85c06-7c20-8a72-ae33-ec6bc5f32317" alt="" /></div>
]]></content:encoded>
			<wfw:commentRss>http://solitarygeek.com/java/a-simple-pluggable-java-application/feed</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
	</channel>
</rss>

