null pointer exception whilst using spring - although bean loaded correctly - spring

i have a bean:
public class StatusPollingFilter extends AbstractDiscovery implements UserTester
defined as :
<bean
id="statusPollingFilter"
class="com.xxxxx.yyyyyyy.zzz.StatusPollingFilter">
<property
name="evoDao"
ref="evoDaoFacade">
</property>
it loads ok, as logs show:
2013-03-07 11:30:14,703 INFO DefaultListableBeanFactory [RunJSPModule] - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#14966cc: defining beans [org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.config.internalTransactionAdvisor,tilesConfigurer,viewResolver,urlMapping,discovery,statu
sPollingFilter,
when i try to use it as:
TopoObject topoobj = evoDao.getTopoObjectDao().findById(topoId);
evoDao is the main guy doing the work this is defined in:
class AbstractDiscovery
as:
//Reference to the DAO facade, for accessing the database via hibernate.
protected EvoTAMDAOFacade evoDao;
The Question?
because i extend AbstractDiscovery i thought i would be able to access evoDao and use it as normal to get my Dao but it seems not - where am i going wrong?
why can it not find the Dao?
The EvoTAMDAOFacade is injected into AbstractDiscovery as:
/**
* DI method for accessing the DAO facade for accessing the
* database via hibernate.
* #param dao
*/
public void setEvoDao(EvoTAMDAOFacade dao)
{
this.evoDao = dao;
}
the getTopoObjectDao() is defined in the injected EvoTAMDAOFacade of as:
public TopoObjectDAO getTopoObjectDao()
{
return this.topoObjectDao;
}
AbstractDiscovery is defined as:
public abstract class AbstractDiscovery implements Discovery
The exception is :
[07 Mar 2013 11:42:24:353] POLL: Exception while getting obj during status update java.lang.NullPointerException 162.109.37.114 at:
java.lang.NullPointerException
Another Q? the statusPollFilter is running as thread in a scheduler for multiple objects - i'm not actually sure i should be defining it as a singleton bean but how do i access the Dao if i don't?
thanks in advance for your help.

having read more - i have come across the ans.
because the StatusPollingFilter object is under control of scheduler (i knew that scheduler had something to do with it) then it is unaware of the spring beans which is why i keep getting null when i try injecting the bean.
i created a class:
ApplicationContextProvider implements ApplicationContextAware
added static access
private static ApplicationContext appContext;
did a setter for it :
public void setApplicationContext(ApplicationContext context)
{
appContext = context;
}
and added
public static Object getBean(String beanName) throws BeansException
{
return appContext.getBean(beanName);
}
used in code as :
EvoTAMDAOFacade evoDao = (EvoTAMDAOFacade) ApplicationContextProvider.getBean("evoDaoFacade");
i now have access to the facade bean and all injected beans into facade.
i still have an issue with hibernate session but thats prob due to some other issue.
pt here is i don't have access to the bean as its not in control of the spring container so i needed to somehow get it , probably could have done it via the factory method but why mess around when there a simpler way.
thanks for help by anyone who may have posted or tried to understand my problem.

Related

Spring #Cachable method within the same class (self-invocation, proxy issue) - What is the best way to solve it?

