I have a singleton service class like the below.
#Service
public class SingletonClass{
#Autowired
private ContextProvider provider;
public Context run(){
context = provider.createContext();
updateContext(context)
}
ContextProvider class:
public abstract class ContextProvider implements MyInterface{
public abstract Context createContext();
}
configuration:
<bean name="provider"
class="xyz.s.s.ContextProvider" >
<lookup-method name="createContext"
bean="someBean" />
</bean>
<bean id="somebean" class="com.x.y.someclass" />
<bean id="singletonService" class="com.x.y.SingletonClass" />
When i try to run the above using Junit ->instead of creating the lookup bean on demand, I am getting the below error
org.springframework.beans.factory.BeanCreationException:
aused by: java.lang.AbstractMethodError
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1585)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
It seems, the lookup method injection is not working in my case
I found the issue and fixed it.
I was having the abstract class implemented an interface. So at run time,
CGLIB unable to create a proxy class since there are unimplemented methods.
Compiler also did not complain, because this is abstract class and it did not expect us to add all implementations of the interface.
I removed the 'implements ' and it just works fine.
So the contextprovider will become,
public abstract class ContextProvider {
public abstract Context createContext();
}
Posting this message, since people might face same situation.
Related
I am trying to introduce a new bean to existing project
Current bean is
package w.x.y.z.pkgA
#Component
public class BeanA implements InterfaceA {
}
And I am trying to add new Bean to w.x.y.z.pkgB
package w.x.y.z.pkgB
public class BeanB implements InterfaceB {
#Autowired
private BeanA beanA
#PostConstruct
public void postConstructMethod() {
//Call some method in BeanA
}
}
From BeanB I want to access BeanA data and in BeanB post construct I want to register BeanB with BeanA. So I want to call BeanA method
And All these packages are packaged as jar
and spring context xml is
<context:annotation-config />
<context:component-scan base-package="w.x.y.z.pkgA,w.x.y.z.pkgB" />
<bean id="beanb" clas="w.x.y.z.pkgB.BeanB"></bean>
But during deployment I get exception about bean in create state
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'context': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:347)
at w.x.y.z.BeanA<init>(BeanA.java:25)
at w.x.y.z.BeanB.<init>(BeanB.java:35)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147)
I have also tried removed #Autowired and getting the BeanA object using getBeanFactory().getBean(BeanA.class). But I get same error.
If I remove bean entry from xml file them it gets deployed properly but post construct is never called as it is no longer a bean.
BeanA is not dependent on BeanB at all. No references?
Is there a way to get this #Autowired and #PostConstruct to work when 2 beans are in same jar?
You declare the bean as <bean id="beanb" clas="w.x.y.z.BeanB"> from w.x.y.z package.
Try with
package w.x.y.z
#Component
public class BeanA implements InterfaceA {
}
package w.x.y.z
public class BeanB implements InterfaceB {
private BeanA beanA
#PostConstruct
public void postConstructMethod() {
//Call some method in BeanA
}
// Getters and Setters
}
and
<context:annotation-config />
<context:component-scan base-package="w.x.y.z" />
<bean id="beanb" clas="w.x.y.z.BeanB">
<property name="beanA" value="beanA"/> <!-- Spring will create beanA as it is annotated with #Component -->
</bean>
I know there are threads similar to this issue. Below is my class and I am configuring it in spring.xml file. Actually HumanResourceService is an interface having only one method.
#Endpoint
public class HolidayEndpoint {
#Autowired
private HumanResourceService humanResourceService;
#Autowired
public HolidayEndpoint(HumanResourceService humanResourceService) throws JDOMException {
this.humanResourceService = humanResourceService;
}
}
My problem is that in my spring.xml file, when I define HumanResourceService as bean, it cannot be instantiated as this is an interface. How can I mention an interface in spring configuration file. My spring.xml file is below
<bean id="holidayEndpoint" class="com.mycompany.hr.ws.HolidayEndpoint" autowire="constructor" >
<property name="humanResourceService" ref="humanResourceService" />
</bean>
<bean id="humanResourceService" class="com.mycompany.hr.service.HumanResourceService" />
You can't, Spring needs something it can make an instance from, the interface isn't enough.
In your spring.xml, the value of the class attribute for your bean with id="humanResourceService" should be the name of your implementation class, not the interface. Spring needs you to tell it what implementation class you want it to use for this.
I am trying all the solutions from Google from last 4 days. but not working.
I am trying to autowire below Interface -
#Qualifier("roleAccessRepository")
#Repository
public interface RoleAccessRepository extends BaseJPACrudRepository<RoleAccess, Long> {
in PermissionEvaluator in following way.But its not working.
#Scope(proxyMode = ScopedProxyMode.INTERFACES, value = "prototype")
public class PermissionEvaluator implements org.springframework.security.access.PermissionEvaluator
{
#Autowired
RoleAccessRepository roleAccessRepository;
..........
Giving me error -
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: net.pa
ger.lrs.sql.db.RoleAccessRepository net.pager.lrs.security.PermissionEvaluator.roleAccessRepository;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying
bean of type [net.pager.lrs.sql.db.RoleAccessRepository] found for dependency: expected at least 1 b
ean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springf
But Repository defined in the same package and autowired in service class are working good.
#Service
#Transactional
public class AccountService extends BaseCrudService<Account> {
/** The account db. */
#Autowired
private AccountRepository accountDB;
}
My security.xml is as follows - which has base package net.pager.lrs which is parent directory.
<bean id="permissionEvaluator" class="net.pager.lrs.security.PermissionEvaluator">
<constructor-arg index="0">
Please help me.
Ok,
From the discussions above, I still think that the problem is with not having the concrete implementation of the Autowired interfaces. Just for the sake of common sense, if you do not provide an implementation, what will you execute using the reference of the Autowired interface.
There is a way where you do not define the implementation, spring can generate proxy beans and autowire, but that is of no use.
You might end up providing an anonymous implementation of the interface as well.
I'm trying to inject a constructor that takes some arguments. After compiling Spring complains it couldn't find a default constructor (I haven't defined it) and throws BeanInstatiationException and NoSuchMethodException.
After defining a default constructor the exceptions don't appear anymore, however my object is never initialized with the argument constructor, only the default one is called. Does Spring really require a default constructor in this case? And if yes, how can I make it use the argument constructor instead of the default one?
This is how I wire everything:
public class Servlet {
#Autowired
private Module module;
(code that uses module...)
}
#Component
public class Module {
public Module(String arg) {}
...
}
Bean configuration:
<beans>
<bean id="module" class="com.client.Module">
<constructor-arg type="java.lang.String" index="0">
<value>Text</value>
</constructor-arg>
</bean>
...
</beans>
Stack trace:
WARNING: Could not get url for /javax/servlet/resources/j2ee_web_services_1_1.xsd
ERROR initWebApplicationContext, Context initialization failed
[tomcat:launch] org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'module' defined in URL [...]: Instantiation of bean failed;
nested exception is org.springframework.beans.BeanInstantiationException: Could not
instantiate bean class [com.client.Module]: No default constructor found; nested
exception is java.lang.NoSuchMethodException: com.client.Module.<init>()
Spring only "requires" a default constructor if you plan on instantiating it without any arguments.
for example, if your class is like this;
public class MyClass {
private String something;
public MyClass(String something) {
this.something = something;
}
public void setSomething(String something) {
this.something = something;
}
}
and you set it up in Spring like this;
<bean id="myClass" class="foo.bar.MyClass">
<property name="something" value="hello"/>
</bean>
you're going to get an error. the reason is that Spring instantiates your class new MyClass() then tries to set call setSomething(..).
so instead, the Spring xml should look like this;
<bean id="myClass" class="foo.bar.MyClass">
<constructor-arg value="hello"/>
</bean>
so have a look at your com.client.Module and see how its configured in your Spring xml
Most probably you are using component-scanning and since you define annotation #Component for class Module it tries to instantiate the bean. You do not need #Component annotation if You are using XML for bean definition.
Just faced the same problem, i guess till now you might have solved the problem.
Below is what you could have changed your bean configuration to,
<bean id="module" class="com.client.Module">
<constructor-arg value="Text"/>
</bean>
I have 2 classes
public class Abcd{
private String username;
private String password;
public Abcd(#Value("${username}") String userName, #Value("${password}") String password) {
...
}
public String retrieveValues(){
......
return "someString";
}
}
public class SomeClass{
#Autowired
private Abcd obj;
public String method1(){
obj.retrieveValues();
}
I have a Xml as below.
<context:annotation-config />
<context:property-placeholder location="classpath:applNew.properties" />
<bean id="abcd" class="com.somecompany.Abcd">
<constructor-arg type="java.lang.String" value="${prop.user}" />
<constructor-arg type="java.lang.String" value="${prop.password}" />
</bean>
<bean id="someclass"
class="com.differentcompany.SomeClass">
</bean>
When I build the project and start the server, i see the below exceptions.
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'abcd' defined in URL []: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class []: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
Caused by: java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
I dont understand what could be the issue to do a constructor injecting this way. Is there any solution for this?
Classes to be proxied by CGLIB (for AOP support) must have no-args constructors.
These no-args constructors don't have to be public and it doesn't affect anything else - you can use other constructors as usually:
public class Abcd{
// Dummy constructor for AOP
Abcd() {}
public Abcd(#Value("${username}") String userName, #Value("${password}") String password) { ... }
...
}
See also:
7.6 Proxying mechanisms