WELD-001562: Producer method with Generic signature - dependency-injection

I am using weld 4.0 and in one of my producer methods, I have this signature:
#Produces
#ConfigurationType
public <T extends IConfiguration> T getConfigurationInstance(InjectionPoint injectionPoint){
<perform some logic, create an instance of class T and return>
}
The objective is to have several configurations. Based on the ConfigurationType (Database/Server/Datasource blah, blah), return a Configuration instance of a specific type, that implements the IConfiguration interface so that I can treat the returned instance in a more readable format like a JDK14 record or its equivalent. In other words, I merely want to say serverConfigurationInstance.port() to read the port, where serverConfigurationInstance is Produced and returned by the Injector logic.
Now, the weld container when booted up tells me this:
An exception occured while executing the Java class. WELD-001562: A producer method return type may not be a type variable or an array type whose component type is a type variable:
[ERROR] [EnhancedAnnotatedMethodImpl] #ConfigurationType #Produces public config.ConfigurationInjector.getConfigurationInstance(InjectionPoint)
[ERROR] at config.ConfigurationInjector.getConfigurationInstance(ConfigurationInjector.java:0)
The Jakarta weld documentation (4.0.1) or searching for the specific error code or the message did not lead me any further. What wrong am I doing?

If you check out the specs, it says:
If a producer method return type is a type variable or an array type whose component type is a type variable the container automatically detects the problem and treats it as a definition error.
This is the cause of the error you are getting.
The spec seems to allow returning a parameterized type with a type variable from a producer method, as long as the scope is #Dependent - which is your case. Something like:
#Produces
#ConfigurationType
public <T extends IConfiguration> Supplier<T> getConfigurationInstance(InjectionPoint injectionPoint){
<perform some logic, create a supplier of an instance of class T and return>
}
This way however, the container "magic" (e.g. interception) will happen on the container object, not the instance of IConfiguration you create, which may or may not be what you want.

Related

Can CDI dependency injection be optional?