I'm trying to call a #Cacheable method from within the same class.
And it didn't work. Because of:
In proxy mode (the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation (in effect, a method within the target object that calls another method of the target object) does not lead to actual caching at runtime even if the invoked method is marked with #Cacheable. Consider using the aspectj mode in this case. Also, the proxy must be fully initialized to provide the expected behavior, so you should not rely on this feature in your initialization code (that is, #PostConstruct).
It means, #Cachable(also #Transactional) works by proxy classes which is Spring AOP in. a internal call in the same class make call by 'this' instead of proxy classes.
To solve the problem, I should call a method by proxy or using AspectJ(another AOP).
So, I found 4 solutions.
What is your choice? and why others are not recommended?
Please, share your opinion!
using AspectJ (another AOP)
get the Bean from ApplicationContext and use it
#Service
public class UserService implements Service {
#Autowired
private ApplicationContext applicationContext;
private Service self;
#PostConstruct
private void init() {
self = applicationContext.getBean(UserService.class);
}
}
self-autowiring using #Resource //since Spring 4.3
#Component
#CacheConfig(cacheNames = "SphereClientFactoryCache")
public class CacheableSphereClientFactoryImpl implements SphereClientFactory {
/**
* 1. Self-autowired reference to proxified bean of this class.
*/
#Resource
private SphereClientFactory self;
#Override
#Cacheable(sync = true)
public SphereClient createSphereClient(#Nonnull TenantConfig tenantConfig) {
// 2. call cached method using self-bean
return self.createSphereClient(tenantConfig.getSphereClientConfig());
}
#Override
#Cacheable(sync = true)
public SphereClient createSphereClient(#Nonnull SphereClientConfig clientConfig) {
return CtpClientConfigurationUtils.createSphereClient(clientConfig);
}
}
make the Bean scope of the class as 'prototype' instead of 'singleton'
#Service
#Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
class AService {
private final AService _aService;
#Autowired
public AService(AService aService) {
_aService = aService;
}
#Cacheable("employeeData")
public List<EmployeeData> getEmployeeData(Date date){
..println("Cache is not being used");
...
}
public List<EmployeeEnrichedData> getEmployeeEnrichedData(Date date){
List<EmployeeData> employeeData = _aService.getEmployeeData(date);
...
}
}
I'm a newbie in spring :)
Actually, I choose the 4th solution, but I felt it isn't a good way. because I just need to call the caching method by proxy, and it make several beans to achieve it.
After reading articles, I think AspectJ is the best choice. It looks cool, Spring recommends it, and many people also recommend too.
But I don't understand how to AspectJ works (I will study) and I also don't know why others is not recommended.
references
Spring Cache #Cacheable - not working while calling from another method of the same bean
Spring cache #Cacheable method ignored when called from within the same class
https://spring.io/blog/2012/05/23/transactions-caching-and-aop-understanding-proxy-usage-in-spring
https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#cache

spring boot application - get bean from static context

I have a instance of a class that is created outside of Spring that I'd like to have access to Spring beans so that it may fire an event and be observed by Spring beans. I'm not using Spring web, my application is running from the command-line via spring boot.
The only option you have is to expose the Spring context of your application using a static method so that the object that is not managed by Spring can use it to get references to managed beans it needs.
Start with a wrapper for the context. Create a regular managed bean which required reference to the context in its constructor. The reference is assigned to a static class field, which also has a static getter:
#Service
class ContextWrapper {
private static ApplicationContext context;
#Autowired
public ContextWrapper(ApplicationContext ac) {
context = ac;
}
public static ApplicationContext getContext() {
return context;
}
}
Use the static getter to get access to context in the object which is not managed by Spring and get reference to beans using methods available in the context:
SomeBean bean = ContextWrapper.getContext().getBean("someBean", SomeBean.class);
// do something with the bean
Last thing you need is communication channel from Spring beans to non-managed object. For instance, the SomeBean can expose a setter which will accept the non-managed object as a parameter and store the reference in a field for future use. The object mast get references to managed beans using the static context accessor mentioned above and use the setter to make the bean aware of its existence.
#Service
class SomeBean {
// ... your bean stuff
private SomeClass someclass;
public void setSomeClass(Someclass someclass) {
this.someclass = someclass;
}
private void sendEventToSomeClass() {
// communicate with the object not managed by Spring
if (someClass == null) return;
someClass.sendEvent();
}
}
You can inject by constructor that spring beans, something like:
#Service
class Bean {
...
}
class NotBean {
private Bean bean;
public NotBean(Bean bean) {
this.bean = bean;
}
// your stuff (handle events, etc...)
}

ClassBridge with DAO class injected

I have a Hibernate Search ClassBridge where I want to use #Inject to inject a Spring 4.1 managed DAO/Service class. I have annotated the ClassBridge with #Configurable. I noticed that Spring 4.2 adds some additional lifecycle methods that might do the trick, but I'm on Spring 4.1
The goal of this is to store a custom field into the index document based on a query result.
However, since the DAO, depends on the SessionFactory getting initialized, it doesn't get injected because it doesn't exist yet when the #Configurable bean gets processed.
Any suggestions on how to achieve this?
You might try to create a custom field bridge provider, which could get hold of the Spring application context through some static method. When provideFieldBridge() is called you may return a Spring-ified instance of that from the application context, assuming the timing is better and the DAO bean is available by then.
Not sure whether it'd fly, but it may be worth trying.
Hibernate Search 5.8.0 includes support for bean injection. You can see the issue https://hibernate.atlassian.net/browse/HSEARCH-1316.
However I couldn't make it work in my application and I had implemented a workaround.
I have created an application context provider to obtain the Spring application context.
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext context;
public static ApplicationContext getApplicationContext() {
return context;
}
#Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
ApplicationContextProvider.context = context;
}
}
I have added it to the configuration class.
#Configuration
public class RootConfig {
#Bean
public ApplicationContextProvider applicationContextProvider() {
return new ApplicationContextProvider();
}
}
Finally I have used it in a bridge to retrieve the spring beans.
public class AttachmentTikaBridge extends TikaBridge {
#Override
public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
// get service bean from the application context provider (to be replaced when HS bridges support beans injection)
ApplicationContext applicationContext = ApplicationContextProvider.getApplicationContext();
ExampleService exampleService = applicationContext.getBean(ExampleService .class);
// use exampleService ...
super.set(name, content, document, luceneOptions);
}
}
I think this workaround it's quite simple in comparision with other solutions and it doesn't have any big side effect except the bean injection happens in runtime.

