Receiving notifications of class loader events
From JPPF 3.3 Documentation
Main Page > Customizing JPPF > Class loader listeners |
It is possible to receive notifications of whether a class was loaded or not found by a JPPF class loader. This can be done by implementing the interface ClassLoaderListener defined as follows:
public interface ClassLoaderListener extends EventListener { // Called when a class has been successfully loaded by a class loader void classLoaded(ClassLoaderEvent event); // Called when a class was not found by a class loader void classNotFound(ClassLoaderEvent event); }
Each notification provides an event object which is an instance of the class ClassLoaderEvent, defined as:
public class ClassLoaderEvent extends EventObject { // Get the class that was successfully loaded or null if the class was not found public Class<?> getLoadedClass() // Get the name of the class that was loaded or not found public String getClassName() // Determine whether the class was loaded from the class loader's URL classpath // If false, then the class was loaded from a remote JPPF driver or client public boolean isFoundInURLClassPath() // Get the class loader which emitted this event public AbstractJPPFClassLoader getClassLoader() }
Note that you may receive up to two notfications for the same class, due to the parent delegation model in the JPPF class loader hierarchy: when a node attempts to load a class from a client class loader (i.e. which accesses the classpath of a remote JPPF client), it will first delegate to its parent class loader, which is a driver class loader. As a result, the parent class loader will send a “classNotFound()” notification, and then the client class loader will send a second notification after it attempts to load the class from the client's classpath. Please refer to the Class loading in JPPF documentation for full details on how class loading works.
Once the implementation is done, the class loader listener is plugged into JPPF using the service provider interface:
- create a file in META-INF/services named "'org.jppf.node.classsloader.ClassLoaderListener"
- in this file, add the fully qualified class name of your implementation of the interface
- copy the jar file or class folder containing your implementation and service file to the classpath of each node.
As an example, let's say we simply want to print the notifications received by a listener, which we implement as follows:
package test; import org.jppf.classloader.*; public class MyClassLoaderListener implements ClassLoaderListener { @Override public void classLoaded(final ClassLoaderEvent event) { AbstractJPPFClassLoader cl = event.getClassLoader(); System.out.println("loaded " + event.getLoadedClass() + " from " + (cl.isClientClassLoader() ? "client" : "server") + " class loader in " + (event.isFoundInURLClasspath() ? "local" : "remote") + " classpath"); } @Override public void classNotFound(final ClassLoaderEvent event) { AbstractJPPFClassLoader cl = event.getClassLoader(); System.out.println("class " + event.getClassName() + " was not found by " + (cl.isClientClassLoader() ? "client" : "server") + " class loader"); } }
Then we create the file META-INF/services/org.jppf.node.classsloader.ClassLoaderListener with this content:
test.MyClassLoaderListener
All that remains to do is to package the class and service files into a jar and add this jar to the classpath of the nodes.
Main Page > Customizing JPPF > Class loader listeners |