Plugin framework and bi-directional program communication - java

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.

The simplest solution to this problem is to use ServiceLoader (doc here). It is included in Java, and is fairly simple to use:
Load Jar file(s) at runtime
Detect classes that implement a particular interface (e.g.: your.package.YourService).
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());
}
}

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

Related

Can I use custom annotations to classify Java classes?

Is it possible that use self defined Annotation to classify java class into different product function ? (Following are my thoughts)
If not, are there any other method to achieve the same purpose in Android project?
Step1: use self defined annotation to make clear java class's function
#SelfDefinedAnnotation( "product-function-a" )
class MyClass {
void func() {
//do something
}
}
Step2: during building period, generate a mapping file like this
MyClass -> product-function-a
YourClass -> product-function-b
I'm not sure about android (never worked with it), but in pure java its possible for sure.
You should define an annotation with retention policy SOURCE and since you're talking about build time, define an annotation processor. This is something that is "hooked" into the compilation process and allows creating such a mapping (I assume you want to store it in some kind of file, maybe *.properties file, or even generate a java source code with these definitions.
The annotation processor is broad topic, there are many ways to register them, so it pretty much depends on how do you build your stuff exactly, but its a general direction.
Please check out this tutorial it talks about annotation processors, the ways to register them, to associate with your custom annotation and so forth.
One suggestion though, if you're about to generate Java Source class and not just a properties file, this tutorial goes "low level" and tries to prepare the syntax by itself, I suggest using a much nicer (IMO) Java Poet library that will help to generate a proper java code

Class wrapper extending different base class

I have a Java project and now I also want to use this code for a GWT project so I don't have to write the same code twice. The problem is that some classes are not available in gwt, for example java.awt.geom.Rectangle2D.Double.
I was thinking of creating a wrapper class called RectangleWrapper that would extend either the standard Rectangle class or a gwt version of the same class.
In the shared code I would replace all my Rectangle2D.Double with my Rectangle and depending on a final boolean my wrapper class (compiler flags java) would either extend on or the other Rectangle class.
Is this even possible or is there a better way to do this?
I just took one of my GWT-project client-side classes and added the following lines:
if (false) {
String a = StringEscapeUtils.escapeHtml("lalala");
}
This obviously compiles just fine, but when I launch the GWT app I get this:
ERROR: Errors in 'file:/C:/gwtproject/src/main/java/package/ClientSideClass.java'
ERROR: Line 119: No source code is available for type org.apache.commons.lang.StringEscapeUtils; did you forget to inherit a required module?
So the answer would be no, you can't use a wrapper like that.
Is there any other way of achieving that? I highly doubt it.
One of the main features of GWT is replacing the old AWT/Swing desktop GUI components with a whole set of web GUI components designed for Javascript compatibility; there's no point in making the old components available or supported in any way.
If you were talking about utility libraries like Apache Commons, I could advise you to make an RPC call instead (client-side calls server-side where you can use anything you like, and return the results asynchronously), but that's not the case.

Write code that works on Desktop and Android

I'm working on a project in Java that will most likely support Android in the future. But from what I know, Android has different classes/APIs than default Java (for example, I don't think android has all of the AWT stuff). So what I'm wondering, is how can I write my code so that if it is running on Android, it will use the android APIs, and if it is on a desktop, it use the standard Java APIs. I have looked into conditional imports, but unlike C++, that doesn't exist in Java. So how is this kind of thing solved in Java.
Here is an example of what I would like to be able to do:
int[] i;
if(onAnroid)
{
i = androidFoo.bar();
} else {
i = javaFoo.bar();
}
EDIT:
One thing I had thought of was using a Common class so I don't directly call the APIs. But What I was trying to figure out is how to call those classes of they aren't necessarily existent without the compiler complaining that the classes don't exist.
You can create architectural layers which are agnostic of any particular user-interface toolkit. If these need to interact with the user interface, they can do so through interface types.
Atop those layers, you can create multiple presentation layers with different toolkits.
Porting software to new user interfaces is common. Separating architectural layers from the beginning can cost little. De-tangling a monolith later can be expensive, sometimes to the point that it is economically infeasible for a company. Whether a requirement to port is certain, possible or unknown, it can be a good practice to separate architectural layers early.
You will have to separate your code, but not like this. Your classes need to be designed to separate the code that is platform dependent from the code it isn't. You should focus on keep the core logic of the application in one layer and render the objects on the screen in another layer.
Regarding not-necessarily existing classes you can call like this:
try {
MyObject o = (MyObject)Class.forName("org.me.MyObject").newInstance();
} catch(ClassNotFoundException x) {
// Here you know class does not exist
}
Actually, you should do better than this but I don't remember. But anyway similar to this.
Dependency Injection can probably serve your needs. There are several Frameworks out there: http://en.wikipedia.org/wiki/Dependency_injection#Frameworks_that_support_dependency_injection

