Inject CDI bean into ContainerRequestFilter results into UnsatisfiedDependencyException - jersey

I'm trying to delegate the work of a request filter to a CDI bean. But Glassfish 4.0 gives me an exceptioon when I call the RestURL.
The filter definition
#Provider
#Authenticated
public class AuthenticationFilter implements ContainerRequestFilter{
#Inject
private AuthenticationService authenticationService;
#Override
public void filter(ContainerRequestContext containerRequestContext) throws IOException {
String token = containerRequestContext.getHeaderString("x-authentication-token");
if (!authenticationService.isAuthenticated(token)) {
containerRequestContext.abortWith(Response.serverError().entity("No authentication").build());
}
}
}
Defintion of the NameBinding so that we can tag specific resource URL's.
#NameBinding
#Target({ ElementType.TYPE, ElementType.METHOD })
#Retention(value = RetentionPolicy.RUNTIME)
public #interface Authenticated {
}
And the CDI bean definition.
#ApplicationScoped
public class AuthenticationService {
public boolean isAuthenticated(String token) {
boolean result = false;
if (token != null && token.length() > 0) {
....
}
return result;
}
}
And I do have a bean.xml file in the WEB-INF directory
<beans
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
</beans>
Thanks
Rudy

Related

Spring: Cannot get bean by using #Component and #Bean

I'm new in Spring framework.
I try to config 2 beans with #Bean annotation within #Component.
After that, I try to getBean (by name), I got a NoSuchBeanDefinitionException.
Please help me to resolve it.
Here is my code:
- The component:
package com.example.component;
#Component
public class FactoryMethodComponent {
private static int i;
#Bean
#Qualifier("public")
public TestBean publicInstance() {
return new TestBean("publicInstance");
}
#Bean
#Qualifier("tb1")
public TestBean1 publicInstanceTB1() {
return new TestBean1(publicInstance());
}
}
-The xml configuration file: app-context.xml.
<beans ...>
<context:component-scan base-package="com.example.*" />
</beans>
-The test code:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:app-context.xml" })
public class ComponentBeanTest {
#Test
public void test() {
System.out.println(((TestBean1)context.getBean("tb1")).getTestBean().getMethodName());
System.out.println(publicTestBean.getMethodName());
}
}
-Exception:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
bean
named 'tb1' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:577)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1111)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:276)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1127)
at com.example.proxy.ComponentBeanTest.test(ComponentBeanTest.java:38)
Replace #Component with #Configuration which indicates that a class declares one or more #Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime.
#Configuration
public class FactoryMethodComponent {
private static int i;
#Bean
#Qualifier("public")
public TestBean publicInstance() {
return new TestBean("publicInstance");
}
#Bean
#Qualifier("tb1")
public TestBean1 publicInstanceTB1() {
return new TestBean1(publicInstance());
}
}

how to create two instance of bean use anotate [duplicate]

