Could dagger get the context of injection point? - cdi

In cdi doc:
https://docs.jboss.org/cdi/api/1.0/javax/enterprise/inject/spi/InjectionPoint.html
The example shows how to get context by using InjectionPoint:
#Produces
Logger createLogger(InjectionPoint injectionPoint) {
return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName() );
}
I am currently using Dagger2 in my project and I found no such class as InjectionPoint available. So is there any other options?
Thanks

Related

How to use Micronaut & depenency injection in a single-file Groovy script?

I want to use Micronaut from a Groovy script. It seems that annotations such as #Inject and #PostConstruct are not processed.
Here is the code I tried:
#!/usr/bin/env nix-shell
#!nix-shell -i groovy
#Grapes([
#Grab('ch.qos.logback:logback-classic'),
#Grab('io.micronaut:micronaut-runtime')
])
package org.sdf // NPE without package
import io.micronaut.runtime.Micronaut
import javax.inject.*
import javax.annotation.*
#Singleton
class Component {
}
#Singleton
class App implements Runnable {
#Inject
Component comp
#Override
#PostConstruct
public void run() {
// Never runs
assert this.comp != null
assert false
}
}
static void main(String... args) {
Micronaut.run(App, args);
}
It doesn't run post-construct method and logs this:
22:17:43.669 [main] DEBUG i.m.context.DefaultBeanContext - Resolved bean candidates [] for type: interface io.micronaut.runtime.EmbeddedApplication
22:17:43.671 [main] INFO io.micronaut.runtime.Micronaut - No embedded container found. Running as CLI application
How can I use Micronaut with dependency injection in a single-file Groovy script?
How can I use Micronaut with dependency injection in a single-file
Groovy script?
You would have to compile all of the code in your script with Micronaut's annotation processors configured on the compile time classpath for your script. Technically that could be done with a single script but as a practical matter I don't think many folks are going to have a good reason to do or build support for making that more easily done.
FYI: Not an answer to your question as asked but one simple alternative approach is to not define all of your bean related classes in a single script, instead define them in their own separate source files in a project configured to build with Maven or Gradle using our annotation processors and then consume those classes from your script using #Grab like you have for other dependencies.

How to inject properties when using Castle Windsor

I am new to IOC.
I've MethodProfilerAspectAttribute attribute which has to be applied on any method like this
[MethodProfilerAspectAttribute(5)]
public void MethodName(){}
Here is the implementation of MethodProfilerAspectAttribute
[Serializable]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class MethodProfilerAspectAttribute : OnMethodBoundaryAspect
{
public ILogger logger { get; set; }
public int x{get;set;}
public MethodProfilerAspectAttribute(int x)
{
this.x=x;
}
public override void OnSuccess(MethodExecutionArgs args)
{
logger.CustomLogging("logMe");
base.OnSuccess(args);
}
}
I want to resolve my ILogger dependency using Log4NetLogger which is registered and resolving constructor dependencies properly by using following :
container.Register(Component.For<ILogger>().ImplementedBy(typeof(Log4NetLogger)));
but unfortunately whatever I've tried for resolving property dependency, is not working.
Any help would be greatly appreciated.
The link you provided just describes property injection for components resolved from the container. Attributes are not resolved from the container, but instead are created by the CLR. You might be able to jigger a way to set attribute properties by providing a custom IContributeComponentModelConstruction implementation, but I'm not so sure. See answers for similar questions here, here, and here (from the creator of Windsor).
In any case, attributes is not where you want to put functionality. They should be minimal, just providing metadata. I see here you're trying to provide some sort of functionality across all method invocations. You may want to consider Windsor's interceptors to provide similar behavior.

Rendering GORM classes from Spring Boot

