CDI managed beans inheritance till sub most object level. - cdi

I have below case.
A.java:-
#Named("a1")
#ApplicationScoped
class A{
}
B.java:-
#Specializes
class B extends A{
}
C.java:-
#Specializes
class C extends B{
}
When I'm using EL language in .xhtml page as (a1.orderForm) it is always pointing B class object.
Can somebody tell me what I have done wrong here in order to point the C class object.

It's my bad that Class C is not in the classpath due to maven exclusions while packaging it.

Related

JavaEE #Specializes annotation usage in inheritence

I have below scenario in our project.
#Named("a")
class A{ }
#Specializes
class B extends A{ }
#Specializes
class C extends B{ }
class Test{
#Inject
A a1;
}
In the test class, I want to inject the c class instance to the reference variable a1. I tried and it always injecting B.
How to do this?
Some more information:
I also want to mentioned that each of these 3 classes are in defferent projects. I'm tring to access the method from xhtml file not from Test class I'm using EL .
project1---> A
#Named("links")
#ApplicationScoped
class A{
public String getMethod1(){
}
}
project2(dependency to project1)----> B
#Specializes
class B extends A{
#Override
public String getMethod1(){
}
}
project3(dependency to project1,project2)---->C
#Specializes
class C extends B{
#Override
public String getMethod1(){
}
}
project4(dependency to project1,project2,project3)--->
MyPage.xhtm
<ui:include src="#{links.method1()}">
</ui:include>
When I'm trying to access by using EL 'links' always pointing the Class B.
Please advice me here.
The issue with my project structure with multiple maven modules. It lead to transitive dependency of the modules.

Groovy-based Spring Boot DI by example

