I'm trying to select the bean programatically, but quarkus does not injected the bean and throw an exception. It's not supported ?
public enum ReportType {
ONE,
TWO
}
#Qualifier
#Retention(RUNTIME)
#Target({METHOD, PARAMETER, FIELD, TYPE})
#Documented
public #interface Report {
ReportType value();
public static final class Literal extends AnnotationLiteral<Report> implements Report {
private final ReportType value;
public static Literal of(ReportType value) {
return new Literal(value);
}
private Literal(ReportType value) {
this.value = value;
}
public ReportType value() {
return value;
}
}
}
public interface CommonnInterface {
void call();
}
#Report(value = ReportType.ONE)
public class ReportOneBusiness implements CommonnInterface {
#Override
public void call() {
System.out.println("Hello");
}
}
And when we call
CommonnInterface commonnInterface = CDI.current()
.select(
CommonnInterface.class,
Report.Literal.of(ReportType.ONE)
).get();
No bean found for required type [interface org.business.CommonnInterface] and qualifiers [[#org.cdi.Report(value=ONE)]]
You likely need to make the beans unremoveable using the #io.quarkus.arc.Unremovable annotation.
See this for more details.
geoand was right, and I forgot to put #Dependent in the ReportOneBusiness.
The right code for ReportOneBusiness is
#Unremovable
#Dependent
#Report(value = ReportType.ONE)
public class ReportOneBusiness extends CommonnInterface {
#Override
public void call() {
System.out.println("Hello");
}
}
Related
I have been trying to create a custom scope in Spring Framework, but I fail to understand how is the scope actually instantiated and destroyed.
Assuming I want to create an EventScope and I have a com.example.EventHandler.handleEvent(Event event) method that handles an incoming event.
How do I ensure that every Event starts/stops a scope when it is being handled?
If I have several EventScoped beans wired in, How do I make sure they are using the same scope instance during an event? It seems like a new EventScopeImpl would be created for every bean?
If I have to use a ThreadLocal or some other static context, what is even the point of using a custom scope when I can use the ContextHolder class directly?
My code is as follows?
EventScopeImpl.java
public class EventScopeImpl implements Scope {
private final Map<String, Object> scopedObjects
= Collections.synchronizedMap(new HashMap<String, Object>());
private final Map<String, Runnable> destructionCallbacks
= Collections.synchronizedMap(new HashMap<String, Runnable>());
#Override
public Object get(final String name, final ObjectFactory<?> objectFactory) {
if(!scopedObjects.containsKey(name)) {
scopedObjects.put(name, objectFactory.getObject());
}
return scopedObjects.get(name);
}
#Override
public Object remove(final String name) {
Optional.ofNullable(destructionCallbacks.remove(name)).ifPresent(Runnable::run);
return scopedObjects.remove(name);
}
#Override
public void registerDestructionCallback(final String name, final Runnable callback) {
destructionCallbacks.put(name, callback);
}
#Override
public Object resolveContextualObject(final String key) {
return EventContextHolder.instance().getValue(key);
}
#Override
public String getConversationId() {
return null;
}
}
EventScope.java
#Qualifier
#Scope(value = "event", proxyMode = ScopedProxyMode.TARGET_CLASS)
#Target({ ElementType.TYPE, ElementType.METHOD })
#Retention(RetentionPolicy.RUNTIME)
public #interface EventScope{}
EventContextHolder.java
public class EventContextHolder{
#Getter
#Accessors(fluent = true)
public static final EventContextHolder instance = new EventContextHolder();
private final static ThreadLocal<Context> context = ThreadLocal.withInitial(Context::new);
private EventContextHolder(){}
public void setValue(final String key, final Object value){
context.get().data().put(key,value);
}
public Object getValue(final String key){
return context.get().data().get(key);
}
public void clear(){
context.get().data().clear();
}
private static class Context{
#Accessors(fluent = true)
#Getter
private final ConcurrentHashMap<String,Object> data = new ConcurrentHashMap<>();
}
}
EventAspect.java
#Aspect
#Component
public class EventAspect {
#Pointcut("execution(com.example.EventHandler.handleEvent(..))")
public void eventHandlerMethod() {};
#Around("eventHandlerMethod()")
public Object startMessageContext(ProceedingJoinPoint pjp) throws Throwable {
final Event event;
if(pjp.getArgs() > 0 && Event.class.isInstance(pjp.getArgs()[0]){
event = (Event)pjp.getArgs()[0];
}
#Cleanup("clear") EventContextHolder context = EventContextHolder.instance();
context.setValue("event",event);
Object retVal = pjp.proceed();
return retVal;
}
}
EventContext.java
#RequiredArgsConstructor
#Getter
#Component
#EventScope
#Lazy
public class EventContext {
#Lazy
#Value("#{event}")
private Event event;
}
EventScopeConfiguration.java
#Configuration
public class EventScopeConfiguration {
#Bean
public BeanFactoryPostProcessor eventScopeBeanFactoryPostProcessor() {
return beanFactory -> beanFactory.registerScope(
"event", new EventScopeImpl());
}
}
I am writing a custom SonarQube rule for java, where I want to check an object is created with an argument having a specific annotation.
the file i am testing against
class MyClass {
public void doSomething() {
final var v = new Dto();
new MyObject(v.value1()); // Compliant since value1 has #MyAnnotation
new MyObject(v.value2()); // Noncompliant
}
public static class MyObject {
private final String value;
public MyObject(String value) {
this.value = value;
}
}
#Target(ElementType.FIELD)
#Retention(RetentionPolicy.RUNTIME)
public #interface MyAnnotation {
}
public static class Dto {
#MyAnnotation
private String value1;
private String value2;
public String value1() {
return this.value1;
}
public String value2() {
return this.value2;
}
}
}
the check
public class MyObjectCheck extends IssuableSubscriptionVisitor {
#Override
public List<Kind> nodesToVisit() {
return Collections.singletonList(Kind.NEW_CLASS);
}
#Override
public void visitNode(Tree tree) {
NewClassTree ctor = (NewClassTree) tree;
if(!ctor.identifier().symbolType().name().contains("MyObject")) { //to change
return;
}
if(ctor.arguments().size() == 1) {
final ExpressionTree expressionTree = ctor.arguments().get(0);
if(expressionTree.is(Kind.METHOD_INVOCATION)) {
MethodInvocationTree methodInvocation = (MethodInvocationTree) expressionTree;
}
}
}
}
from the methodInvocation, I can manage to call methodSelect to have a MethodInvocationTree but then I can't figure how to go to the field returned by the method.
I had to make concession where I consider the class of the method invoked being a POJO or a java record. This way I was able to fetch the linked field and annotations :
String methodName = methodInvocationTree.symbol().name();
final Symbol.TypeSymbol methodClass = (Symbol.TypeSymbol) methodInvocationTree.symbol().owner();
final List<SymbolMetadata.AnnotationInstance> annotations = methodClass.lookupSymbols(methodName).iterator().next().metadata().annotations();
We've been using Guice for DI in AWS Lambdas, but now are moving to Spring Boot and long running services.
We've got feature toggles working as dynamic proxies in Guice, but need to implement in Spring.
Say we have a SomeFeature interface and two implementations DisabledImplementation and EnabledImplementation.
I can get really close by tagging DisabledImplementation with #Component("some.feature.disabled") and EnabledImplementation with #Component("some.feature.enabled") and then writing an implementation like this:
#Primary
#Component
public class FlippingFeature implements SomeFeature {
private final SomeFeature enabled;
private final SomeFeature disabled;
private final FeatureFlip featureFlip;
#Inject
public FlippingFeature(#Named("some.feature.enabled") SomeFeature enabled,
#Named("some.feature.disabled") SomeFeature disabled,
FeatureFlip featureFlip) {
this.enabled = enabled;
this.disabled = disabled;
this.featureFlip = featureFlip;
}
#Override
public String foo() {
return featureFlip.isEnabled("some.feature") ? enabled.foo() : disabled.foo();
}
}
But I'd prefer to not write the FlippingFeature class at all and do it w/ a dynamic proxy hidden away. Can I do this with a custom BeanFactoryPostProcessor or something else?
I've got a pretty decent solution now.
#Qualifier
#Retention(RUNTIME)
// tag the disabled feature implementation w/ this annotation
public #interface Disabled {}
#Qualifier
#Retention(RUNTIME)
// tag the enabled feature implementation w/ this annotation
public #interface Enabled {}
#Target(TYPE)
#Retention(RUNTIME)
// tag the feature interface w/ this annotation
public #interface Feature {
String value();
}
// create a concrete implementation of this class for each feature interface and annotate w/ #Primary
// note the use of #Enabled and #Disabled injection qualifiers
public abstract class FeatureProxyFactoryBean<T> implements FactoryBean<T> {
private final Class<T> type;
private FeatureFlag featureFlag;
protected T enabled;
protected T disabled;
protected FeatureProxyFactoryBean(Class<T> type) {
this.type = type;
}
#Autowired
public void setFeatureFlag(FeatureFlag featureFlag) {
this.featureFlag = featureFlag;
}
#Autowired
public void setEnabled(#Enabled T enabled) {
this.enabled = enabled;
}
#Autowired
public void setDisabled(#Disabled T disabled) {
this.disabled = disabled;
}
#Override
public T getObject() {
Feature feature = type.getAnnotation(Feature.class);
if (feature == null) {
throw new IllegalArgumentException(type.getName() + " must be annotated with #Feature");
}
String key = feature.value();
ClassLoader classLoader = FeatureProxyFactoryBean.class.getClassLoader();
Class<?>[] interfaces = {type};
return (T) Proxy.newProxyInstance(classLoader, interfaces,
(proxy1, method, args) -> featureFlag.isEnabled(key) ?
method.invoke(enabled, args) :
method.invoke(disabled, args));
}
#Override
public Class<T> getObjectType() {
return type;
}
}
// test classes
#Feature("test_key")
public interface SomeFeature {
String foo();
}
#Disabled
#Component
public class DisabledFeature implements SomeFeature {
#Override
public String foo() {
return "disabled";
}
}
#Enabled
#Component
public class EnabledFeature implements SomeFeature {
#Override
public String foo() {
return "enabled";
}
}
#Primary
#Component
public class SomeFeatureProxyFactoryBean extends FeatureProxyFactoryBean<SomeFeature> {
public SomeFeatureProxyFactoryBean() {
super(SomeFeature.class);
}
}
Then inject #Inject SomeFeature someFeature where needed and it will get the proxy instance due to the #Primary annotation.
Now we can toggle the feature on and off in Launchdarkly and it (nearly) instantly gets reflected in all running instances without a restart or re-initializing the Spring context.
I have a web-application on Hibernate / Spring and I have few enums that I want to use in applications
public enum MerchantStatus {
NEW("New"),
...
private final String status;
MerchantStatus(String status) {
this.status = status;
}
public static MerchantStatus fromString(String status) {..}
public String toString() {..}
}
And
public enum EmployerType {
COOL("Cool"),
...
private final String type;
EmployerType (String type) {
this.type = type;
}
public static EmployerType fromString(String type) {..}
public String toString() {..}
}
I want to create converter to convert my enum objects to string and and vice versa. It is something like this:
public class MerchantStatusConverter implements AttributeConverter<MerchantStatus, String> {
public String convertToDatabaseColumn(MerchantStatus value) {..}
public MerchantStatus convertToEntityAttribute(String value) {..}
}
The problem is that I don't want to create converter for each enum and ideally it should be generic class/interface and I will use polymorphism here. The problem is that fromString is static method and it seems that it is impossible to create static method that returns generic type.
Are there any solutions of this problem?
The problem is that I don't want to create converter for each enum and
ideally it should be generic class/interface and I will use
polymorphism here.
You have no choice as your AttributeConverter implementation could not be parameterized when you annotate your entity.
You should indeed specify it only with the AttributeConverter class :
#Enumerated(EnumType.STRING)
#Convert(converter = MerchantStatusConverter.class)
private MerchantStatus merchantStatus;
But you could define an abstract class that defines the logic and subclassing it in each enum class.
To achieve it, you should introduce an interface in front of each enum class that declares a fromString() and a toString() method.
The interface :
public interface MyEnum<T extends MyEnum<T>>{
T fromString(String type);
String toString(T enumValue);
}
The enum that implements the interface :
public enum MerchantStatus implements MyEnum<MerchantStatus> {
NEW("New"), ...
#Override
public MerchantStatus fromString(String type) {
...
}
#Override
public String toString(MerchantStatus enumValue) {
...
}
}
The abstract AttributeConverter class :
public abstract class AbstractAttributeConverter<E extends MyEnum<E>> implements AttributeConverter<E, String> {
protected MyEnum<E> myEnum;
#Override
public String convertToDatabaseColumn(E attribute) {
return myEnum.toString(attribute);
}
#Override
public E convertToEntityAttribute(String dbData) {
return myEnum.fromString(dbData);
}
}
And concrete AttributeConverter class that needs to declare a public constructor to assign the protected myEnum field to an enum value (whatever of it):
public class MerchantStatusAttributeConverter extends AbstractAttributeConverter<MerchantStatus> {
public MerchantStatusAttributeConverter(){
myEnum = MerchantStatus.NEW;
}
}
If you want a general Converter for all your enum classes, you can use reflection, as long as you stick to a naming convention.
Your convention seem to be that you use toString() for enum -> String conversion, and a static fromString(String) for String -> enum conversion.
A Converter for that would be something like this:
public class EnumConverter<T extends Enum<T>> implements AttributeConverter<T, String> {
private final Method fromStringMethod;
public EnumConverter(Class<T> enumClass) {
try {
this.fromStringMethod = enumClass.getDeclaredMethod("fromString", String.class);
} catch (NoSuchMethodException e) {
throw new NoSuchMethodError(e.getMessage());
}
if (! Modifier.isStatic(this.fromStringMethod.getModifiers()))
throw new NoSuchMethodError("fromString(String) is not static");
if (this.fromStringMethod.getReturnType() != enumClass)
throw new NoSuchMethodError("fromString(String) does not return " + enumClass.getName());
}
public String convertToDatabaseColumn(T value) {
return value.toString();
}
#SuppressWarnings("unchecked")
public T convertToEntityAttribute(String value) {
try {
return (T) this.fromStringMethod.invoke(null, value);
} catch (IllegalAccessException e) {
throw new IllegalAccessError(e.getMessage());
} catch (InvocationTargetException e) {
throw new RuntimeException("Error calling fromString(String): " + e, e);
}
}
}
You then construct it by naming the class, e.g.
new EnumConverter<>(MerchantStatus.class)
new EnumConverter<>(EmployerType.class)
You should be able to do the following:
public class Converter<T extends Enum<T>, U> implements AttributeConverter<T, U> {
public U convertToDatabaseColumn(T value) {
...
}
public T convertToEntityAttribute(U value) {
...
}
}
I'm trying to inject several datastax Mappers but the Provider creation code is always the same and writing a provider for each type is redundant.
The provider code is
public class FooMapperProvider extends Provider<Mapper<Foo>> () {
private final MappingManager mappingManager
#Inject
FooMapperProvider(MappingManager) {
this.mappingManager = mappingManager;
}
#Override
public Mapper<Foo> get() {
mappingManager.mapper(Foo.class);
}
}
Is it possible to bind or create the provider for
bind(Foo.class).toProvider(GenericMapperProvider.class)
bind(Bar.class).toProvider(GenericMapperProvider.class)
so that get is called in a way mappingManager.mapper can create a mapper based on the class for that specific binding?
I thought about trying something like
public class MapperProvider<T> implements Provider<Mapper<T>> {
private final MappingManager mappingManager;
private final Class klass;
#Inject
public MapperProvider(MappingManager mappingManager, Class klass) {
this.mappingManager = mappingManager;
this.klass = klass;
}
#Override
public Mapper<T> get() {
return mappingManager.mapper(klass);
}
}
but I can't figure out how to specify the class and inject the dependency
public class MapperProvider<T> implements Provider<Mapper<T>> {
private final MappingManager mappingManager;
private final TypeLiteral<T> type;
#Inject
public MapperProvider(MappingManager mappingManager, TypeLiteral<T> type) {
this.mappingManager = mappingManager;
this.type = type;
}
#Override
public Mapper<T> get() {
return mappingManager.mapper(type.getRawType());
}
}
bind(new TypeLiteral<Mapper<Foo>>(){})
.toProvider(new TypeLiteral<MapperProvider<Foo>>(){});