Querying classes with arbitrary properties in Java classpath using the Reflections library - java

I have used in the past the Reflections library to query classes in my classpath having a particular annotation, or inheriting from a particular class.
This is very easy to do with Reflections since the library already provide methods that answer such specific queries.
For example, the code below illustrates how to query classes inheriting from SomeType and classes annotated with SomeAnnotation, looking for classes located in the package my.package.prefix (example taken from the documentation of the Reflection.java class):
Reflections reflections = new Reflections("my.package.prefix");
Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(SomeAnnotation.class);
However, in my current problem what I need to do is querying for classes having an arbitrary set of properties (e.g., a combination of a particular class name + existing annotations + whatever ). I do not know these properties in advance since they should be defined by the programmer using the library I am developing.
I envision that part of the solution will be something like asking the programmer to define a Strategy class with a boolean method answering if the class should be in the answer set or not.
For example, the programmer should implement an interface similar to:
public interface MyStrategy {
public boolean match(Class clazz);
}
So my question is, once I have this strategy object, how I can instruct the Reflections library to filter classes keeping only those that match according to the strategy class defined by the programmer ?
UPDATE:
Apparently the filtering part is not the most difficult task (thanks for the answer #MvG) but actually gathering all the classes to be filtered (typically classes in a set of base packages defined by the programmer).
So the idea is querying all the classes and then filtering them with the method:
ReflectionUtils.getAll(allClasses, predicate).
Then, in order to obtain the initial set of classes to be filtered, I tried with querying all the subtypes of Object in a particular package chosen by the programmer.
Below the code I used for this:
ConfigurationBuilder config = new ConfigurationBuilder();
FilterBuilder fb = new FilterBuilder();
fb.include(FilterBuilder.prefix("my.package.prefix"));
config.filterInputsBy(fb);
config.setUrls(ClasspathHelper.forPackage("my.package.prefix"));
config.setScanners(new SubTypesScanner(false)); //the first argument at the constructor of SubTypesScanner indicates if the Object class should be ignored
Reflections reflections = new Reflections(config);
Set<Class<? extends Object>> unfilteredClasses = reflections.getSubTypesOf(Object.class);
Is this the best (more efficient) solution ?
Does someone have any alternative idea ?. Thanks in advance !

Use com.google.common.base.Predicate to express your strategies, or wrap your own strategy objects into such predicates. Then you can write
ReflectionUtils.getAll(allClasses, predicate);
It seems that actually computing this allClasses iterable is going to be the more demanding task. I see no simple API for that at first glance. You'll probably have to access the underlying store directly, and turn class names to Class objects yourself. That means loading all the classes, which might be quite time-consuming, and might even fail in certain scenarios.

Related

correct way to instantiate bunch of classes at once

I have a class Main.java in which I need to instantiate a bunch of other classes say C1.java ... C50.java. I am not able to think of an elegant way to instantiate these 50 classes in Main class. If I simply put all instantiating code in one place it looks so crowded and ugly. Today I have 50 classes to instantiate, tomorrow this count can increase to 100, then this situation will get worse. Can you please suggest an elegant way of instantiating all these classes without making Main class crowded with instantiation code. I am not aware of any design pattern to do this.
I am thinking to create an array of classes that needs to be instantiated and use reflection to instantiate them.
The answer depends on what purpose the classes would serve. However, if you don't mind to end up with an unordered collection of instantiated classes, there is a way to go using Reflections library and I guess also a shorted one in the matter of lines of code:
// find out all the classes implementing MyInterface
Set<Class<? extends MyInterface>> subTypes = reflections.getSubTypesOf(MyInterface.class);
// iterate those classes and instntinate them
List<MyInterface> objects = new ArrayList<>();
for (Class<? extends MyInterface> clazz: subtypes) {
objects.add(clazz.newInstance());
}
In any case, the whole design should be rethough.
The recommended solution is to use the service loader architecture.
Instantiating all registered implementations of MyInterface can be done as simple as
for(MyInterface my: ServiceLoader.load(MyInterface.class)) {
/* do something with <my> */
}
To make this work, its not enough to just implement the interface, these implementations must be declared as service providers, either via an entry in META-INF/services/ of your jar file (as described in the linked class documentation) or via provides declaration within a Java module declaration when using Java 9 or newer.
The advantage of this is not only a higher performance, compared to searching the entire class path with a reflection library, it also ensures that the necessary access rights are established when using Java’s module system in the future.
See also Java 9’s version of the class documentation.

Framework to populate common field in unrelated classes

I'm attempting to write a framework to handle an interface with an external library and its API. As part of that, I need to populate a header field that exists with the same name and type in each of many (70ish) possible message classes. Unfortunately, instead of having each message class derive from a common base class that would contain the header field, each one is entirely separate.
As as toy example:
public class A
{
public Header header;
public Integer aData;
}
public class B
{
public Header header;
public Long bData;
}
If they had designed them sanely where A and B derived from some base class containing the header, I could just do:
public boolean sendMessage(BaseType b)
{
b.header = populateHeader();
stuffNecessaryToSendMessage();
}
But as it stands, Object is the only common class. The various options I've thought of would be:
A separate method for each type. This would work, and be fast, but the code duplication would be depressingly wasteful.
I could subclass each of the types and have them implement a common Interface. While this would work, creating 70+ subclasses and then modifying the code to use them instead of the original messaging classes is a bridge too far.
Reflection. Workable, but I'd expect it to be too slow (performance is a concern here)
Given these, the separate method for each seems like my best bet, but I'd love to have a better option.
I'd suggest you the following. Create a set of interfaces you'd like to have. For example
public interface HeaderHolder {
public void setHeader(Header header);
public Header getHeader();
}
I'd like your classes to implement them, i.e you's like that your class B is defined as
class B implements HeaderHolder {...}
Unfortunately it is not. Now problem!
Create facade:
public class InterfaceWrapper {
public <T> T wrap(Object obj, Class<T> api) {...}
}
You can implement it at this phase using dynamic proxy. Yes, dynamic proxy uses reflection, but forget about this right now.
Once you are done you can use your InterfaceWrapper as following:
B b = new B();
new IntefaceWrapper().wrap(b, HeaderHolder.class).setHeader("my header");
As you can see now you can set headers to any class you want (if it has appropriate property). Once you are done you can check your performance. If and only if usage of reflection in dynamic proxy is a bottleneck change the implementation to code generation (e.g. based on custom annotation, package name etc). There are a lot of tools that can help you to do this or alternatively you can implement such logic yourself. The point is that you can always change implementation of IntefaceWrapper without changing other code.
But avoid premature optimization. Reflection works very efficiently these days. Sun/Oracle worked hard to achieve this. They for example create classes on the fly and cache them to make reflection faster. So probably taking in consideration the full flow the reflective call does not take too much time.
How about dynamically generating those 70+ subclasses in the build time of your project ? That way you won't need to maintain 70+ source files while keeping the benefits of the approach from your second bullet.
The only library I know of that can do this Dozer. It does use reflection, but the good news is that it'll be easier to test if it's slow than to write your own reflection code to discover that it's slow.
By default, dozer will call the same getter/setters on two objects even if they are completely different. You can configure it in much more complex ways though. For example, you can also tell it to access the fields directly. You can give it a custom converter to convert a Map to a List, things like that.
You can just take one populated instance, or perhaps even your own BaseType and say, dozer.map(baseType, SubType.class);

Factory class that automatically loads subclasses of specific superclass in Java?

Before I describe my problem let my say that I suspect I might simply lack the correct terms to search for, and that's why my searches here on stackoverflor haven't been fruitful. So links to answers would also be very much appreciated.
Im trying to make a library that has a Factory, lets call it "MyFactory". MyFactory has a method that returns objects of the abstract class "MySuper", but also one that exposes the avilable subclasses to "MySuper". The library is intended to be expanded on a lot, so subclasses of "MySuper" will be added often, and then library will be recompiled, and dumped into a library folder of the application that uses it.
What I want is to be able to add a subclass of "MySuper" to the library, and have "MyFactory" become aware of it, preferebly without having to do anything else than create a new sublass of "MySuper"..
So far I use reflection to make "MyFactory" create new instances of a "MySuper" type, by giving the class name to a method, like this:
public MySuper getSuperObject(String name) {
return (MySuper) Class.forName("my.package." + name).newInstance(); }
But how can I get the factory to expose alle the "MySuper" classes as f.x. a List of String, so the applications that use the library know what they can call? Can I iterate the content of a package?
I'm open for solutions, the most important part is that in the future it should be very hassle free to add new "MySuper" sub-classes..
Thanks :-)
UPDATE:
I just want to note that I have found a nice Java library that handles reflection in an easy way, and lets you search for subtypes of a specific class. So my problem can be solved with that library (I have tested it). Here is a link: http://code.google.com/p/reflections/
You are looking for a Generic Factory Pattern. Something like..
public static <T extends MySuper> T createDocument(Class<T> subClazz) throws InstantiationException, IllegalAccessException {
return subClazz.newInstance();
};
You may google for Generic Factory Pattern and you will find lots of examples.
The default class loader knows nothing about a class until it searches for it. It then looks in several places depending on the class path. If you depend on the class loader you will not be able to get the class into the list until it has already been asked for by name.
The most automatic solution may be to designate a location, such as a directory, for new classes extending MySuper. To construct the list of classes, look in that directory for class files, and use your favorite bytecode library to check them for classes that extend MySuper.
Another option is to have a configuration file that lists the extending class names.
I suggest creating an enum that contains the possible subclasses to MySuper. whenever you add a subclass add an entry in the enum for the same and then you can give that as an input to the getMySuperObject() method.
do comment if u think i have left something in this solution