With an XML configured Spring bean factory, I can easily instantiate multiple instances of the same class with different parameters. How can I do the same with annotations? I would like something like this:
#Component(firstName="joe", lastName="smith")
#Component(firstName="mary", lastName="Williams")
public class Person { /* blah blah */ }
It's not possible. You get a duplicate exception.
It's also far from optimal with configuration data like this in your implementation classes.
If you want to use annotations, you can configure your class with Java config:
#Configuration
public class PersonConfig {
#Bean
public Person personOne() {
return new Person("Joe", "Smith");
}
#Bean
public Person personTwo() {
return new Person("Mary", "Williams");
}
}
Yes, you can do it with a help of your custom BeanFactoryPostProcessor implementation.
Here is a simple example.
Suppose we have two components. One is dependency for another.
First component:
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
public class MyFirstComponent implements InitializingBean{
private MySecondComponent asd;
private MySecondComponent qwe;
public void afterPropertiesSet() throws Exception {
Assert.notNull(asd);
Assert.notNull(qwe);
}
public void setAsd(MySecondComponent asd) {
this.asd = asd;
}
public void setQwe(MySecondComponent qwe) {
this.qwe = qwe;
}
}
As you could see, there is nothing special about this component. It has dependency on two different instances of MySecondComponent.
Second component:
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
#Qualifier(value = "qwe, asd")
public class MySecondComponent implements FactoryBean {
public Object getObject() throws Exception {
return new MySecondComponent();
}
public Class getObjectType() {
return MySecondComponent.class;
}
public boolean isSingleton() {
return true;
}
}
It's a bit more tricky. Here are two things to explain. First one - #Qualifier - annotation which contains names of MySecondComponent beans. It's a standard one, but you are free to implement your own. You'll see a bit later why.
Second thing to mention is FactoryBean implementation. If bean implements this interface, it's intended to create some other instances. In our case it creates instances with MySecondComponent type.
The trickiest part is BeanFactoryPostProcessor implementation:
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
Map<String, Object> map = configurableListableBeanFactory.getBeansWithAnnotation(Qualifier.class);
for(Map.Entry<String,Object> entry : map.entrySet()){
createInstances(configurableListableBeanFactory, entry.getKey(), entry.getValue());
}
}
private void createInstances(
ConfigurableListableBeanFactory configurableListableBeanFactory,
String beanName,
Object bean){
Qualifier qualifier = bean.getClass().getAnnotation(Qualifier.class);
for(String name : extractNames(qualifier)){
Object newBean = configurableListableBeanFactory.getBean(beanName);
configurableListableBeanFactory.registerSingleton(name.trim(), newBean);
}
}
private String[] extractNames(Qualifier qualifier){
return qualifier.value().split(",");
}
}
What does it do? It goes through all beans annotated with #Qualifier, extract names from the annotation and then manually creates beans of this type with specified names.
Here is a Spring config:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="MyBeanFactoryPostProcessor"/>
<bean class="MySecondComponent"/>
<bean name="test" class="MyFirstComponent">
<property name="asd" ref="asd"/>
<property name="qwe" ref="qwe"/>
</bean>
</beans>
Last thing to notice here is although you can do it you shouldn't unless it is a must, because this is a not really natural way of configuration. If you have more than one instance of class, it's better to stick with XML configuration.
I just had to solve a similar case. This may work if you can redefine the class.
// This is not a #Component
public class Person {
}
#Component
public PersonOne extends Person {
public PersonOne() {
super("Joe", "Smith");
}
}
#Component
public PersonTwo extends Person {
public PersonTwo() {
super("Mary","Williams");
}
}
Then just use PersonOne or PersonTwo whenever you need to autowire a specific instance, everywhere else just use Person.
Inspired by wax's answer, the implementation can be safer and not skip other post-processing if definitions are added, not constructed singletons:
public interface MultiBeanFactory<T> { // N.B. should not implement FactoryBean
T getObject(String name) throws Exception;
Class<?> getObjectType();
Collection<String> getNames();
}
public class MultiBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
Map<String, MultiBeanFactory> factories = beanFactory.getBeansOfType(MultiBeanFactory.class);
for (Map.Entry<String, MultiBeanFactory> entry : factories.entrySet()) {
MultiBeanFactory factoryBean = entry.getValue();
for (String name : factoryBean.getNames()) {
BeanDefinition definition = BeanDefinitionBuilder
.genericBeanDefinition(factoryBean.getObjectType())
.setScope(BeanDefinition.SCOPE_SINGLETON)
.setFactoryMethod("getObject")
.addConstructorArgValue(name)
.getBeanDefinition();
definition.setFactoryBeanName(entry.getKey());
registry.registerBeanDefinition(entry.getKey() + "_" + name, definition);
}
}
}
}
#Configuration
public class Config {
#Bean
public static MultiBeanFactoryPostProcessor() {
return new MultiBeanFactoryPostProcessor();
}
#Bean
public MultiBeanFactory<Person> personFactory() {
return new MultiBeanFactory<Person>() {
public Person getObject(String name) throws Exception {
// ...
}
public Class<?> getObjectType() {
return Person.class;
}
public Collection<String> getNames() {
return Arrays.asList("Joe Smith", "Mary Williams");
}
};
}
}
The bean names could still come from anywhere, such as wax's #Qualifier example. There are various other properties on the bean definition, including the ability to inherit from the factory itself.
Continuing #espen answer, injecting beans with qualifiers and configuring them differently with external values.
public class Person{
#Configuration
public static class PersonConfig{
#Bean
//#Qualifier("personOne") - doesn't work - bean qualifier is method name
public Person personOne() {
return new Person("Joe", "Smith");
}
#Bean
//#Qualifier("personTwo") - doesn't work - bean qualifier is method name
public Person personTwo(#Value("${myapp.second.lastName}") String lastName) {
return new Person("Mary", lastName);
}
}
/* blah blah */
}
#Component
public class SomePersonReference{
#Autowired
#Qualifier("personTwo")
Person marry;
}
Should you need to inject, in the new created object, beans or properties from the spring context, you can have a look at the following section of code in which I have extended the Espen answer by injecting a bean which is created from the spring context:
#Configuration
public class PersonConfig {
#Autowired
private OtherBean other;
#Bean
public Person personOne() {
return new Person("Joe", "Smith", other);
}
}
Have a look at this article for all the possibile scenarios.