I'm trying to write a simple Spring Boot controller that renders a GORM instance and failing.
Here's a shortened version of my code:
#RestController
#RequestMapping("/user")
class UserController {
#RequestMapping(value='/test', method=GET)
User test() {
return new User(username: 'my test username')
}
}
I get the following error message:
Could not write JSON: No serializer found for class org.springframework.validation.DefaultMessageCodesResolver and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: users.domain.User["errors"]->grails.validation.ValidationErrors["messageCodesResolver"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.springframework.validation.DefaultMessageCodesResolver and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: users.domain.User["errors"]->grails.validation.ValidationErrors["messageCodesResolver"])
The error seems to be caused by extra properties injected by GORM. What is the proposed solution for this? Will this eventually be solved in gorm-hibernate4-spring-boot? Should I simply disable SerializationFeature.FAIL_ON_EMPTY_BEANS (I don't have a lot of experience with Jackson so I'm not entirely sure what side effects this may have)? Should I use Jackson's annotations to solve the problem? Any other options?
I've found a way to get rid of the error using this code:
#Component
class ObjectMapperConfiguration implements InitializingBean {
#Autowired
ObjectMapper objectMapper
#Override
void afterPropertiesSet() {
def validationErrorsModule = new SimpleModule()
validationErrorsModule.addSerializer(ValidationErrors, new ErrorsSerializer())
objectMapper.registerModule(validationErrorsModule)
}
}
class ErrorsSerializer extends JsonSerializer<ValidationErrors> {
#Override
void serialize(ValidationErrors errors, JsonGenerator jgen, SerializerProvider provider) {
jgen.writeStartObject()
jgen.writeEndObject()
}
}
Obviously this solution is far from perfect as it simply nukes all validation errors but right now it is good enough for me. I am pretty sure the Spring Boot team will have to address this issue eventually as the GORM objects are also being serialized with some internal Hibernate properties like attached. I'm not accepting this answer as it is not an acceptable solution for most scenarios, it basically just squelches the exception.
This did not work for me.
So I used this instead and the error disappeared.
#JsonIgnoreProperties(["errors"])
I'm using springBootVersion '1.4.1.RELEASE' with gorm & hibernate5:
compile("org.grails:gorm-hibernate5-spring-boot:6.0.3.RELEASE")
I am having to include the following at the top of each domain class in order to use them in a client response (i.e. json serialization using jackson):
#JsonIgnoreProperties(["errors", "metaClass", "dirty", "attached", "dirtyPropertyNames"])
When using springBootVersion '1.3.5.RELEASE' I was able to get away with:
#JsonIgnoreProperties(["errors"])
This is trending in the wrong direction :)

RESTEasy, CDI, embedded Jetty, bean validation is ignored

I've a Groovy project where I use RESTEasy with Weld and deploy to embedded Jetty. What I can't seem to get working is bean validation. RESTEasy documentation says that adding resteasy-validator-provider-11 along with hibernate validator dependencies (hibernate-validator, hibernate-validator-cdi, javax.el-api, javax.el) is enough. But the bean validation is simply ignored by RESTEasy. I curiously also get the following message in the logs:
plugins.validation.ValidatorContextResolver - Unable to find CDI supporting ValidatorFactory. Using default ValidatorFactory
Based on the suggestions on [this][1] post, I tried registering Hibernate InjectingConstraintValidatorFactory in META-INF/validation.xml but it depends on a BeanManager being injected and blows up at runtime.
The code can be found here https://github.com/abhijitsarkar/groovy/tree/master/movie-manager/movie-manager-web
A log gist is here: https://gist.github.com/anonymous/8947319
I've tried everything under the sun without any success. Pls help.
To do this without EE, I believe you'll need to fork the existing InjectingConstraintValidatorFactory but instead of using injection of the bean manager, use the CDI 1.1 class CDI to get a reference to the bean manager, e.g. CDI.current().getBeanManager(). http://docs.jboss.org/cdi/api/1.1/javax/enterprise/inject/spi/CDI.html
You do need to be on CDI 1.1 to do this (so Weld 2+, 2.1.1 is current I believe). Here's an example impl, based on: https://github.com/hibernate/hibernate-validator/blob/master/cdi/src/main/java/org/hibernate/validator/internal/cdi/InjectingConstraintValidatorFactory.java
public class InjectingConstraintValidatorFactory implements ConstraintValidatorFactory {
// TODO look for something with better performance (HF)
private final Map<Object, DestructibleBeanInstance<?>> constraintValidatorMap =
Collections.synchronizedMap( new IdentityHashMap<Object, DestructibleBeanInstance<?>>() );
private final BeanManager beanManager;
public InjectingConstraintValidatorFactory() {
this.beanManager = CDI.current().getBeanManager();
Contracts.assertNotNull( this.beanManager, "The BeanManager cannot be null" );
}
#Override
public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
DestructibleBeanInstance<T> destructibleBeanInstance = new DestructibleBeanInstance<T>( beanManager, key );
constraintValidatorMap.put( destructibleBeanInstance.getInstance(), destructibleBeanInstance );
return destructibleBeanInstance.getInstance();
}
#Override
public void releaseInstance(ConstraintValidator<?, ?> instance) {
DestructibleBeanInstance<?> destructibleBeanInstance = constraintValidatorMap.remove( instance );
destructibleBeanInstance.destroy();
}
}
I finally fixed this. Turns out, a validation.xml is not really required, resteasy-cdi module does a fine job of registering the BeanManager. What I was missing and not clearly documented anywhere, is that if an annotation is placed on a method, the validation engine just "decides" what should be validated. I placed a #NotNull on a method and it was validating the return type, not the parameters. One can use validationAppliesTo element in some cases but #NotNull doesn't have it. When I moved it from the method to the parameter, it started working.
Now I ran across what I believe is a Weld bug but I'll post that question separately.

CDI: How to put an existing object into application scope (without writing CDI extension)?

I have an object which I initialized manually (legacy code).
I'd like to put this object to the application context to make it available through CDI.
How do I do that without writing a CDI extension?
Using a producer. Make a bean that #Produces instances of your class.
Do you need something like that?
#ApplicationScoped
public class ApplicationScopedClass {
#Produces
public static ApplicationScopedClass makeAnInstance() {
return new ApplicationScopedClass();
}
}

Resources