JPF Questions & Answers
What kind of applications can I develop with JPF?
Where can I get plug-ins for JPF?
Why is JPF's plug-in manifest format different from the one used by Eclipse?
Why isn't there a UI provided for plug-in management?
What are the system requirements and dependencies for JPF?
Is there a way of hot-deploying plug-ins?
Is it possible to package JPF plug-in into a single JAR file?
What is it useful to know about plug-ins and classloaders?
The short answer is: ANY type of Java application. We are currently testing JPF with different types of applications and some other projects are helping with this. The first project is a simple GUI application, developed using the Java Swing API. It is available for download as a JPF demo application. The next project is a web site and services platform aimed at providing web developers and site maintainers (administrators, managers, content editors) with powerful tools to run web applications and maintain them from remote sites (with an HTML based UI, for example). This project is currently under serious development and will be publicly released soon (hopefully sometime in 2006). This project especially demonstrates how JPF can be very useful in J2EE applications. The last project is in the early design stages and is an SWT library based GUI application. This project is used to test how well JPF deals with native libraries.
JPF plug-ins are dependent on the main application being developed. While with a few lines of code JPF can be used as an effective tool to dynamically add any Java library to any application, JPF itself does not provide plug-ins. It only provides the FRAMEWORK for developing your own. That said, you can have a look at the plug-ins that come with the demo application as an example to get you started.
Your right! Making the JPF plug-in manifest compatible with Eclipse's would be convenient from a developers point of view. But unfortunately it is not so easy to implement :( The Eclipse team is moving very fast and it seems that they are moving to a completely OSGI plug-in model and making "XML based" plug-ins deprecated.
We like the original idea as it is simple and easy to understand. JPF has added several things to Eclipse's plug-in concept to make it as open for extensions as possible. All manifest related APIs exist as a set of interfaces and can be implemented by custom code. JPF believes that it is possible to develop an Eclipse-compatible manifest implementation and provide it as an additional module.
The UI is out of the framework scope. That is up to the applications that use JPF. JPF provides full information about plug-ins and runtime resources, to support application logic. Nevertheless, it may be possible that some functions, related to plug-in management, will be implemented as "tools" and be added to the JPF distribution package.
JPF requires a Java 1.3 compatible VM. It also uses the Jakarta Commons-logging library (included in the distribution package).
It is possible from version 0.4 and up! To register/deregister plug-ins while the application is running, use publishPlugins method in the PluginManager class or register() and unregister() methods in the PluginRegistry interface. To activate/deactivate registered plug-ins use the activatePlugin() and deactivatePlugin() methods in PluginManager class.
Note though that correct working of "hot deploy" functionality is dependent on cooperation between JPF and all plug-ins. In general, it is impossible to "unload" any Java class being used by at least one other "active" class. So plug-in developers need to keep in mind this aspect of Java class loading when developing plug-ins. The Framework provides and handles all required "services" to correctly "initialize" and "un-initialize" plug-in classes as well as to inform them about any changes to the plug-in manager and registry.
This is possible and not as difficult as it may seem. It can be done using the standard Java feature - "JAR URL" handler. Developers construct URL's that point to resources within a JAR file.
Note that not any plug-in can be packaged in such a way if you are using standard path resolver. The exceptions are plug-ins that contain other JAR's as libraries or native code libraries.
Starting from version 0.8 the "single file plug-ins" are fully supported by the various JPF tools. There is also a special Ant task to help building this type of plug-in and the JPF Boot Library was designed to support loading such plug-ins. If you need to load plug-ins manually (not using JPF Boot library) you may find it useful to use standard plug-in location implementation, it knows how to handle ZIP file or "plain folder style" plug-ins. Finally the special path resolver knows how to handle JAR'ed plug-ins even if they contain other JAR files or native libraries.
Generally speaking plug-in developers usually don't care how plug-ins management and classloading work. This might be useful to know for application core developers - those who implement base logic and core plug-ins.
JPF introduces concept of plug-ins and main part of this concept is classloaders isolation - each plug-in has it's own associated classloader that is responsible for managing resources of the plug-in (classes and other files). Plug-in's classloaders are organized in graph hierarchy that reflects dependencies between corresponding plug-ins.
The relations in classloaders hierarchy are used to delegate resource lookup requests from descendant classloader to ancestor one: first trying to load resource with current (this) classloader, next with ancestors and next with descendants (see reverse lookup mechanism bellow).
Java classloader API introduces another, it's own classloaders hierarchy - every classloader should have parent except
bootstrap classloader that is root of this hierarchy. All plug-ins in JPF have
system classloader as parent in Java API. This is the classloader that reflect your application CLASSPATH variable. By default, delegation in this hierarchy organized according to Java Language Specification - delegate loading request to parent classloader first and if this fails, try to load resource with this classloader using JPF hierarchy logic as described above. With special configuration parameter (see
probeParentLoaderLast parameter on configuration reference page) JPF allows to reverse this delegation logic: try to load resource with this classloader first and if fails delegate to parent.
Another useful feature of JPF classloading is "reverse lookup". Describing inter plug-ins dependencies in prerequisites section of manifest (see manifest DTD for details) you may specify that your plug-in "pluginB" depends on "pluginA" allowing "reverse lookup". What this mark will affect on? When classloader of "pluginA" will search for a resource, it will not only delegate loading request to parent classloader as described above but also try classloader of "pluginB" and all "reverse lookup" plug-ins ("children" classloaders). This trick allows creating plug-ins that can see classes not only in it's own libraries but in any depending plug-in also.
For those who want to deep into classloading in Java it is recommended to look through the following resources:
- Javadocs for java.lang.ClassLoader
- Classes lookup, initializing and loading related parts of Java Language Specification
- "Inside Class Loaders" article on http://www.onjava.com/pub/a/onjava/2003/11/12/classloader.html
- Source code of