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();
}
}
Related
The Adobe AEM software provides several classes which can take an apache Sling Resource and adapt it to another class like so:
Page page = resource.adaptTo(Page.class);
To use this syntax with classes that you author and control this boils down to simply implementing the Adaptable interface.
However, if you want to enable a Resource to adaptTo your new custom class, is seems that you have to implement the AdapterFactory interface and register it in OSGI.
This is how the Adobe website describes it:
By an AdapterFactory, which can map arbitrary objects.
The objects must still implement the Adaptable interface and must extend SlingAdaptable (which passes the adaptTo call to a central adapter manager).
This allows hooks into the adaptTo mechanism for existing classes, such as Resource.
I have walked through the SlingScriptAdapterFactory code, but ultimately I am not connecting the dots here. Basically I want to do this:
MyClass myClass = Resource.adaptTo(MyClass.class);
Do I create a class that implements AdapterFactory and simply deploy it with the package expecting that Sling will just find it by type or is there more to it?
Here is a little bit better documentation https://sling.apache.org/documentation/the-sling-engine/adapters.html
So you should implement the Adaptable interface, as you already described. Then create a properly annotated AdapterFactory:
#Component
#Service(value=org.apache.sling.api.adapter.AdapterFactory.class)
#Properties({
#Property(name = "adaptables", value = { "org.apache.sling.api.resource.Resource" }),
#Property(name = "adapters", value = { "org.sling.MyClass" })
})
public class MyAdapterFactory implements AdapterFactory{
public <AdapterType> AdapterType getAdapter(final Object adaptable, Class<AdapterType> type){
return new MyClassAdapter(adaptable);
}
}
Note that I've been working on a simpler way to create Sling adapters, by annotating methods with a new #Adapter annotation, as in
#Component
#Service
public class C implements AdapterMethodsProvider {
#Adapter
public CustomerRecord convert(Resource r) { ... }
#Adapter
public Person adaptToPerson(Resource r) { ... }
}
See https://issues.apache.org/jira/browse/SLING-2938 for details, but note that this is not even in the Sling trunk yet, so it will take some time before it's released and available in AEM/CQ.
I'm reviewing Guice. Let's say I've got the following setup:
public interface IsEmailer {...}
public interface IsSpellChecker {...}
public class Emailer implements IsEmailer {
#Inject
public class Emailer(final IsSpellChecker spellChecker)....
}
public class FrenchSpellChecker implements IsSpellChecker {....}
public class EnglishSpellChecker implements IsSpellChecker {....}
#BindingAnnotation public #interface English {}
#BindingAnnotation public #interface French {}
Then in my module I've bound the interfaces to their respective implementations, and annotated the spell checkers with the respective binding-annotation.
Now, let's say based on a runtime variable I need to construct an emailer that either uses the English or the French spell checker.
I thought of using a named providers in my module:
#Provides
#English
IsEmailer provideEnglishEmailer() {
return new Emailer(new EnglishSpellChecker());
}
#Provides
#French
IsEmailer provideFrenchEmailer() {
return new Emailer(new FrenchSpellChecker());
}
This works like this:
IsEmailer emailer = myModule.getInstance(Key.get(IsEmailer.class,
French.class));
Is this the cleanest way to do something like this? After all, I'm forced to construct the object by hand (in the providers).
Thanks
First some notes:
Generally you want to avoid using getInstance as much as possible, except for your "root" element (e.g. YourApplication). Within anything that Guice provides, your best bet is to ask for an injection of Provider<IsEmailer>, or perhaps #English Provider<IsEmailer> and #French Provider<IsEmailer>. Guice will not actually create the elements until you call get on the Provider, so the overhead of creating the Provider is very very light.
You don't have to bind to a provider to get a provider. Guice will resolve any binding of X, Provider<X>, or #Provides X to any injection of X or Provider<X> automatically and transparently.
Provider implementations can take injected parameters, as can #Provides methods.
If you want to bind a lot of things to #English or #French, you may also investigate private modules, since this sounds like the "robot legs" problem to me.
The easiest way is simply to go with the first bullet and inject a Provider of each, especially if you're only doing this once.
You can also bind it in a Module, if your runtime variable is accessible via Guice. Put this in your module along with the #Provides annotations above. (As noted, you may want to rewrite them to accept an EnglishSpellChecker and FrenchSpellChecker as parameters respectively, to enable the spell checkers to inject their own dependencies.)
#Provides IsEmailer provideEmailer(Settings settings,
#English Provider<IsEmailer> englishEmailer,
#French Provider<IsEmailer> frenchEmailer) {
if (settings.isEnglish()) {
return englishEmailer.get();
} else {
return frenchEmailer.get();
}
}
You could use a MapBinder. That would allow you to inject a Map<Language, IsSpellChecker>, and then retrieve the appropriate spell checker at runtime.
I better explain the question with an example.
I have an Interface Model which can be used to access data.
There can be different implementations of Model which can represent the data in various format say XMl , txt format etc. Model is not concerned with the formats.
Lets say one such implementation is myxmlModel.
Now i want to force myxmlModel and every other implementation of Model to follow Singleton Pattern.The usual way is to make myxmlModels constructor private and provide a static factory method to return an instance of myModel class.But the problem is interface cannot have static method definitions and a result i cannot enforce a particular Factory method definition on all implementation of Model. So one implementation may end with providing getObject() and other may have getNewModel()..
One work around is to allow package access to myxmlModel's constructor and create a Factory class which creates the myxmlModel object and cache it for further use.
I was wondering if there is a better way to achieve the same functionality .
Make a factory that returns
instances of your interface, Model.
Make all concrete implementations of the model package-private classes
in the same package as your factory.
If your model is to be a singleton, and you are using java
5+, use enum instead of traditional
singleton, as it is safer.
public enum MyXMLModel{
INSTANCE();
//rest of class
};
EDIT:
Another possibility is to create delegate classes that do all the work and then use an enum to provide all of the Model Options.
for instance:
class MyXMLModelDelegate implements Model {
public void foo() { /*does foo*/}
...
}
class MyJSONModelDelegate implements Model {
public void foo() { /*does foo*/ }
...
}
public enum Models {
XML(new MyXMLModelDelgate()),
JSON(new MyJSONModelDelegate());
private Model delegate;
public Models(Model delegate) { this.delegate=delegate; }
public void foo() { delegate.foo(); }
}
You can use reflection. Something like this:
public interface Model {
class Singleton {
public static Model instance(Class<? extends Model> modelClass) {
try {
return (Model)modelClass.getField("instance").get(null);
} catch (blah-blah) {
blah-blah
}
}
}
public class XmlModel implements Model {
private static final Model instance = new XmlModel();
private XmlModel() {
}
}
usage:
Model.Singleton.instance(XmlModel.class)
Actually, I don't like this code much :). First, it uses reflection - very slow, second - there are possibilities of runtime errors in case of wrong definitions of classes.
Can you refactor the interface to be an abstract class? This will allow you to force a particular factory method down to all implementing classes.
I used to ask myself the same question. And I proposed the same answer ;-)
Now I normally drop the "forcing" behavior, I rely on documentation.
I found no case where the Singleton aspect was so compelling that it needed to be enforced by all means.
It is just a "best-practice" for the project.
I usually use Spring to instanciate such an object,
and it is the Spring configuration that makes it a Singleton.
Safe, and so easy ... plus additionnal Spring advantages (such as Proxying, substituing a different object once to make some tests etc...)
This is more an answer to your comment/clarification to kts's answer. Is it so, that the real problem is not using the Singleton pattern but instead defining an eclipse (equinox) extension point schema that allows contributing a singleton?
I think, this can't be done, because everytime you call IConfigurationElement.createExecutableExtension you create a new instance. This is quite incompatible with your singleton requirement. And therefore you need the public default constructor so that everybody can create instances.
Unless you can change the extension point definition so that plugins contribute a ModelFactory rather than a model, like
public interface ModelFactory {
public Model getModelInstance();
}
So the extension user will instantiate a ModelFactory and use it to obtain the singleton.
If I guessed wrong, leave a comment and I delete the answer ;)
I refer to "service provider framework" as discussed in Chapter 2 of Effective Java, which seems like exactly the right way to handle a problem I am having, where I need to instantiate one of several classes at runtime, based on a String to select which service, and an Configuration object (essentially an XML snippet):
But how do I get the individual service providers (e.g. a bunch of default providers + some custom providers) to register themselves?
interface FooAlgorithm
{
/* methods particular to this class of algorithms */
}
interface FooAlgorithmProvider
{
public FooAlgorithm getAlgorithm(Configuration c);
}
class FooAlgorithmRegistry
{
private FooAlgorithmRegistry() {}
static private final Map<String, FooAlgorithmProvider> directory =
new HashMap<String, FooAlgorithmProvider>();
static public FooAlgorithmProvider getProvider(String name)
{
return directory.get(serviceName);
}
static public boolean registerProvider(String name,
FooAlgorithmProvider provider)
{
if (directory.containsKey(name))
return false;
directory.put(name, provider);
return true;
}
}
e.g. if I write custom classes MyFooAlgorithm and MyFooAlgorithmProvider to implement FooAlgorithm, and I distribute them in a jar, is there any way to get registerProvider to be called automatically, or will my client programs that use the algorithm have to explicitly call FooAlgorithmRegistry.registerProvider() for each class they want to use?
I think you need to create a META-INF/services/fully.qualified.ClassName and list things there, but I don't remember the spec (JAR File Specification or this).
The Practical API design confessions of a Java architect book chapter 8 is about SPI.
The ServiceLoader might help you to list available implementations. For example with the PersistenceProvider interface:
ServiceLoader<PersistenceProvider> loader =
ServiceLoader.load(PersistenceProvider.class);
Iterator<PersistenceProvider> implementations = loader.iterator();
while(implementations.hasNext()) {
PersistenceProvider implementation = implementations.next();
logger.info("PersistenceProvider implementation: " + implementation);
}
You could have the client JAR register the providers in a static initializer block within some class that you know will be called before FooAlgorithmRegistry.getProvider(), something like:
static {
FooAlgorithmRegistry.registerProvider("test", new MyFooAlgorithmProvider());
}
But, it might be pretty hard to find a way to guarantee that this will run (static initializers are guaranteed to be run once and only once, when the class is first loaded) before the accessor method of the factory.
Is there any way to require that a class have a default (no parameter) constructor, aside from using a reflection check like the following?
(the following would work, but it's hacky and reflection is slow)
boolean valid = false;
for(Constructor<?> c : TParse.class.getConstructors())
{
if(c.getParameterTypes().length == 0) {
valid = true;
break;
}
}
if(!valid)
throw new MissingDefaultConstructorException(...);
You can build an Annotation processor for that. Annotation Processors are compiler plugins that get run at compile time. Their errors show up as compiler errors, and may even halt the build.
Here is a sample code (I didn't run it though):
#SupportedAnnotationTypes("*") // needed to run on all classes being compiled
#SupportedSourceVersion(SourceVersion.RELEASE_6)
public class DefaultConstructor extends AbstractProcessor {
#Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
for (TypeElement type : ElementFilter.typesIn(roundEnv.getRootElements())) {
if (requiresDefaultConstructor(type))
checkForDefaultConstructor(type);
}
return false;
}
private void checkForDefaultConstructor(TypeElement type) {
for (ExecutableElement cons :
ElementFilter.constructorsIn(type.getEnclosedElements())) {
if (cons.getParameters().isEmpty())
return;
}
// Couldn't find any default constructor here
processingEnv.getMessager().printMessage(
Diagnostic.Kind.ERROR, "type is missing a default constructor",
type);
}
private boolean requiresDefaultConstructor(TypeElement type) {
// sample: require any JPA Entity to have a default constructor
return type.getAnnotation(Entity.class)) != null
|| type.getQualifiedName().toString().contains("POJO");
}
}
The annotation processor becomes even easier if you introduce an annotation (e.g. RequiresDefaultAnnotation).
Declaring the requirement of having a default qualifier
::I am also assuming that the OP asking for a mechanism that prevents accidental errors for developers, especially written by someone else.::
There has to be a mechanism to declare which classes require a default processor. Hopefully, you already have a criteria for that, whether it is a pattern in the name, pattern in the qualifier, a possible annotation, and/or a base type. In the sample I provided above, you can specify the criteria in the method requiresDefaultConstructor(). Here is a sample of how it can be done:
Based on a name pattern. TypeElement provide access to the fully qualified name and package name.
return type.getQualifiedName().toString().contains("POJO");
Based on an annotation present on the type declaration. For example, all Java Bean Entity classes should have a non-default constructors
return type.getAnnotation(Entity.class) != null;
Based on a abstract class or interface.
TypeElement basetype = processingEnv.getElements().getTypeElement("com.notnoop.mybase");
return processingEnv.getTypes().isSubtype(type.asType(), basetype.asType());
[Recommended Approach]: If you are using the basetype interface, I recommend mixing the annotation approach with the base type interface. You can declare an annotation, e.g. MyPlain, along with the meta annotation: #Inherited. Then you can annotate the base type with that annotation, then all subclasses would inherit the annotation as well. Then your method would just be
return type.getAnnotation(MyPlain.class) != null;
This is better because it's a bit more configurable, if the pattern is indeed based on type hierarchy, and you own the root class.
As mentioned earlier, just because it is called "annotation processing", it does mean that you have to use annotations! Which approach in the list you want to follow depends on your context. Basically, the point is that whatever logic you would want to configure in your deployment enforcement tools, that logic goes in requiresDefaultConstructor.
Classes the processor will run on
Annotation Processors invocation on any given class depends on SupportedAnnotationTypes. If the SupportedAnnotationTypes meta-annotation specifies a concrete annotation, then the processor will only run on those classes that contain such annotation.
If SupportedAnnotationTypes is "*" though, then the processor will be invoked on all classes, annotated or not! Check out the [Javadoc](http://java.sun.com/javase/6/docs/api/javax/annotation/processing/Processor.html#getSupportedAnnotationTypes()), which states:
Finally, "*" by itself represents the
set of all annotation types, including
the empty set. Note that a processor
should not claim "*" unless it is
actually processing all files;
claiming unnecessary annotations may
cause a performance slowdown in some
environments.
Please note how false is returned to ensure that the processor doesn't claim all annotations.
No. The above check can be easier rewritten as:
try {
MyClass.newInstance();
} catch (InstantiationException E) {
// no constructor
} catch (IllegalAccessException E) {
// constructor exists but is not accessible
?
You can employ PMD and Macker in order to guarantee architectural rules.
In partilar, Macker provokes compilation errors, breaking your build process when validations fail.
Macker extends some concepts made popular by PMD regarding validations of source code. A good example is when you'd like to guarantee that all classes from a package implements a certain interface.
So, if you are very paranoid (like me!) about verifying all possible architectural rules, Macker is really useful.
http://innig.net/macker/
Note: The website is not great. Colors will hurt your eyes... but the tools is very useful anyway.
Richard Gomes
http://www.jquantlib.org/