In Spring DI, declaring an autowired field as Optional enables a client to not inject any value to it. Is this possible using Java EE's CDI? I tried Optional and it fails. I want to know if there is an equivalent mechanism I can use.
Here is what I tried:
public class OmeletteMaker implements EggMaker{
public static void main(String[] args){
WeldContainer container = new Weld().initialize();
OmeletteMaker omeletteMaker = container.instance().select(OmeletteMaker.class).get();
}
#Inject
Optional<Vegetable> vegetable;
}
I get an error message:
Exception in thread "main" org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [Optional] with qualifiers [#Default] at injection point [[BackedAnnotatedField] #Inject cafeteria.OmeletteMaker.vegetable]
There are many questions lurking in this seemingly simple question. I'll try to answer them bearing in mind the spirit of the question.
First, as a general rule, if you #Inject a Fred, that Fred cannot be null unless Fred is in #Dependent scope, and even then a producer method or custom bean will have to explicitly be written to return null. There are edge cases but in all modern CDI implementations this is a good rule of thumb to bear in mind.
Second, Optional isn't special. From the standpoint of CDI, an Optional is just another Java object, so see my first statement above. If you have something that produces an Optional (like a producer method) then it cannot make a null Optional (unless, again, the production is defined to be in the #Dependent scope—and if you were writing such a method to make Optional instances and returning null you are definitely going to confuse your users). If you are in control of producing Optional instances, then you can make them any way you like.
Third, in case you want to test to see if there is a managed bean or a producer of some kind for a Fred, you can, as one of the comments on your question indicates, inject a Provider<Fred> or an Instance<Fred>. These are "made" by the container automatically: you don't have to write anything special to produce them yourself. A Provider<Fred> is an accessor of Fred instances and does not attempt to acquire an instance until its get() method is called.
An Instance is a Provider and an Iterable of all known Freds and can additionally tell you whether (a) it is "unsatisfied"—there are no producers of Fred at all—and (b) it is "resolvable"—i.e. there is exactly one producer of Fred.
Fourth, the common idiom in cases where you want to see if something is there is to inject an Instance parameterized with the type you want, and then check its isResolvable() method. If that returns true, then you can call its get() method and trust that its return value will be non-null (assuming the thing it makes is not in #Dependent scope).
I hope this is helpful!

why abstract class instantiation isn't runtime error in dart?

In many languages if you try to instantiate abstract class you get compile time error.
In Dart however, you get warning while compiling and a runtime exception AbstractClassInstantiationError.
Why is that? Can someone provide an example, where it's reasonable to compile such code?
Dart tries to allow you to run your program while you are developing it.
That is why many things that are compile time errors in other languages are compile-time warnings and runtime errors in Dart. This includes "x is Foo" where Foo doesn't exist, type-annotating with a non-existing types, and calling constructors of partial (abstract) classes.
In short: because it's not a problem that prevents the program from being compiled (unlike a syntax error that might mean the rest of the file is interpreted wrongly), so there is no reason to stop you from running the code. Only if you hit the branch that actually depends on the problem will your program be stopped.
It appears that the answer is factory constructor in abstract class:
abstract class Foo {
factory Foo() { // make Foo appear to be instantiable
return new Bar();
}
some(); // some abstract method
Foo.name() {} just a named constructor
}
class Bar extends Foo {
Bar():super.name(); // call named super constructor
some() {} // implement abstract method
}
main() {
print(new Foo()); // "instantiate" abstract Foo
}
Output:
Instance of 'Bar'
Asking 'where it's reasonable to compile such code?' in Dart isn't very meaningful because Dart is an interpreted language - there is no compilation stage. Dart editors will issue warnings if they think you are making a type error as they analyse your code on the fly.
Factory constructors can be used to provide a 'default' concrete implementation of an abstract class as you have done in your example. This is used quite widely in Dart. For instance, if you create a new Map object you actually get a LinkedHashMap object - see this question and answer.
In your example your are not instantiating an instance of Foo ('new Foo' does not appear anywhere), you are instantiating a `Bar'. This is because when a factory constructor is called a new instance of its class is not automatically instantiated.

dart, keeping type checking on but letting proxys through?

Im passing a proxy object in to a method which expects a specific argument type, the proxy object isn't an instance of the expected type however it does through it's noSuchMethod support all the functionality of the expected concrete type, I want to keep the argument type specification for static type checking whilst I'm coding, I would also like to keep the type checking on whilst I'm debugging my code, but I thought it wouldn't throw type exceptions when the class that causes the error is a proxy object? is there anyway to do this with all the type checking on?
You could implement the argument type.
#proxy
class MyProxy implements MyArgumentType {
...
}

Java EE 6 : #Inject and Instance<T>

I have a question about the #Inject annotation in java ee 6 :
What is the difference between :
#Inject
private TestBean test;
#Inject
private Instance<TestBean> test2;
To have the reference :
test2.get();
Some infos about Instance : http://docs.oracle.com/javaee/6/api/javax/enterprise/inject/Instance.html
Maybe it's doesnt create the object until it's called by get() ? I just wanted to know which one is better for the jvm memory. I think direct #Inject will directly create an instance of the object , even if it's not used by the appplication...
Thank you !
The second is what's called deferred injection or initialization. Your container will elect do do the work of locating, initializing, and injecting the proper object for TestBean until you call get() in most circumstances.
As far as "which one is better", you should defer to the rules of optimization. Don't optimize until you have a problem, and use a profiler.
Another words, use the first one unless you can definitively prove the second one is saving you significant amounts of memory and cpu.
Let me know if that answers your question!
Further information on use cases for Instance can be found in documentation:
In certain situations, injection is not the most convenient way to obtain a contextual reference. For example, it may not be used when:
the bean type or qualifiers vary dynamically at runtime
there may be no bean which satisfies the type and qualifiers
we would like to iterate over all beans of a certain type
This is pretty cool so you can do something like
#Inject #MyQualifier Instance<MyType> allMycandidates;
So you can obtain an Iterator from allMyCandidates and iterate over all the qualified objects.

How to set a default constructor argument to null with StructureMap?

A class has a unique constructor taking IMyInterface as its argument. If I define a concrete type of IMyInterface and registers it to StructureMap then there is no issue and my class can be instanciated with this concrete type.
However, in some cases, no concrete type will be registered. In that case, I would like to receive null for the IMyInterface parameter. Instead I get an exception:
StructureMap Exception Code: 202
No Default Instance defined for PluginFamily IMyInterface.
Is it possible to define a default value for a missing plugin?
Context: my class, which is a service, uses the Spark view engine and defines some default namespaces. The service uses a ISparkNamespacesProvider (IMyInterface) to add aditional namespaces. The client app may register such a provider or not. That's why the constructor of the service will receive either a provider or none.
Taken from here:
For<IService>().Use<MyService>()
.Ctor<IMyInterface>("nameOfParameter").Is(null);
But You should think about why Your class is dependent on IMyInterface. If it's optional - that's a code smell. Maybe You should refactor it out as method argument for method that needs it or as settable property.
There shouldn't be need for switching between concrete implementation and null. When composing dependency graph at composition root, You should know exactly what will be Your dependencies w/o .If(isSomething()).Use<MyService>().Ctor<IMyInterface>(null).
You might want to check out this tekpub presentation and this book (look for so called MEAP access) about DI and IOC.
One way to accomplish what You want is using so called 'poor man dependency injection'. That is - to define second constructor:
public MyClass():this(null){...}
But I wouldn't recommend that.
StructureMap now supports this case via UseIfNone https://structuremap.github.io/registration/fallback-services/

Resources