Lightweight runtime "build system"

I've recently worked on refactoring a system that processes bundles of client data. The system executes a series of steps, each of which consumes files from previous steps (and sometime in-memory data), and produces its own output, in the form of files or data. Sometimes the output data for a particular step is already available. I have to be careful to make sure that, when one step fails, we continue to run all possible steps (ones that don't depend on the failed step), so that the final output is as complete as possible. Furthermore, not all steps have to be run in all situations.
Previously, the relationships were all implicit in the structure of the code. For instance:
void processClientData() {
try {
processA();
} catch(Exception e) {
log.log(Level.SEVERE, "exception occured in step A", e);
processC(); // C doesn't depend on A, so we can still run it.
throw e;
}
processB();
processC();
//etc... for ~20 steps
}
I changed this to make the dependencies explicit, the error handling uniform, etc, by introducing Tasks:
public interface Task {
List<Task> getDependencies();
void execute(); //only called after all dependencies have been executed
}
public class TaskRunner {
public void run(Set<Task> targets) {
// run the dependencies and targets ala ANT
// make sure to run all possible tasks on the "road" to targets
// ...
}
}
This starts to feel a lot like a very watered-down version of a build system with dependency management (ANT, being most familiar to me). I don't want to pull in ANT for this kind of thing, and I certainly don't want to write out the XML.
I have my system up and running (mostly), but it still feels a bit hacked together, and I have since reflected on how much I hate to be reinventing the wheel. I would expect that this is a fairly common problem - one that has been solved many times over by people smarter than me. Alas, a few hours of googling turned up nothing
Is there a library that implements this sort of thing, without being a really heavy-weight build system? I'd also appreciate any pointers, including libraries in other languages (or even novel systems) that I should take inspiration from.
EDIT: I appreciate the suggestions (and I will give them due consideration), but I'm really NOT looking for a "build system" per se. What I am looking for is something more like the kernel of a build system, that I could just call directly from Java and use as a small, low-overhead library for doing said dependency analysis, task execution, and resulting resource management. Like I said, I have existing (working) code in pure Java, and I don't want to bring in XML and all of the baggage that comes with it, without a very compelling reason.
At its core, a build system does 3 things. It manages dependency, it test whether something is "built" or not, and it "builds" the things that aren't built.
Dependency management is little more than a simple topological sort. There rest is iterating through the tasks in dependent order, and processing them.
You can readily create something like:
BuildSystem bs = new BuildSystem();
bs.addTask(new Task1());
bs.addTask(new Task...);
bs.addTask(new TaskN());
bs.build();
public void build() {
List<Task> sortedTasks = topologicalTaskSort(tasks);
for(Task t : sortedTasks) {
if (t.needsBuilding()) {
t.execute();
}
}
}
If you have no need to externalize the list of Tasks, then there's no reason for an XML file or anything.
The topological sort allows you to simply add tasks to the list and let the system sort things out. Not a problem with 4 tasks, more of an issue with dozens of tasks.
The sort fails if it detects a cycle of dependency, so that's where you get that control.
Something like this is "too simple" to need a framework. I don't know how you're doing your dependency management now.
Take a look at jsr166 fork/join framework. It seems to me this is exactly what you're trying to accomplish.
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ForkJoinTask.html
This is included in JDK7 but is available as a separate jar for 5 and 6. If I wasn't on my tablet I'd write a more comprehensive example. Maybe someone else can expand in the meantime.
public class DependencyTreeTask extends RecursiveAction {
private final List<DependencyTreeTask> dependencies = new ArrayList<Task>();
public void addDependency(DependencyTreeTask t) { dependencies.add(t) }
public void compute() {
invokeAll(dependencies);
}
}
...
// build tree...
DependencyTreeTask root = ...
ForkJoinPool pool = new ForkJoinPool();
pool.invoke(root);
You also have to take care if your graph is unconnected, but there are a well known set of algorithms for determining this.
I would consider writing a Maven plugin, it isn't that hard and much lighter weight because you only have to provide the relevant special logic. All the infrastructure is provided by Maven. Maven 3 would even give you things like parallel builds where your plugin supports it for free, amongst all the other things it provides.
One of the major goals of Maven 3 was a re-write to make it as easy as possible to embed the workflow engine in your own projects.
I've heard of Jenkins being used for this sort of thing in addition to it's primary 'build system' role. I only just started using Jenkins so can't say for sure whether it will do what you need. I'm impressed with it so far. It's relatively easy to use and has a lot of configuration options. There are a large number of plugins for it as well. Just run Jenkins and go to the plugins page to review the list and install them.
Your code reminds me of iwant, a java build engine I've been developing. You can declare your target definitions with dependencies using fluent java, and in addition to using it normally from a commandline (or ant script), you can also embed your build in a java program.

DLLs for a dynamic Java program?