In a traditional Spring DI-based application, you define an application.xml file and wire your beans as needed. Then in your main class you can just grab the ApplicationContext (that is configured with those wirings) or you can even make a class ApplicationContextAware.
But it seems everything has changed with Spring Boot. With Boot, it seems as though you annotate classes with #Component, however I have been unable to find any really good concrete examples of its use. Furthermore, I don't see solutions to scenarios where there are different instances of the same class/component that you want to wire into dependent beans differently, or how #Component-based injections work with Groovyisms like #Canonical. So I figured I would start with a concrete example and see if anyone could point me in the right direction:
// Groovy pseudo-code
#Canonical
class Fizz {
boolean checked
String umberGUID
}
#Canonical
class Buzz {
Fizz fizz // # always use Fizz instance #1 for all Buzz instances
int value
}
#Canonical
class Widget {
Fizz fizz // always use Fizz instance #2 for all Widget instances
String magicNumber // we need to define and wire a different magic number into each Widget instance
}
===
The example below is how I would accomplish dependency injection in Guice
using the classes and constraints above:
===
#Canonical
class Fizz {
#Inject #Named('checked')
boolean checked
#Inject #Named('umberGUID')
String umberGUID
}
#Canonical
class Buzz {
#Inject #Named('buzz_fizz')
Fizz fizz
#Inject #Named('buzz_value')
int value
}
#Canonical
class Widget {
#Inject #Named('widget_fizz')
Fizz fizz
#Inject #Named('magic_number')
String magicNumber
}
class MyGuiceModule extends AbstractModule {
#Override
void configure() {
}
// I wont write Provider methods for everything above, just showing
// 2 here as as an example.
#Provides #Named('buzz_fizz')
Fizz provideBuzzFizz() {
new Fizz(true, 'A', null)
}
#Provides #Named('widget_fizz')
Fizz provideWidgetFizz() {
new Fizz(false, 'D', 'blue')
}
}
How would I wire these beans up with each other in Spring Boot? The end result should be my ability to access, say, a Widget instance inside some fourth class, say, "HerpDerp", and have the Widget instance have properly-injected fizz/magicNumber fields on it. If that answer requires more info, I'm happy to whip something up, just ask!
From the description of your problem, This is really not a question dependent on features of SpringBoot, or Groovy, but is more of a question about Spring and how the configuration is different between the XML based configuration: application.xml, vs. a Java based configuration and/or with the use of annotations like #Component.
I bring this up, because if you are looking for documentation, then you would really want to refer directly to the Spring documentation on the Java based configuration to get the most information. A good start would be 5.12.1 Basic concepts: #Bean and #Configuration.
As I mentioned in the comments to your question, I don't think the #Canonical annotation affects this at all. #Canonical is simply a composite annotation, used to auto-generate commonly used methods to your Groovy classes. Specifically, as stated directly in the #Canonical GroovyDoc :
The #Canonical meta-annotation combines the #EqualsAndHashCode, #ToString and #TupleConstructor annotations. It is used to assist in the creation of mutable classes. It instructs the compiler to execute AST transformations which add positional constructors, equals, hashCode and a pretty print toString to your class.
None of which affects how beans are 'wired' up in your application, regardless of whether you are using Java, Spring, Groovy, or Spring Boot.
With all of that said, how would you accomplish your requirements using Spring Boot and Groovy?
I think the best way to demonstrate would be with a concrete example.
To provide a good example, I have created a Test SpringBoot project, with Gradle as the build tool and Groovy as the language of choice. For this example, I have place the Groovy classes in the com.app.bootinjection package. Here is a screenshot showing the folder and package structure:
To build the application, I have created the build.gradle file, seen in the image, with the following contents:
buildscript {
ext {
springBootVersion = '1.3.1.RELEASE'
}
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'groovy'
apply plugin: 'idea'
apply plugin: 'spring-boot'
repositories {
jcenter()
mavenCentral()
}
dependencies {
compile('org.codehaus.groovy:groovy-all:2.4.5')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.apache.tomcat.embed:tomcat-embed-jasper:8.0.30')
compile('com.fasterxml.jackson.core:jackson-core:2.7.1')
compile('com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.7.1')
}
springBoot{
mainClass = 'com.app.Application'
}
task wrapper(type: Wrapper) {
gradleVersion = '2.9'
}
Note in the build.gradle file, I have added 2 compile time dependencies on Jackson libraries. The 'core' library to support JSON output, and the 'dataformat' library to make the JSON output formatted nicely when viewing in a client like the browser.
Because this is to be a SpringBoot application, I have created a simple Application class annotated with the #SpringBootApplication annotation, which contains the main method and starts up our application:
Application.groovy:
package com.app
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.context.ApplicationContext
#SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args)
}
}
I also created a Groovy class representative of each class mentioned in your question: Fizz, Buzz, Widget and HerpDerp. Each is annotated with both the #Canonical annotation and the #Component annotation. When component scanning is done, Spring will see the #Component annotation and as a default will construct a single (singleton like) instance of that class and register it as a bean. By default, the bean name will be the same name of the class, with the first letter in the class name lower cased. So, the Fizz class will be instantiated as a bean and registered under the bean name 'fizz'. For more information, see the Spring docs in Section 5.10.1 #Component. By the way, you could change the 'scope' of the bean to have a new one created every time it is injected, using the #Scope(value = "prototype"). But, I would recommend only doing that if absolutely required.
Fizz.groovy:
package com.app.bootinjection
import groovy.transform.Canonical
import org.springframework.stereotype.Component
#Canonical
#Component
class Fizz {
boolean checked
String umberGUID = 0
}
Note: I have defaulted umberGUID to a value of 0 for demonstration/output purposes only.
Buzz.groovy:
package com.app.bootinjection
import groovy.transform.Canonical
import org.springframework.stereotype.Component
import javax.annotation.Resource
#Canonical
#Component
class Buzz {
#Resource
Fizz fizz1
int value
}
Widget.groovy:
package com.app.bootinjection
import groovy.transform.Canonical
import org.springframework.stereotype.Component
import javax.annotation.Resource
#Component
#Canonical
class Widget {
#Resource
Fizz fizz2
#Resource
Buzz buzz
#Resource
String magicalNumber
}
HerpDerp.groovy:
package com.app.bootinjection
import groovy.transform.Canonical
import org.springframework.stereotype.Component
import javax.annotation.Resource
#Component
#Canonical
class HerpDerp {
#Resource
Widget widget
#Resource
Fizz fizz
}
Note the usage of #Resource to inject beans into our objects. On our projects, we switched from #Autowired initially to #Inject and now to the #Resource annotation. In most cases, we have found the #Resource to be more appropriate and work more often within our projects. For example, notice the declaration of Fizz fizz1 in the class Buzz. Using the #Resource, it will inject the proper instance of Fizz where the bean name matches fizz1. For more clarification on when/why to use either, refer to Section 5.9.3 of the Spring docs, which states:
Tip
If you intend to express annotation-driven injection by name, do not primarily use #Autowired, even if is technically capable of referring to a bean name through #Qualifier values. Instead, use the JSR-250 #Resource annotation, which is semantically defined to identify a specific target component by its unique name, with the declared type being irrelevant for the matching process.
As a specific consequence of this semantic difference, beans that are themselves defined as a collection or map type cannot be injected through #Autowired, because type matching is not properly applicable to them. Use #Resource for such beans, referring to the specific collection or map bean by unique name.
#Autowired applies to fields, constructors, and multi-argument methods, allowing for narrowing through qualifier annotations at the parameter level. By contrast, #Resource is supported only for fields and bean property setter methods with a single argument. As a consequence, stick with qualifiers if your injection target is a constructor or a multi-argument method.
Sow how do we declare multiple beans of the same instance with different names? Remember you can use the #Component annotation alone to have Spring create a single instance of the class, defaulting the bean name to the class name (first character lower cased). You can also specify the name to override the default when using the #Component. For example: #Component("myBean"). Still, a single instance will be created. You can also specify the 'scope' as mentioned before using the #Scope("prototype") annotation. Now, each time the bean is injected, a new instance is created and injected.
If you want to control the number of beans created, specify unique names, and inject with the unique names, you need a more configurable solution. The preferred solution compared to the XML configuration is a Java based solution. You can create any class and configure it with the #Configuration annotation to indicate to Spring this class is intended to provide configuration information. For this example, I have created the ApplicationConfiguration class:
ApplicationConfiguration.groovy:
package com.app
import com.app.bootinjection.Fizz
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
#Configuration
class ApplicationConfiguration {
#Bean
Fizz fizz1(){
new Fizz(checked: true, umberGUID: 1)
}
#Bean
Fizz fizz2(){
new Fizz(checked: false, umberGUID: 2)
}
#Bean
#Scope("prototype")
String magicNumber(){
System.currentTimeMillis()
}
}
In the configuration, we create 2 methods for the Fizz class to create 2 unique fizz instances: fizz1 and fizz2. The name of the method will become the bean name, hence the method fizz1() and fizz2). Also note that only one instance of each is created. Spring takes care of instantiating the beans and only creating a single instance of each.
Now if you look back at the Buzz class, you will see that we use the #Resource annotation to inject the instance of the Fizz class that matches the bean name fizz1, which matches the bean name declared in the configuration class. The same is true for fizz2 in Widget. Also for demonstration purposes, notice that we also inject a Fizz instance in the HerpDerp class, called simply fizz. Since we annotated the Fizz class with #Component, when Spring performs the component scan, it will see the annotated class and by default create a separate instance with the default name of fizz.
In the configuration class, we have another bean method, annotated with #Bean called magicNumber(). Because we want the magic number injected to be unique every time, I have annotated that bean with a scope of prototype: Scope("prototype"). The bean, of type String, is then injected in the Widget class as required.
Finally, to put it all together, I have created a REST web service controller that simply injects the HerpDerp bean instance and returns it, which is then serialized to JSON to demonstrate the output we expect. The results are seen by accessing http://localhost:8080 :
TestController.groovy:
package com.app.bootinjection
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import javax.annotation.Resource
#RestController
class TestController {
#Resource
HerpDerp herpDerp
#RequestMapping("/")
def index(){
[herpDerp]
}
}
With a resulting output of:
<HerpDerp xmlns="">
<widget>
<fizz2>
<checked>false</checked>
<umberGUID>2</umberGUID>
</fizz2>
<buzz>
<fizz1>
<checked>true</checked>
<umberGUID>1</umberGUID>
</fizz1>
<value>0</value>
</buzz>
<magicalNumber>1464240486303</magicalNumber>
</widget>
<fizz>
<checked>false</checked>
<umberGUID>0</umberGUID>
</fizz>
</HerpDerp>
I hope this proves to be a comprehensive demonstration that covers the topics you are trying to accomplish. I think you will see that Spring/SpringBoot make it very easy to produce the results you are looking for. Good luck!