Use of TypeLiteral in java

Please provide some basic information of how TypeLiteral in Google Guice or Java EE is used, It will be very helpful if it would be explained using a simple code, thanks in advance
The purpose of TypeLiteral in Guice is to allow you to bind classes and instances to generic types (with type parameters specified) avoiding the problems stemming from the fact that generics are not reified in Java, i.e. from the fact that erasure hides the difference between SomeInterface<String> and SomeInterface<Integer> at runtime. TypeLiteral allows the value of a generic parameter survive erasure by creating an ad hoc subclass of the generic type.
Example usage of TypeLiteral:
bind(new TypeLiteral<SomeInterface<String>>(){})
.to(SomeImplementation.class);
This binds a parameter of type SomeInterface<String> to SomeImplementation class.
For some background information have a look at this blog post on super type tokens and then this one on type literals.
Like anything in Guice - modularity, reusability, and removal of boilerplate are core concepts of all utilities.
Of course, anything you do in Guice can be mimicked in Java - at the cost of lots of boilerplate So... the real question is :
How can we USE TypeLiterals to write more modular/reusable components ?
The power of TypeLiterals in Guice is that it allows you to refernce implementations of a service without defining what that service is.
Lets start with a simple list in a program where we have many types of lists that are processed differntly :
List<String> myStringList = new ArrayList<String>();
Now, how should I process these Strings ? At runtime, there is no way to "know" that its a String list. So, often times I might create a factory, like so , that gets processing objects for me :
ProcessorFactory.get(String.class).process(myStringList);
Thus, I might use a factory (with a bunch of if/else or case statements) to define processors for different data types. My constructor, for the object which uses these processors, and which needs access to various Processor Implementations, might look like this :
public MyClass(Processor<String> strProcessor, Processor<Integer> intProcessor)P
{
//Simple enough, but alot of boiler plate is required to launch this constructor.
}
//and to invoke
new MyClass(PRocessorFactory.get(....), ProcessorFactory.get(...));
All good so far... Until we realize that there is a better way :
In the Guice world, I can forget about writing this factory - rather, I can explicitly BIND classes to processors. The advantage of this is that there are no static dependencies - the class which needs to USE processor implementations DOES NOT need any static dependency on a factory -rather, the classes are directly injected. Thus, I can easily define a class which uses complex dependencies, without having to build a factory aware class builder... Thus, I have far less boilerplate :
#Inject
public MyClass(Processor<String> implStr, Processor<Integer> implInt)
{
//Now , this method will work magically, because Guice is capable of
//Using the loaded modules, which define bindings between generics and their implementations
}
//Elsewhere I simply define a single guice module that does the binding, and make sure to load it before my application launches.
There is a good tutorial on this with interface implementations and binding examples, here : http://thejavablog.wordpress.com/2008/11/17/how-to-inject-a-generic-interface-using-guice/
This is a way how guys bypass generics erasure in java. You need it, when you want ot bind some implementation to parametrized(generic) interface. Found some usage in Guice docs:
bind(new TypeLiteral<PaymentService<CreditCard>>() {})
.to(CreditCardPaymentService.class);
This admittedly odd construct is the way to bind a parameterized type. It tells Guice how to honor an injection request for an element of type PaymentService. The class CreditCardPaymentService must implement the PaymentService interface. Guice cannot currently bind or inject a generic type, such as Set; all type parameters must be fully specified.
The TypeLiteral class is a workaround for the fact that you cannot have class literals for generic types. The API doc of Binder (this is from Google Guice, but the Java EE class of the same name has exactly the same purpose) gives an example for how it's used:
bind(new TypeLiteral<PaymentService<CreditCard>>() {})
.to(CreditCardPaymentService.class);
This specifies that any auto-injected reference of type PaymentService<CreditCard> will be implemented by the concrete class CreditCardPaymentService, leaving the option for PaymentService<Coupon> to be implemented by a different class. Without TypeLiteral, this would not be possible because the Java compiler will accept PaymentService<CreditCard>.class, only PaymentService.class.
Note that this also requires the use of anonymous subclasses (the {} after new TypeLiteral<PaymentService<CreditCard>>()) in order to work around type erasure.
I'll simplify the answer/reason for the existence of TypeLiteral<> in GUICE:
if java allows you to write:
bind(FooInterface<String>.class).to(FooImplementation.class);
then you are done, there is no need for TypeLiteral<>
but java has this "Type Erasure" thing for generics, so FooInterface<String>.class won't even get complied.
So you use:
bind(new TypeLiteral<FooInterface<String>>() {}).to(FooImplementation.class);
"new TypeLiteral<Interface>() {}" will create some anonymous class and new an object out of it. You can imagine that object knows everything about the tpye info of the Interface, so GUICE use that object to perform the DI magic.