Unable to assign autowired child bean to parent object in Spring Boot

XML Config:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<bean class="com.fossians.maven_courses.Say_Impl" id="id_Say_Impl" />
</beans>
Say_I
public interface Say_I
{
public void Say_I_m1();
}
Say_Impl
public class Say_Impl implements Say_I
{
public void Say_I_m1()
{
System.out.println("inside : public void Say_I_m1() \n");
}
}
Controller :
public class Controller_Test implements SpringApplicationContextInterface
{
#Autowired
private Say_Impl say_Impl;
//Below line not assigning, need to reassign into method
private Say_I say_I = (Say_I) say_Impl;
// private Say_I say_I = (Say_I) applicationContext.getBean("id_Say_Impl");
#RequestMapping(value = "/test10")
public String Test1()
{
say_I = say_Impl;
System.out.println("Say_Impl_auto : "+say_Impl);
System.out.println("Say_I : "+say_I);
say_I.Say_I_m1();
return " request value = test10 ";
}
}
public interface SpringApplicationContextInterface
{
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beanConfig.xml");
}
#SpringBootApplication
#ImportResource("classpath:beanConfig.xml")
public class Courses extends SpringBootServletInitializer
{
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
{
return application.sources(Courses.class);
}
}
The above code is part of a spring boot application.
This line of code inside "Controller_Test" class :
private Say_I say_I = (Say_I) say_Impl;
is not assigning Say_Impl object "say_Impl" reference into its parent object say_I. But if i am assigning it again into Test1() method then it is working.
But the below line of code is assigning the say_Impl reference into say_I object.
private Say_I say_I = (Say_I) applicationContext.getBean("id_Say_Impl");
Now my question is, when i am taking the say_impl object by autowiring why i need to reassign it into method? Is there any way to make it working without reassigning?
When i am taking the bean by application context then i need not to reassign, Why?
Very ugly code, legacy xml with spring boot WTF?
Try this
#Autowired
private Say_I say_I;
or better:
#SpringBootApplication
public class Courses {
public static void main(String[] args) {
SpringApplication.run(Courses.class, args);
}
#RestController
public class Controller_Test {
#Autowired
private Say_I say_I;
#RequestMapping(value = "/test10")
public String Test1() {
System.out.println("Say_I : " + say_I);
say_I.Say_I_m1();
return " request value = test10 ";
}
}
#Component
public class Say_I {
void Say_I_m1() {
System.out.println("inside : public void Say_I_m1() \n");
}
}
}

Autowired bean giving Null Pointer Exception

