Che Veyo
Che Veyo

Reputation: 385

Plugin framework and bi-directional program communication

What would be a good way to let 2 different separate Java programs communicate with each other?

I am not sure if I want to use OSGi (but it seems to be the only one which still gets updates; jpf and jspf are very old). I am very new to the topic Plugin Framework. Am I right that OSGi is just the description of the architecture, plugin structure etc. and that equinox and all this other thing are the real implementation, which i have to use?

I make things more precise: I want to program a Core Tool which should be able to hot-load Plugins, and bidirectionally communicate with them and a JavaFX GUI.

I usually use a class for controlling the GUI and a additional class for algorithms and so on (MVC). But I think this style is no longer helpful to structure a plugin-based Tool.

I want to use a good design pattern from the beginning, else it'll end up a mess.

Upvotes: 2

Views: 448

Answers (2)

Eric Leibenguth
Eric Leibenguth

Reputation: 4277

The simplest solution to this problem is to use ServiceLoader (doc here). It is included in Java, and is fairly simple to use:

  1. Load Jar file(s) at runtime
  2. Detect classes that implement a particular interface (e.g.: your.package.YourService).
  3. Instantiate objects from these classes.

Here is a pretty good post describing how to do so (Note: you should use the second proposal with URLCLassLoader; not extend the classpath dynamically). Also, do not forget to declare your services inside the Jar's META-INF directory:

If com.example.impl.StandardCodecs is an implementation of the CodecSet service then its jar file also contains a file named

META-INF/services/com.example.CodecSet 

This file contains the single line:

com.example.impl.StandardCodecs    # Standard codecs

By choosing this approach, your core program will naturally have a handle to your plugins, so will be able to communicate with them easily. To ensure the bi-directional communication (i.e. plugins calling your core program), I would suggest to create an interface that your core program will implement, and pass that interface to your plugins.

Plugin interface:

public interface Plugin { 
   public void doPluginStuff(Caller caller);
}

Core program Caller interface:

public interface Caller {
   public void sendBackResults(Object results);
}

Plugin implementation (in separate Jar file):

public class AParticularPlugin implements Plugin {
   public void doPluginStuff(Caller caller){
      caller.sendBackResults("Hello world");
   }
}

Core program:

public class CoreProgram implements Caller {

   public void callPlugin(URL[] urlToJarFiles){
      URLClassLoader ucl = new URLClassLoader(urlToJarFiles);
      ServiceLoader<Plugin> sl = ServiceLoader.load(Plugin.class, ucl);
      Iterator<Plugin> plugins = sl.iterator();
      while (plugins.hasNext())
         plugins.next().doPluginStuff(this);
   }

   public void sendBackResults(Object results){
      System.out.println(results.toString());
   }

}

Upvotes: 4

Torsten Hopf
Torsten Hopf

Reputation: 69

An little "answer" to your first question. It is more likely some sort of experience report.

I used the Akka Framework in some earlier projects to communicate across programm (and hardware) borders.

Akka is an Framework that uses the actor pattern and messages. It is build in scala but there is a good Java Version, too.

Give it a look: http://akka.io/

I'm still new to this, please don't hesitate to give me advice!

Greetings, Torsten

Upvotes: 1

Related Questions