I need to use two classes with the same name but different namespaces (foo.request.Response and bar.request.Response) in an interface. In classes this can be achieved by using the full name with namespace :
public foo.request.Response method1() { [...]
public bar.request.Response method2() { [...]
But this does not seem to work in Interfaces.
What is the correct way of dealing with this problem ?
Edit 1
Error comes from Eclipse :
foo cannot be resolved to a type
Interface code :
public interface ITestController {
String method1(foo.request.Response response);
}
I found the issue, it was not coming from the interface it was a simple mess-up in the dependencies. Thanks for your help ;)
It works in interfaces, but care should be taken so that the implementing classes fully qualify the names in the same way.
Note that you can not choose which of the two classes when implement the interface. It's the interface that specifies which of the two classes is to be used when implementing the interface.
The code you've posted in your answer is messed up. If the two first methods belong to a class implementing ITestController then that class must also include an implementation for
public String method1(foo.request.Response response) { ... }
Related
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();
}
}
Suppose I have created a library and distribute all over the company and it use in every project.
Library is 1.0 and Suppose I have a interface Componentble.
public interface Componentble {
public String getComponentId();
}
I had done some modification and updated the jar for 1.1 and Componentble interface modified as follows.
public interface Componentble {
public String getComponentId();
public Componentble getParentComponent();
}
When this jar applied to existing project it will gives compile errors.
I want to do this modifications and update the jar. but case is it should not affect to existing projects.
What is the best way to do this.
Create ComponentbleV2 and in new project ask to use ComponentbleV2 not Componentble.
Or Create custom class loader and do what need.
The answer what i want is how we can do api modification and apply to existing project with out any compilation issue for existing projects.
One way to do this is by annotating the method(s) in your old interface with #Deprecated and explaining in the javadocs what to use instead.
For more documentation on that, see Oracle documentation on #Deprecated
For the sake of backwards compatibility, you're going to have to keep both interfaces for now. This might require a bit of customization in the implementation of the interfaces. In a while, after you've been through a couple more versions, you can remove the old interface.
Make sure to properly document your deprecated methods, so that the developers who use it know what to use instead and where to find it.
From Java 8 on you can provide default implementations for interface methods. They were invented exactly for your problem.
public interface Componentble {
public String getComponentId();
public default Componentble getParentComponent() {
return null;
}
}
Two interfaces
There is no need to deprecate the old one.
Create two interfaces where the new one extends the old one.
public interface Componentble {
public String getComponentId();
}
and
public interface ComponentbleWithStructure extends Componentble {
public Componentble getParentComponent();
}
Implementing a interface should imply that the implementer follows the contract of that interface.
This way you know that any class implementing both has been remade to fit the new contract and the ones implementing only the old still follows the old contract.
Example of use:
void doStuff(Componentble component){
if(component instanceof ComponentbleWithStructure){
Componentble parent=((ComponentbleWithStructure)component).getParentComponent();
....
}
....
}
Default implementation
The java8 way is only useful when it is possible to express the new functionality using the old interface. For example if you have a service that can look up parents you could write.
public interface Componentble {
public String getComponentId();
public default Componentble getParentComponent() {
return ParentLookUpService.getParent(getComponentId());
}
}
This way you will know that all instances using the new interface have a correct implementation.
I am doing Spring Aspect Oriented Programming with annotations in Java. I have an Aspect LogAOP:
#Aspect
public class LogAOP {
#DeclareParents(value="beans.service.*+", //Line 1
defaultImpl= EventImpl.class)
public static Event mixin;
#Before("com.beans.business.businessService() &&" +
"this(abc)")
public void usage(Event abc) {
abc.increment();
}
}
I am not able to understand the significance of '+' symbol in Line 1 in value attribute of #DeclareParents annotation.
Beacuse even if I remove this + symbol, the program is running fine. I have also searched in official documentation of Spring AOP (http://docs.spring.io/spring/docs/2.5.4/reference/aop.html) , nothing is mentioned there.
Using + after a class name or interface name is used to match that class or interface, and all it's subclasses. So, the pointcut expression in this case:
#DeclareParents(value="beans.service.*+", //Line 1
defaultImpl= EventImpl.class)
public static Event mixin;
...will match any interfaces or class defined in package beans.service, and also any subclass or implementing class of those classes and interfaces. It may be needed because, the implementing classes might not be in the beans.service package. In your case, you're not seeing the effect because may be all your implementing classes are in the same package. Try implementing an interface in beans.service package, and put the implementing class in a different package. I guess, you'll see the difference then.
I have a generated object that I want to:
Preserve existing functionality of without injecting into the constructor and rewriting every method to call injectedObject.sameMethod().
Add additional functionality to that generated object without modifying the generated object.
add additional functionality to.
For example:
public class GeneratedObject {
public String getThis() { ... }
public String getThat() { ... }
}
public interface ObjectWrapper {
String doThisWithThat();
}
public class ObjectWrapperImpl extends GeneratedObject implements ObjectWrapper {
String doThisWithThat() { ... }
}
However, downcasting is not allowed, what is the proper implementation without rewriting a bunch of redundant code just to wrap the object?
I think decorator pattern may help you: "The decorator pattern can be used to extend (decorate) the functionality of a certain object at run-time, independently of other instances of the same class"
Have you tried aspectj? http://www.eclipse.org/aspectj/doc/next/progguide/semantics-declare.html It's a bit complicated but so is your request.
If you can extract an interface from GeneratedObject, then it would be possible to do this using a dynamic proxy. You would make a proxy which implemented the extracted interface and ObjectWrapper, with an invocation handler which passed all calls to methods in the GeneratedObject interface through to the delegate, and sent the doThisWithThat() calls elsewhere.
Proxies aren't pretty, but the ugliness is at least well-localised.
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