I'm currently working on a Java project where I have a set of data which I wish to output in several custom formats. I have a class for each format, which takes the raw data and converts it accordingly. However, to begin with I am only implementing two or three of these formats, but wish to allow more formats to be added at a later date without having to do a massive rebuild of the application.
My idea was to create a DLL for each of the format classes, and have my application pass the data to be converted to each of these. This way, I can create a DLL later on and have my main application accessing it. (I would gladly listen to any alternative ways of doing this, as someone who has done this in C++/C# before this felt like the logical solution but it may not be applicable to Java)
My problem is that I have absolutely no idea how to do this - in C++/C# I could write this in a few lines of code but I'm not sure how it works with Java. At the risk of asking a terribly vague question, how can I do this?
Answers are greatly appreciated and cookies and tea will be offered. :)
Thanks in advance,
M
Edit: Sorry, just to add: I am also unsure how to create the DLL, which must be in Java for this project, to be read in the first place. Thanks. :)
Rather than using a DLL per se, it seems like what is wanted is a plugin architecture of some sort.
One reason why I wouldn't recommend using a DLL unless it is necessary is that linking Java code with native code will require using the Java Native Interface (JNI) which would probably require more effort than a pure Java solution.
One relatively simple way to do so is to use the reflection capabilities of Java.
From the information given, I would probably go along the lines of the following:
Define an interface for the output format.
Create a Java class implementing the interface.
Have the class available from the classpath.
Dynamically load the class using reflection. (Using the Class.newInstance method can instantiate objects from class files loaded by the ClassLoader.)
With these steps, it would be possible to implement a simplistic plugin which wouldn't require a full rebuild when support for a new format is required.
Step 1: Define the interface
Let's say we end up with an interface like the following:
public interface Outputter {
public void write(Data d);
}
Step 2: Make an implementation class
Then, we'll make an implementation class.
public class TextOutputter {
public void write(Data d) {
// ... output data to text
}
}
Then, compiling the above, we'll end up with a class file called TextOutputter.class.
Step 3: Make the class available from the classpath
When running the main application, we'll need to have the above TextOutputter.class in the classpath. Normally, one would tell the JVM a list of places to consider as the classpath, and that should include the above class file.
Once that is done, we should be able to load the above class using reflection.
Step 4: Dynamically load the class using reflection
Now, when we actually want to load the above class, we'd do something like the following:
// Note: We load the class by specifying the fully-qualified class name!
Class<?> clazz = Class.forName("TextOutputter");
// Then, we instantiate the class.
// Note that the following method will call the no-argument constructor.
Outputter outputter = clazz.newInstance();
// Now, we can give data to the TextOutputter object that we loaded dynamically.
outputter.write(...);
The Class.forName method is used to attempt to find the TextOutputter class from the default ClassLoader. Once we obtain the class as a Class representation, we can then instantiate an object of that class.
Instantiating the object can be performed by using the Class.newInstance method. If something other than the no-argument constructor should be used, the Constructor of the class would have to be obtained proceed to instantiate the object from there.
The object instantiates via reflection is then placed into a Outputter variable, so the write method can be called on the TextOutputter.
Adding more formats would entail the above process, but changing the fully-qualified class name (e.g. for String, the FQCN is java.lang.String) is all that is needed to load up a different class.
In a nutshell, that's what it will take to dynamically load class files and use it from your application.
(Just as a side note, I did not actually compile the above code, so there may be some errors here and there, but I hope I could illustrate the process it will take.)
I've made such things.
i created an open java based plugin architecture POJO based,that even did reload on the fly of updated plugin classes.
JNI is the interface for dealing with native code.
The only technical part was to rewrite a classloader that enabled DLL reloading dynamically at runtime.
But if you do only make "offline" updates, no such things are needed.
You can load a new DLL at any time with System.loadLibrary(). However you may need to load a java class for it to bind to.
You might find using an OSGi container helpful as this supports both load and unloading of modules (including shared libraries)
I would suggest using karaf with iPOJO but there are many others.
If you want write native codes (compiled to a DLL) to be used in java, you want to look at Java Native Interface (JNI).
Update you can use System.loadLibrary(String libName) (if you know the library name and the library path is set) or System.load(String filename) (library filename) to load library (DLL) in java.
I think you can ignore the JNI path. I have the impression you're using the term dll for lack of a better word, you don't really need a dll.
You could do the same thing in Java, but you'd put your filters in jar files instead of dll.
Define an interface for the file format filters to implement
Put each implementation into a jar, in a specific folder (like 'filters')
At one point in the app, iterate over the folder, generate classloader for the jars
Use reflection to find all implementations of your interface, and create a class for each
Call the methods to do their job
That's basically it.
Java SE 6 introduces the ServiceLoader class:
http://download.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html
If you want a proper modular approach consider the NetBeans Platform (especially if it is a desktop application) or OSGi.

Categories