I am using Autowired annotation in a Service class to inject Dao dependency. The code I have written is:
public interface Service {
public List<String> getAllCountries() ;
}
public class ServiceImpl implements Service {
#Autowired
private TestDao testDao;
public TestDao getTestDao() {
return testDao;
}
public void setTestDao(TestDao testDao) {
this.testDao = testDao;
}
public List<String> getAllCountries() {
// TODO Auto-generated method stub
System.out.println("coming in here:" + testDao);
return testDao.getAllCountries();
}
}
public interface TestDao {
List<String> getAllCountries() ;
}
public class TestDaoImpl implements TestDao{
#Override
public List<String> getAllCountries() {
// TODO Auto-generated method stub
List<String> ls = new ArrayList<>();
ls.add("test1");
return ls;
}
}
And a controller
public class TestController {
public void doSth() {
Service service = new ServiceImpl();
try {
System.out.println("service obj:" + service);
List<String> list = service.getAllCountries();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Beans.xml:
<context:annotation-config/>
<bean id="controller" class="org.test.TestController"/>
<bean id="testDao" class="org.test.TestDaoImpl"/>
And a main class:
ApplicationContext context = new
ClassPathXmlApplicationContext("beans4.xml");
TestController obj= (TestController) context.getBean("controller");
obj.doSth();
But it is throwing NullPointerException in ServiceImpl class. These all classes are in the same package.
Can somebody help me understand what exactly is the issue?
Solution:
public class TestController {
#Autowired
Service service;
//remaining code as it is
}
Your Service class is not managed by Spring . Hence, the dependency is getting injected.
To make your service class managed,
You can use #Service stereo type annotation and do a component scan.
I mean,
package com;
#Service
public class ServiceImpl implement XXXX{
//Your changes
}
and in spring config file:
<context:component-scan base-package="com"/>
I did not see any bean declaration or annotation for the ServiceImpl.
//You canot do it like the following
#controller
class A{
ServiceImpl simp=new ServiceImpl();
}
class ServiceImpl{
#Autowired
Adao adoa;//throws NPE
}
//it should be like this
#Controller
class A{
#autowired
ServiceImpl simp;
}
#Service
class ServiceImpl{
#Autowired
Adao adoa;
}
#Repository
class Adao{
}
Your testDao dependency bean has not been injected and you need the Spring container that you are using annotations and also specify which packages need to be scanned for Autowiring by adding the following:
<context:annotation-config />
<context:component-scan base-package="org.test" />
You can look here on how you can auto wire spring beans.

spring 2.5.6 DI issue in jsf application

i get NPE(null pointer exception) each time when i try to insert data into database. help me to resolve this issue. i have import all the necessary libraries which are requried for spring.
this is my applicationContext.xml file where i have configure all the beans.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="personService" class="com.ecommerce.assignment.service.PersonService">
<property name="personDAO" ref="personDAO" />
</bean>
<bean id="personBean" class="com.ecommerce.assignment.bean.PersonBean" />
<bean id="personDAO" class="com.ecommerce.assignment.dao.PersonDAO" />
</beans>
this is interface of person DAO.
public interface IPersonDAO {
public void addPerson(Person instance);
}
this personDAO class implementing IpersonDAO interface and its unimplemented methods.
public class PersonDAO implements IPersonDAO {
#Override
public void addPerson(Person instance) {
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction().begin();
session.saveOrUpdate(instance);
session.getTransaction().commit();
session.close();
}
}
this is interface personService.
public interface IPersonService {
public void addPerson(Person instance);
}
public class PersonService implements IPersonService,Serializable {
private IPersonDAO personDAO;
public IPersonDAO getPersonDAO() {
return personDAO;
}
public void setPersonDAO(IPersonDAO personDAO) {
this.personDAO = personDAO;
}
#Override
public void addPerson(Person instance) {
getPersonDAO().addPerson(instance);
}
}
public class PersonBean implements Serializable {
private static final long serialVersionUID = 1L;
private String emailAddress;
private String password;
private String username;
#ManagedProperty(value = "#{personService}")
private IPersonService iPersonService;
public void addPerson(){
try{
Person person = new Person();
person.setUsername(getUsername());
person.setEmailAddress(getEmailAddress());
person.setPassword(getPassword());
iPersonService.addPerson(person);
}
catch(Exception ex){
ex.printStackTrace();
}
}
}
As your person bean is managed by Spring, you should use #Autowired annotation to make dependency injection, or inject it via XML, as you did for PersonService. You can as well declare the bean as #Component and #Scope.
You error is in injecting service in a bean by using JSF's #ManagedProperty annotation that works solely within JSF context, that is, with JSF managed beans, annotated with #ManagedBean, or declared via XML.

Resources