Pluggable HelloWorld in Java

Here is my version of Hello World. I call this, Pluggable HelloWorld! :)

Greeting.java, which all Classes must implement to be a plug-in.


1
2
3
4
5
6
package ph.devpinoy.helloworld;

public interface Greeting
{
public String sayGreeting();
}


HelloWorld.java

1
2
3
4
5
6
7
8
9
package ph.devpinoy.helloworld;

public class HelloWorld implements Greeting
{
public String sayGreeting()
{
  return "Hello World!";
}
}


Now we want to be able to make our app pluggable even when the class files are already compiled(i.e. we won't be able to make any changes). We need a properties file. It's just a plain text file with a key and value specified in it.

greetings.properties

greeting-class=ph.devpinoy.helloworld.HelloWorld


Now for our main class. It doesn't have to extend Greeting. We just need to load our class dynamically through the ClassLoader and locate the class with the help of the Properties file.


GreetingDriver.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package ph.devpinoy.helloworld;

import java.io.InputStream;
import java.io.IOException;

import java.util.Properties;

public class GreetingDriver implements Runnable
{  
  public static final String propertyFileName = "ph/devpinoy/helloworld/greetings.properties";
  public static final String className = "greeting-class";
  
public static void main(String[] args)
{
  GreetingDriver gDriver = new GreetingDriver();
  
  Thread t = new Thread(gDriver);
  t.run();
}

public void go()
{
  System.out.println("Loading property file: " + propertyFileName );
  System.out.println("Loading class from property: " + className );
  
  InputStream propertyFileStream = ClassLoader.getSystemClassLoader().getResourceAsStream(propertyFileName);
  
  Properties properties = new Properties();
  
  try
  {
    properties.load(propertyFileStream);
    
    Class customGreetingClass = Class.forName( properties.getProperty(className) );
  
Greeting greeting = (Greeting)customGreetingClass.newInstance();

System.out.println( greeting.sayGreeting() );
  }
  catch(IOException ioex)
  {
    ioex.printStackTrace();
  }
  catch(ClassNotFoundException cnfex)
  {
    cnfex.printStackTrace();
  }
  catch(InstantiationException iex)
  {
    iex.printStackTrace();
  }
  catch(IllegalAccessException iaex)
  {
    iaex.printStackTrace();
  }
  
}

public void run()
{
  go();
}
}

It doesn't have to support multithreading. I just implemented the interface because I thought it would be nice to be able to print it and see the output change without having to close the app. But then, I realized it will take a lot of tweaking and I got lazy! :)

So how does it become pluggable? Remember our Greeting interface? Let's try to make another one of those...

MerryChristmas.java

1
2
3
4
5
6
7
8
9
package ph.devpinoy.helloworld;

public class MerryChristmas implements Greeting
{
public String sayGreeting()
{
  return "Merry Christmas!";
}
}


and let's change the value in greetings.properties file from

greeting-class=ph.devpinoy.helloworld.HelloWorld

to

greeting-class=ph.devpinoy.helloworld.MerryChristmas

Ooops! No need to compile everything. Just the MerryChristmas class. See the magic! :)

The code is by no means copy-pasted. I made it on my own. But like many others, I did use some resources and they deserve some credit. It was a really fun coding experience for me. :)

Resources:

http://mindprod.com/jgloss/classforname.html

http://site.red-illusions.dk/2006/11/04/simple-dynamic-loadingunloading-of-code/
http://www.javaworld.com/javaworld/javaqa/2003-08/01-qa-0808-property.html
http://www.theserverside.com/tt/articles/article.tss?l=IOCBeginners
Published 12-23-2006 9:13 AM by lamia
Filed under: ,

Comments

Wednesday, December 27, 2006 4:10 PM by keithrull

# re: Pluggable HelloWorld in Java

this is nice! i'll post an equivalent in .NET tonight :D