I am looking for a way to do the following:
A Project :
Defines an abstract class that is called when some events happen (event handler if you will)
Defines the engine that will fire the events using the event handler above
B Project:
Defines the implementation for the abstract class
Runs the engine.
How can i register the implementation class and make sure that is the one being called when the engine runs.
EDIT 1: By register i mean i must somehow define which is the implementation that should be called for that given abstract object
Sorry if the question isn't too clear, let me know if you need some more details
Something like this?
class A implements EventHandlerForB {
...
}
public class B {
private EventHandlerForB eventHandler;
public void registerEventHandler(EventHandlerForB eventHandler) {
this.eventHandler = eventHandler;
}
...
}
public interface EventHandlerForB {
...
}
At runtime, you can have the name of the implementation passed in your A project (with a properties file or a Java system property).
Then you find this class in the classpath with class.forName() and instantiate it with newInstance().
But you'd prefer using a framework like Guice or Spring, that will allow you to glue stuff together in a clean way.
there are several "patterns" that try to address this issue. Using only JDK (6 or above) classes you may want to take a look at java.util.ServiceLoader
Related
I'm trying to develop a simple application using OSGi framework. My question involves an "utility bundle" available in the framework: let me explain with a pretty verbose example. At the moment I'm trying to build an event my bundle will send.
From what I understood, what i need is to do something like the following (event admin felix):
public void reportGenerated(Report report, BundleContext context)
{
ServiceReference ref = context.getServiceReference(EventAdmin.class.getName());
if (ref != null)
{
EventAdmin eventAdmin = (EventAdmin) context.getService(ref);
Dictionary properties = new Hashtable();
properties.put("title", report.getTitle());
properties.put("path" , report.getAbsolutePath());
properties.put("time", System.currentTimeMillis());
Event reportGeneratedEvent = new Event("com/acme/reportgenerator/GENERATED", properties);
eventAdmin.sendEvent(reportGeneratedEvent);
}
}
Now, since an OSGi application may have lots of bundles, I thought to create a subclass of Event for every bundle (eg. I have a bundle named "BundleExample"? Inside it's exported classes there will be a "BundleExampleEvent"). I know this doesn't add any information since you can know which event you received by looking at "topic", but please bear with me for the moment.
Now, the Event constructor needs a topic and a Map<String, Object>. However, to "simplify" the event constructor, I would like to have only the topic and the list of parameters to put inside the map. For example here's what might be a BundleExampleEvent class:
public class BundleExampleEvent extends Event{
private int importantVariable;
public BundleExampleEvent(String topic, int importantVariable) {
super(topic, Utils.toMap("importantVariable", importantVariable));
//here toMap is static
}
public int getImportantVariable() {
return this.importantVariable;
}
}
Ok, please note the Utils.toMap: it's a function that allows you to convert a sequence of String, Object into a Map. Ok, now Utils is an example of a utility class (stupid, useless but a utility class nonetheless). In the spirit of OSGi I want to make this utility class a bundle as well: my thought would be to start this Utils bundle at framework boot and then whenever I need one of its utility I want to fetch a reference via #Reference annotation.
This can work greatly in any bundle interface implementation, like this:
#Component
public class BundleExampleImpl implements BundleExample {
#Reference
private Utils utils;
#Override
public String sayHello() {
return this.utils.fetchHello();
//another useless utility function, but hopefully it conveys what i'm trying to do
}
}
But what about other classes (i.e. called by BundleExampleImpl during its work)? For example what about the BundleExampleEvent? I need to call it from sayHello method and I want to use this utility also inside that class in order to compute the Map! In the previous example i used a static function, but I would like to use the reference of Utils OSGi gave me.
Of course I could add a parameter inside the constructor of BundleExampleEvent in order to satisfy the link but I rather not to do it because it's pretty silly that something would depend on an "utility class"; my question are:
Is this the only method available if I want a "utility bundle"?
Or can I do something weird like adding a reference of Utils also in my BundleExampleEvent; i.e. something like this:
public class BundleExampleEvent extends Event{
#Reference
private Utils utils;
private int importantVariable;
public BundleExampleEvent(String topic, int importantVariable) {
super(topic, Utils.toMap("importantVariable", importantVariable));
//here toMap is static
}
public int getImportantVariable() {
return this.importantVariable;
}
}
Or maybe the whole idea of having an "utility bundle" is just pure trash?
Thanks for any reply. Hope I could convey my problem in the clearest way
I don't think there is any point in Utils being a service. Things should only be a service if they can conceivably have multiple implementations. In your case, the consumer of the Util functionality only ever wants a single implementation... the implementation is the contract.
I don't even think the utils code should be in a bundle. Just make it into a library that is statically linked into the bundles that need it.
In your case the Utils utils would be an OSGi service. Then you want to use this service inside an object that is not a service like BundleExampleEvent.
What you could do is to create a service that creates BundleExampleEvent instances and feeds it with an OSGi service. Kind of like a factory as a service. The problem with this is that services in OSGi are dynamic. If the service needed by the BundleExampleEvent instance goes away then the object would have to be discarded. So this only works for short lived objects.
In the eventadmin example a different solution would be to not use a special event class but instead create a service that has a method to send such an event. Then all the magic would happen inside this method and the result would be an event without further logic. You could also inject EventAdmin into that service using DS.
This works very well in OSGI but has the disadvantage of the anemic domain model (http://www.martinfowler.com/bliki/AnemicDomainModel.html).
I am not sure which variant to prefer.
Can I do it with reflection or something like that?
I have been searching for a while and there seems to be different approaches, here is a summary:
reflections library is pretty popular if u don't mind adding the dependency. It would look like this:
Reflections reflections = new Reflections("firstdeveloper.examples.reflections");
Set<Class<? extends Pet>> classes = reflections.getSubTypesOf(Pet.class);
ServiceLoader (as per erickson answer) and it would look like this:
ServiceLoader<Pet> loader = ServiceLoader.load(Pet.class);
for (Pet implClass : loader) {
System.out.println(implClass.getClass().getSimpleName()); // prints Dog, Cat
}
Note that for this to work you need to define Petas a ServiceProviderInterface (SPI) and declare its implementations. you do that by creating a file in resources/META-INF/services with the name examples.reflections.Pet and declare all implementations of Pet in it
examples.reflections.Dog
examples.reflections.Cat
package-level annotation. here is an example:
Package[] packages = Package.getPackages();
for (Package p : packages) {
MyPackageAnnotation annotation = p.getAnnotation(MyPackageAnnotation.class);
if (annotation != null) {
Class<?>[] implementations = annotation.implementationsOfPet();
for (Class<?> impl : implementations) {
System.out.println(impl.getSimpleName());
}
}
}
and the annotation definition:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.PACKAGE)
public #interface MyPackageAnnotation {
Class<?>[] implementationsOfPet() default {};
}
and you must declare the package-level annotation in a file named package-info.java inside that package. here are sample contents:
#MyPackageAnnotation(implementationsOfPet = {Dog.class, Cat.class})
package examples.reflections;
Note that only packages that are known to the ClassLoader at that time will be loaded by a call to Package.getPackages().
In addition, there are other approaches based on URLClassLoader that will always be limited to classes that have been already loaded, Unless you do a directory-based search.
What erickson said, but if you still want to do it then take a look at Reflections. From their page:
Using Reflections you can query your metadata for:
get all subtypes of some type
get all types annotated with some annotation
get all types annotated with some annotation, including annotation parameters matching
get all methods annotated with some
In general, it's expensive to do this. To use reflection, the class has to be loaded. If you want to load every class available on the classpath, that will take time and memory, and isn't recommended.
If you want to avoid this, you'd need to implement your own class file parser that operated more efficiently, instead of reflection. A byte code engineering library may help with this approach.
The Service Provider mechanism is the conventional means to enumerate implementations of a pluggable service, and has become more established with the introduction of Project Jigsaw (modules) in Java 9. Use the ServiceLoader in Java 6, or implement your own in earlier versions. I provided an example in another answer.
Spring has a pretty simple way to acheive this:
public interface ITask {
void doStuff();
}
#Component
public class MyTask implements ITask {
public void doStuff(){}
}
Then you can autowire a list of type ITask and Spring will populate it with all implementations:
#Service
public class TaskService {
#Autowired
private List<ITask> tasks;
}
The most robust mechanism for listing all classes that implement a given interface is currently ClassGraph, because it handles the widest possible array of classpath specification mechanisms, including the new JPMS module system. (I am the author.)
try (ScanResult scanResult = new ClassGraph().whitelistPackages("x.y.z")
.enableClassInfo().scan()) {
for (ClassInfo ci : scanResult.getClassesImplementing("x.y.z.SomeInterface")) {
foundImplementingClass(ci); // Do something with the ClassInfo object
}
}
With ClassGraph it's pretty simple:
Groovy code to find implementations of my.package.MyInterface:
#Grab('io.github.classgraph:classgraph:4.6.18')
import io.github.classgraph.*
new ClassGraph().enableClassInfo().scan().withCloseable { scanResult ->
scanResult.getClassesImplementing('my.package.MyInterface').findAll{!it.abstract}*.name
}
What erikson said is best. Here's a related question and answer thread - http://www.velocityreviews.com/forums/t137693-find-all-implementing-classes-in-classpath.html
The Apache BCEL library allows you to read classes without loading them. I believe it will be faster because you should be able to skip the verification step. The other problem with loading all classes using the classloader is that you will suffer a huge memory impact as well as inadvertently run any static code blocks which you probably do not want to do.
The Apache BCEL library link - http://jakarta.apache.org/bcel/
Yes, the first step is to identify "all" the classes that you cared about. If you already have this information, you can enumerate through each of them and use instanceof to validate the relationship. A related article is here: https://web.archive.org/web/20100226233915/www.javaworld.com/javaworld/javatips/jw-javatip113.html
Also, if you are writing an IDE plugin (where what you are trying to do is relatively common), then the IDE typically offers you more efficient ways to access the class hierarchy of the current state of the user code.
I ran into the same issue. My solution was to use reflection to examine all of the methods in an ObjectFactory class, eliminating those that were not createXXX() methods returning an instance of one of my bound POJOs. Each class so discovered is added to a Class[] array, which was then passed to the JAXBContext instantiation call. This performs well, needing only to load the ObjectFactory class, which was about to be needed anyway. I only need to maintain the ObjectFactory class, a task either performed by hand (in my case, because I started with POJOs and used schemagen), or can be generated as needed by xjc. Either way, it is performant, simple, and effective.
A new version of #kaybee99's answer, but now returning what the user asks: the implementations...
Spring has a pretty simple way to acheive this:
public interface ITask {
void doStuff();
default ITask getImplementation() {
return this;
}
}
#Component
public class MyTask implements ITask {
public void doStuff(){}
}
Then you can autowire a list of type ITask and Spring will populate it with all implementations:
#Service
public class TaskService {
#Autowired(required = false)
private List<ITask> tasks;
if ( tasks != null)
for (ITask<?> taskImpl: tasks) {
taskImpl.doStuff();
}
}
I am working on GWT project with JDK7. It has two entryPoints (two clients) that are located in separate packages of the project. Clients share some code that is located in /common package, which is universal and accessible to both by having the following line in their respective xml-build files:
<source path='ui/common' />
Both clients have their own specific implementations of the Callback class which serves their running environments and performs various actions in case of failure or success. I have the following abstract class that implements AsyncCallback interface and then gets extended by its respective client.
public abstract class AbstractCallback<T> implements AsyncCallback<T> {
public void handleSuccess( T result ) {}
...
}
Here are the client's classes:
public class Client1Callback<T> extends AbstractCallback<T> {...}
and
public class Client2Callback<T> extends AbstractCallback<T> {...}
In the common package, that also contains these callback classes, I am working on implementing the service layer that serves both clients. Clients use the same back-end services, just handle the results differently. Based on the type of the client I want to build a corresponding instance of AbstractCallback child without duplicating anonymous class creation for each call. I am going to have many declarations that will look like the following:
AsyncCallback<MyVO> nextCallback = isClient1 ?
new Client1Callback<MyVO>("ABC") {
public void handleSuccess(MyVO result) {
doThatSameAction(result);
}
}
:
new Client2Callback<MyVO>("DEF") {
public void handleSuccess(MyVO result) {
doThatSameAction(result);
}
};
That will result in a very verbose code.
The intent (in pseudo-code) is to have the below instead:
AsyncCallback<MyVO> nextCallback = new CallbackTypeResolver.ACallback<MyVO>(clientType, "ABC"){
public void handleSuccess(MyVO result) {
doThatSameAction(result);
}
};
I was playing with the factory pattern to get the right child instance, but quickly realized that I am not able to override handleSuccess() method after the instance is created.
I think the solution may come from one of the two sources:
Different GWT way of dealing with custom Callback implementations, lets call it alternative existent solution.
Java generics/types juggling magic
I can miss something obvious, and would appreciate any advice.
I've read some articles here and on Oracle about types erasure for generics, so I understand that my question may have no direct answer.
Refactor out the handleSuccess behavior into its own class.
The handleSuccess behavior is a separate concern from what else is going on in the AsyncCallback classes; therefore, separate it out into a more useful form. See Why should I prefer composition over inheritance?
Essentially, by doing this refactoring, you are transforming an overridden method into injected behavior that you have more control over. Specifically, you would have instead:
public interface SuccessHandler<T> {
public void handleSuccess(T result);
}
Your callback would look something like this:
public abstract class AbstractCallback<T> implements AsyncCallback<T> {
private final SuccessHandler<T> handler; // Inject this in the constructor
// etc.
// not abstract anymore
public void handleSuccess( T result ) {
handler.handleSuccess(result);
}
}
Then your pseudocode callback creation statement would be something like:
AsyncCallback<MyVO> nextCallback = new CallbackTypeResolver.ACallback<MyVO>(
clientType,
"ABC",
new SuccessHandler<MyVO>() {
public void handleSuccess(MyVO result) {
doThatSameMethod(result);
}
});
The implementations of SuccessHandler don't have to be anonymous, they can be top level classes or even inner classes based on your needs. There's a lot more power you can do once you're using this injection based framework, including creating these handlers with automatically injected dependencies using Gin and Guice Providers. (Gin is a project that integrates Guice, a dependency injection framework, with GWT).
Here's a problem I am facing.
I am writing a plugin. There is an interface called SystemObject, and a default getter.
public class MyPlugin extends Plugin {
#override
public SystemObject getSystemObject() {
return super.getSystemObject();
}
}
SystemObject interface has a method called getScreenSize() which I would like to proxy or intercept. When I create a proxy class, or simply implement this SystemObject interface myself, I get a class cast exception.
This is because the caller for getSystemObject (part of the plugin system) has this in their code (found via reverse-engineering):
private void foo() {
SystemObjectImpl impl = (SystemObjectImpl)plugin.getSystemObject();
}
My question is: is there any way I can proxy calls on the SystemObject interface?
I tried implementing the interface and using java reflection proxy invocation to no avail. Unfortunately, I'm not responsible for running the java process, so I can't use an agent.
Cheers!
You could use something like CGLIB to create a proxy class that extends SystemObjectImpl.
i'm just learning java, and i meet some problems.
Here we have simple factory pattern:
public class SomeFactory {
...
public static void registerProduct(String name, Class<? extends IProduct > f)
}
public SomeProduct implements IProduct {
static {
SomeFactory.register("some product", SomeProduct.class);
}
...
}
All products should register themselves at factory.
But before using this code, all Products classes should be loaded.
I can put Class.forName() somewhere, for example in main function.
But i want to avoid such sort of manual classes loading. I want just add new IProduct
implementations, without updating other parts(such as SomeFactory or Main methods, etc.).
But i wonder, is it possible to automatically load some classes(marked with annotation, for example)?
P.S I want to notice, that no other classes will be added at run-time, all IProduct implementations are known before compiling.
UPD#1
Thank for your answering!
But is it possible to make auto-generated property-file with IProduct instances?
I mean is it possible to make some build-time script(for maven for example) that generates property-file or loader code? Are there such solutions or frameworks?
UPD#2
I finished with using Reflections library that provides run-time information, by scanning classpath at startup.
This is possible, but not easily. It would need to scan all the classes in the classpath to see if they have an annotation or implement the IProduct interface. See How do you find all subclasses of a given class in Java? for answers to such a problem.
I would do keep it simple and just have a list of classes to load, either in the factory itself, or in an external file (properties file, for example).
Have each product register itself, using a static block like this:
class MyProduct1{
static{
SomeFactory.register(MyProduct1.getClass());
}
..
..
}
An external property file can keep track of all Products.
Your main method can parse this list of Products and do a Class.forName("..").
This way you wouldnt need to code any specific product, just the property file keeps changing. Ah! yes adding security registration would also be a plus point.
Note: I'm just proposing an idea, I'vent tried it myself :)