java dependency inject ambiguous overwrite - java

I'm using openapi generator to generate java-resteasy server stub code template, my idea is that use the generator generate some interface that I will never modify, and I will implement that interface with my own code.
However, the generator already generated implementation class, I write my own implementation class which extends the generated one. So now there're two implementation classes, so CDI complains about the ambiguouty:
javax.enterprise.inject.AmbiguousResolutionException: Ambiguous dependencies for type openapidemo.gen.FruitsApiService and qualifiers [#Default]
is there any way to mark my own implementation class as first priority when CDI try to discover bean? so as to overwrite the one generated by openapi.
edit:
Per #Negi answer, #Alternative might be a way to indicate a class as low priority when CDI searching bean, however, in my case, I want to hide the generated code without modifying it since I will check it in my repo, and I expect the code generation is idempotent. So is there any way to annotate a class as "prioritize" with my own implementation class, as opposite to #Alternative?

You can create a file named .openapi-generator-ignore and mention the files you would like not to generate.
https://openapi-generator.tech/docs/faq-extending/#how-do-i-skip-files-during-code-generation

It is ambiguous because CDI searches for beans by type and your entity and the producer method return the same type.
Please add #Alternative annotation at bean level.

Related

How to know which bean was injected into interface?

So I have a set packages that are my base code for extended applications. My application implements a series of interfaces that then are inject by spring during run time (As configured). I would like to know is there is a way that I could know which class that implements the interface was injected. I need this because I have JSON serializer/deserializer actions that I would like to perform but for that I need to know the class that was injected.
I have an java config file that will describe the wiring and it will be provided with the game implementation. But so far I haven't been able to get the concrete class implementing the interface. I also haven't been successful to request that info from the context.
Ant hints?
You can use reflection to let the injected instance tell you what implementation class it is: injectedInstance.getClass().getName(). However, unless you're doing something special, consider this a hack. You probably should revisit your design so that you do not need to do that.
You can simply autowire an interface and get the implemented class name:
#Autowired
private Service service;
System.out.println(service.getClass().getName());
However with Spring beans the spring container has usually proxied them so it's not always helpful, in the case above the class is a Spring class called:
hello.HelloServiceImpl$$EnhancerBySpringCGLIB$$ad2e225d
I suspect you should look at Jackson serializers which should handle all this, see Java - Jackson Annotations to handle no suitable constructor
So the way I came around this issue was by injecting an object into the JSON deserializer and use a getClass() method as the template to Jackson to use. And it worked like a charm, even thought the implementation to be injected was injected into a wiring happening in the dependency!. Hope it helps!

What is the best way to bind the same type twice (e.g. a wrapper) for dependency injection in Guice?

Say I have a service type Service that has a number of different implementations, ServiceImplX and ServiceImplY. I also have a caching layer, CachedService, that implements Service and wraps some basic implementation of Service to access the data.
What I want is to be able to bind one of ServiceImplX and ServiceImplY as the basic implementation to be injected into CachedService, while CachedService itself should be bound to Service to be injected into actual clients of this service.
I would like to avoid naming annotations to solve this since that seems fragile. Is there any safer way of achieving this?
Define a proper binding annotation:
#RetentionPolicy(RUNTIME)
#BindingAnnotation
#interface ServiceBinding {}
This is a lot more robust than an #Named binding annotation because:
It's a symbol, just like a class name or variable, so you can easily find references to it in your code; the name in an #Named annotation can be constructed at runtime, so it is much harder to find.
You can control the accessibility of a binding annotation via public/private etc modifiers, so you can control where the annotation is configured and referenced. The strings of #Named annotations are in a global scope.

Figure out annotated class in ConstraintValidator implementaiton

I need to figure out the annotated class in my custom ConstraintValidator but I didn't find a way without using provider specific API like:
ConstraintValidatorContextImpl x = (ConstraintValidatorContextImpl)constraintContext;
getValidationContext().getCurrentOwner();
Is there a non provider specific approach to figure out the annotated class?
Thanks a lot for your support.
Oli
Based on your comment I'd recommend to either implement two separate constraints, one for each target class (they could share implementation code using a delegate or super-class).
Or you implement a class-level constraint, which naturally has access to the validated class and all its properties. Note that you can still let the resulting constraint validation point to a specific property of the class using the constraint builder API in your validator implementation.
I recommend to Implement 2 ConstraintValidators, one for each class. The would both use the same Annotation which references them in the validateBy() method.

How does Guice Populate Annotated Fields

For the sake of my own education, I wanted to build a simple Dependency Injection framework that functions similar to the way Google's Guice does. So that when a class is loaded, it pre-populates annotated fields with data from a factory class.
I am using Reflections to scan all my factory classes at compile time and save those classes in a static list so that when it comes time to load my classes, I have a reference to my factories that I can then scan methods and return the appropriate data.
Where i'm stuck at is how to pre-populate my classes annotated fields without actually doing any of the work in the actual class. In other words, when a class is loaded, I need to be able to determine if any of the fields are annotated with a specific annotation, and if they are, retrieve the value from the factory class.
Is there some way of performing reflection on a class right before it is loaded, pre-populate specific fields and then return an instance of that class to be used?
I could extend all of my classes that require dependency injection with a base class that does all of this work, but I figure there must be a better way so that I can simply use an #Inject (or whatever annotation I decide to use to say that this field requires DI) and "magically" all the work is done.
The way that Guice approaches this is that it will only populate the fields of an instance that was itself created by Guice1. The injector, after creating the instance, can use the Reflection API to look at the fields of the Class and inspect their annotations with Field.getDeclaredAnnotations().
This is also the reason why, when you want to inject into a static field, you need to use Binder.requestStaticInjection() to populate the static fields.
Guice does not simply scan your code for annotations; all injections recurse from an explicit request (e.g. requestStaticInjection(), Injector.getInstance(), etc). Now often that initial, explicit request will have been made in some library code.
For example, if you're using guice-servlet you let Guice create the instances of your servlet by using the serve().with() calls. But if you didn't do that, and instead left your servlet config in your web.xml, Guice would not inject into your servlet.
1 - You can also request explicit injection using Binder.requestInjection().

How to specify interceptor at inject time

I have some beans for which, in specific injections, I want to add a given interceptor.
I was naïvely thinking there was something like a #Interceptors annotation that could allow me to write
private #Interceptors(Logging.class, Connection.class) #Inject MyBean instance;
Unfortunatly, Weld documentation clearly states the opposite.
So, how could I inject an intercepted version of my bean ? Is it possible using a cdi Instance object ?
EDIT
Although LightGuard's answser is really relevant, it doesn't totally answser my question, so let me rephrase it.
I want to have an annotation that triggers some kind of method call event sending. For that, I created a CDI Interceptor, complete with its own interceptor binding (let's say interceptor is called SenderInterceptor, and the binding is called SenderBinding). What I want now is to add a CDI qualifier (let's call it SenderQualifier) that, when used for an injection, installs SenderInterceptor.
To be more clear, I want the following code to use SenderInterceptor
/* calling any method of that bean should trigger an event */
private #Inject #SenderQualifier MyBean aBean;
while this one doesn't
private #Inject MyBean aBean;
What I tried so far was
detecting fields requiring those injections using reflections library (that works)
create using seam solder an AnnotatedType from bean class (during the BeforeBeanDiscovery event) (the type is created, but not really distinguishable from the initial one) and giving that AnnotatedType the interceptor binding annotation.
create using seam solder (again) a Bean from generated AnnotatedType, and giving it the required qualifier annotation
All seems to worrk, except it's the original bean which gets injected.
I could of course replace original one with intercepted one, but there are some cases where such interception is not required, so I have to keep both AnnotatedType refering the same concrete type. I was thinking I coulld do that in CDI, but it doesn't seems to work (as original type is never replaced by intercepted one).
What you would need to do:
Add the interceptor to beans.xml so it's activated
Create an extension to add the interceptor binding or the interceptor annotation to the type in ProcessAnnotatedType life cycle event. You'll need to call getAnnotatedType, add the annotation(s) then call setAnnotatedType. I strongly recommend looking at Seam Solder or Apache DeltaSpike project for the AnnotatedTypeBuilder to make this easier.
Possibly, you could try #Inject MyInterceptedBean instance;, where the interceptors are listed with the MyInterceptedBean?
(Caveat: this does not look right, though, using inheritance for types that only differ in annotations ... probably acceptable when it's always the two stated same annotations and not different annotations in each case.)

Categories

Resources