Inject vaadin #UIScope bean in spring #Component

I am using Vaadin Spring 1.0.0 and trying to figure out how could I inject beans that are available only within UI scope (when the user has the page opened) into classic spring #Component beans. Simple, let's have classes:
#Component
public class A {
#Inject
private IB b;
}
#UIScope
#SpringComponent
public class B implements IB {
}
And obviously during startup:
Caused by: java.lang.IllegalStateException: No VaadinSession bound to current thread
What is the normal way how to do it? I understand the whole concept, that beans are initialized on startup when UI scope is not available, but I use common libraries which are implemented in Spring with #Component and I want to implement some of the interfaces, but I can do it only in UI scope and not during startup.
Try injecting an aop scoped proxy instead.
For example:
#Scope(value="vaadin-ui", proxyMode=ScopedProxyMode.INTERFACES)
#SpringComponent
public class B implements IB {
}
I think that should work.
You need to get it from ApplicationContext itself:
#Component
public class A {
#Autowired
private ApplicationContext context;
public B getCurrentB(){
return context.getBean(B.class);
}
}
Note that it will throw exception if there is no UI bound to the current thread (normally). In other words, you MUST make sure this method only gets called during a UI request. Any kind of listener in Vaadin should be OK, as long as you're in the same thread with the request.

Superclass has no null constructors but no arguments were given. Spring Integration

I'm developing web application supported by Spring Integration. I'm using 1.0.4.RELEASE. I use CGLib proxies. I have a transactional message endpoint. Everything worked correctly, but I experimented a little bit with annotations. I use annotation-config, which works fine. I started from switching my service-activator configuration from xml to annotations, but it failed.
The following configuration worked correctly:
spring-integration.xml
<channel id="inChannel" />
<channel id="outChannel" />
<service-activator method="myMethod" input-channel="inChannel" ref="myService" output-channel="outChannel" />
MyService.java
#MessageEndpoint
#Transactional
public class MyService {
#Autowired
private MyDao myDao;
public MyObject myMethod(String message) throws Exception {
...
}
}
Trying to achieve exactly the same functionality using annotations (having in mind that I use CGLIB, so I do not need interface, but default constructor) I
removed service-activator from my .xml
changed MyService:
Changed MyService.java
#MessageEndpoint
#Transactional
public class MyService {
#Autowired
private MyDao myDao;
public MyService () {
}
#ServiceActivator(inputChannel="inChannel", outputChannel="outChannel")
public MyObject myMethod(String message) throws Exception {
...
}
}
I get the following error:
java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
I've seen many threads describing the following error article, but the problem was about custom classes. My problem regards Spring class.
Error creating bean with name 'myService'
nested exception is org.springframework.aop.framework.AopConfigException
Could not generate CGLIB subclass of class [class org.springframework.integration.handler.ServiceActivatingHandler]
java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
What's wrong? Why Spring tries to create proxy for spring class but not only for MyService? Is my class somehow wrapped? I don't understand what's happening. Help greatly appreciated.
Try taking off the #Autowired Tag. That looks for a constructor or setter method in order to populate that field. Considering you have neither of those, that might be the problem. Just a guess though.
OR you can make myDao package-protected or public (so that Spring can actually autowire it)
for instance:
#Autowired
myDao

Resources