How to annotate helper class to be visible inside JSF?

I have a helper class, which is neither a stateful managed bean, nor a stateless EJB, nor an entity mapped to a table via JPA or Hibernate. It is simply a collection of static methods that do simple things like return date formats and similar.
Given that, in order for a Java class to be visible inside a JSF, that class must be annotated in a way that the container assigns as visible to JSFs, is there a way to annotate a helper class that does not match any of the standard JSF visible categories so that it becomes visible? An alternative, of course, is to have a conduit method in the managed bean that passes the call from the JSF to the helper class but I prefer not to clutter my managed bean if I can call it directly from the JSF. I understand that doing this with a stateless EJB from a JSF would be considered an anti-pattern but the methods in the class I wish to use are all very simple and non-transactional.
Mark your class as #ApplicationScoped. Make sure it has a public no-arg constructor and that this class doesn't have state and its methods are thread safe.
E.g.
Managed bean (pure JSF)
//this is important
import javax.faces.bean.ApplicationScoped;
#ManagedBean
#ApplicationScoped
public class Utility {
public static String foo(String another) {
return "hello " + another;
}
}
CDI version
//this is important
import javax.enterprise.context.ApplicationScoped;
#Named
#ApplicationScoped
public class Utility {
public static String foo(String another) {
return "hello " + another;
}
}
View
<h:outputText value="#{utility.foo('amphibient')}" />