Getting the names of all Java classes declared in a package

I'm writing a functionality where it would be helpful to get the classes inside a certain package of my program. Also, I only want the classes that subclass a certain class.
I need the classes in order to call static methods on them.
Is there an automatic way to do this? If so, is it slow?
In case I was not clear, what I want is something like this:
ArrayList<Class<? extends MySuperClass>> classes = ;
classes.add(MyClass.class);
classes.add(MyClass2.class);
Instead of having to call add for each class, I would like to automatically get that class list.
The number of classes is small, so I would not mind declaring them manually if the automatic trick would be slow - this app is for a mobile platform.
In either way, I would also like to know how to call the static method for each method in the ArrayList:
// error The method nameOfStaticMethod is undefined for the type Class<capture#2-of ? extends MySuperClass>
classes.get(0).nameOfStaticMethod ();
Thanks for your comments.
Java doesn't provide this ability. There is no introspection at the package level. The classes could be records in a database, or on the other side of a network connection. There's no requirement for them to be stored and organized so as to facilitate enumerating them by package.
You could make a custom class loader and API to provide a method of listing the class names.
I too would like to list all classes in a package but so far the methods of doing this is pretty bad:
Like JOTN suggested - needs file access - not if it is a jar
Listing a JAR entries - well, also needs the jar file
Quoting a older SO question:
It isn't possible to query a Package for it's Classes (or even its subpackages). http://forums.sun.com/thread.jspa?threadID=341935&start=0&tstart=0 contains a very good discussion about why this is problematic, as well as a handful of solutions to your problem.
Anyways, here is how you invoke static methods on the class:
Method m = Integer.class.getMethod("toString", Integer.TYPE);
System.out.println(m.invoke(null, 123));

Categories

Resources