CDI #Specializes and Constructor Injection with #Postconstruct

I have the following classes:
#Named
#ViewScoped
public class BaseClass {
private SomeDependency dep;
public BaseClass(){}
#Inject
public BaseClass(SomeDependency dep) {
this.dep = dep;
}
#PostConstruct
private void initialize() {
dep.doSomething(); // Point "A"
}
public String getProperty() {
return "BaseClass-Property";
}
#Specializes
public class SpecialClass extends BaseClass() {
#Override
public String getProperty() {
return "SpecialClass-Property";
}
}
Now in some .xhtml I have something like
<h:outputText value="#{baseClass.property}" />
This works fine without the SpecialClass. It breaks with a NullPointerException at Point "A" if I include the SpecialClass in the project.
Well, according to the Weld specification, this is more or less intended behavior:
When an enabled bean specializes another bean, the other bean is never
instantiated or called by the container.
Nevertheless, now I have to make sure that every #Specializes bean implements the complete constructor like
public SpecialClass() {}
#Inject
public SpecialClass(SomeDependency dep) { super(dep); }
which IMHO is kind of counter-intuitive and produces a lot of duplicated, boilerplate code, especially with something like 5-6 arguments for every constructor. Also, this is never caught when creating a new specialized bean since the project is always still compile clean.
Am I doing something wrong or is there no alternative to implementing the constructors over and over again?
BTW, I do use Constructor Injection to create easily testable classes where I can just use the constructor to "Inject" dummy implementations of the dependencies.
CDI 1.1 spec at section 4.3 says:
"The only way one bean can completely override a second bean at all
injection points is if it implements all the bean types and declares
all the qualifiers of the second bean."
Your base class is annotated with the Named qualifier and the specializing class is not. You should also mark it with Alternative and enable it in beans.xml. There's also the ViewScoped annotation. Unless it's the Omnifaces' ViewScoped, it looks like you're mixing up JSF managed beans with CDI beans.

Dependency injection in abstract and concrete classes

I'm using JSF and am running in a problem for quite awhile, I've searched at a lot of places but couldn't find any suitable answer.
Can I have dependency injection working in an abstract (or more generally a class higher in the hierarchy) class ?
Also, how should we handle annotations when working with inheritance ? I've read that the common practice would be not to annotate the abstract class, only the concrete one, but then, it would imply no injection for that abstract ?
My problem is that one (check the last comment) :
Abstract class
#ManagedBean
#ViewScoped
public abstract class AbstractController<T extends VersionedObject> implements Serializable {
#ManagedProperty("#{libraryVersionController}")
private LibraryVersionController libraryVersionController;
public List<T> loadFromDatasource(IVersionedServiceBase<T> service) {
log.info("Loading generic VO from data source");
VersionedObjectFilter filter = new VersionedObjectFilter();
filter.setSelectedLibVersion(libraryVersionController.getSelectedItem());
// etc
}
// getters, setters...
}
Concrete class
#ManagedBean
#ViewScoped
public class DomainController extends AbstractController<Domain> implements Serializable {
private List<Domain> allItems;
private Domain[] selectedItem;
#ManagedProperty(value = "#{domainService}")
private DomainService domainService;
#PostConstruct
public void loadFromDatasource() {
allItems = super.loadFromDatasource(domainService);
// !! DOES NOT WORK, null pointer exception on abstract class (libraryVersionController)
// etc
}
Getters and setters are correctly set up, as I could read in my .xhml it is the concrete class that I'm referencing (#{domainController.allItems}), there is only one #PostConstruct. I'm using JSF2.1 and Mojarra.
Thanks for your help !
As to your NullPointerException, my guess is that AbstractController.setLibraryVersionController is missing. As I understand it, when the AbstractController is constructed (presumably it has an implicit constructor even though it's abstract), that method is needed to fill in the appropriate value.
I know you said all getters and setters are there, but this one seems tricky, so possibly you missed it. If you add logging to this method, you can check that JSF is attempting to fill in the value, and also check whether the value is null or not.
On the general question of how dependency injection works with the inheritance hierarchy, I would guess that your approach is OK, and that dependencies are injected for the base class and then for the derived class, down the chain.

Resources