Spring AutoWire gives Null Pointer exception - java

I have a maven mutli module project :
Project
-ProjectDAO
-Projectx
ProjectDAO uses spring + hibernate
From Projectx I am trying to use something like below:
public class TesMessage implements ITesMessage {
#Autowired
private IGlobal iGlobal;
...
iGlobal.getSomeMethod();
}
.. With the above code I get Null Pointer exception, Am i missing anything?
I have this in my appContext.xml
<context:component-scan base-package="com.test.nty.dal">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Repository" />
</context:component-scan>
Thanks

Believe the exception: Yes, you're missing something.
You don't show how you've annotated the IGlobal interface. The exception suggests that it's not under Spring's control. You have to let the Spring app context handle its creation as well as your TextMessage.
I would question this design. I don't see why every text message would need something global. Looks like a singleton bottleneck to me.

Related

How to load two ResourceBundles and inject them separately

I am using Spring for loading localized resource bundles into my application. Here is what I have done.
<bean id="systemMessages" class="o.s.c.s.ResourceBundleMessageSource">
<property name="basename" value="locale/system">
</bean>
<bean id="clientMessages" class="o.s.c.s.ResourceBundleMessageSource">
<property name="basename" value="locale/client">
</bean>
I want to load messages based on the locale in my controller, and I tried both these ways below
#Autowired
#Qualifier("clientMessages")
ResourceBundleMessageSource clientMessages;
#Resource(name="systemMessages")
ResourceBundleMessageSource systemMessages;
EDIT
The application is a JAXRS application and the injection is being tried in a Global Exception Mapper. From the comments I now understand that this class would have been created by the JAXRS container and not Spring ( Code below). How to let Spring know that this injection must work?
import javax.ws.rs.WebApplicationException;
//other imports
public class GlobalWebApplicationException extends WebApplicationException{
private String systemMessage;
private String clientMessage;
//Autowire the multiple resourcebundles
public GlobalWebApplicationException (String key, Locale locale) {
// this is where I want to use the injected object fetch the property
}
public doSomething(){
// Business Logic
}
}
But the injection is not happening and I am getting an NPE. How do I achieve this?
When using Spring and having it do auto wiring using annotations the fields cannot be null. The dependencies need to be satisfied on startup of the application. If that doesn't happen there can be 1 of 2 things wrong
You haven't enabled annotation processing
You aren't using a spring managed bean but are creating instances yourself
For the first option add <context:annotation-config /> to your application context, or if you want to do component scanning add <context:component-scan /> the latter already implies annotation processing.
For the second option you need to make your bean a spring managed bean and use that instead of creating new instances yourself.

Null Pointer on Autowired Service Object in Spring 4

I am learning Spring MVC, and am trying to troubleshoot an issue with an #Autowired Service object. I have the following annotation:
#Autowired
private UserServiceBLInt userService;
This is within the context of a Controller class, and I get a NullPointerException when using the userService object. Nowhere in the class am I manually instantiating the userService object, since my understanding is that for #Autowired to work, I have to let spring be responsible for creating the object.
My suspicion is that in the spring configuration file, the component-scan base-package declared incorrectly, so Spring doesn't know where to find the classes.
<context:component-scan base-package="com.app.service.**" />
The UserServiceBLInt is in com.app.service.int
The concrete implementation is in com.app.service.impl
Is the ** notation correct?
The example in the Spring reference doc does not use .**:
<beans>
<context:component-scan base-package="com.acme"/>
</beans>
So most likely, this is your problem.
Don't use the .** ind base package declartion. just specify the package name whose Bean you want to autowire by Spring, you can use comma separated values for package name as well.

Spring MVC : Asynchronous giving beancurrently in creation exception

I am working on a Spring-MVC application in which I want to use #Async at-least for the methods which are fire-and-forget. When I try to use #Async and I have used #EnableAsync annotation too for class, the actions inside the method are not performed. When I add task executor in servlet-context.xml, then I get an error bean is getting currently created. I am new to Async, can anyone tell me how I can use it.
I am not using Eager loading btw.
Error log :
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'groupNotesService': Bean with name 'groupNotesService' has been injected into other beans [mattachService] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.
Code :
GroupNotesServiceImpl :
#Service
#Transactional
#EnableAsync
public class GroupNotesServiceImpl implements GroupNotesService {
#Override
#Async
public void editGroupNote(GroupNotes mnotes, int msectionId) {
//Code to be executed, which is not getting executed
}
}
Servlet-context.xml :
<task:annotation-driven executor="executor" />
<task:executor id="executor" pool-size="20"/>
<mvc:annotation-driven />
<mvc:default-servlet-handler />
<resources mapping="/resources/" location="/resources/" />
If I remove any of the mvc lines above, I get a servlet.init() threw load exception error.
Also, Is it possible to use Async where I am returning int? I checked out the Future tag, but I don't know what modifications are required.
Here is the method that returns int.
#Override
public int saveGroupNoteAndReturnId(GroupNotes mnotes, int msectionid) {
// saves note and returns its id.
}
MattachService bean :
<beans:bean id="mattachDAO"
class="com.journaldev.spring.dao.GroupAttachmentsDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory" />
</beans:bean>
<beans:bean id="mattachService"
class="com.journaldev.spring.service.GroupAttachmentsServiceImpl">
<beans:property name="groupAttachmentsDAO" ref="mattachDAO" />
</beans:bean>
Edit
I checked out that there is a problem to run #Transactional and #Async both in one class. Jira SPR-7147. The workaround suggested there was to introduce a normal facade, and I really don't know what that means.
#EnableAsync should be in configuration, not the service itself. Since you seem to use xml configuration, check this https://stackoverflow.com/a/20127051/562721. It recommends to declare org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor to take care of #Async annotations

MongoDB throws NullPointerException in Class DBTCPConnector

I'm trying to get a grip using MongoDB with the Spring Data MongoDB framework. I tried severeal approaches to connect to my local DB and insert + retrieve some collections and documents, using the official Spring Reference Documentation and some simple examples like this Hello-World-Demo.
Actually, for the beginning I'm going to use the MongoTemplate to keep it simple. But now I'run into the following problem.
When I use the Spring Configuration with annotations configure the setting needed to connect to my local DB, everything works fine.
Otherwise When I use XML for the configuration, I run into an java.lang.NullPointerException at com.mongodb.DBTCPConnector.getClusterDescription
Here are my configuration files and the example code for connecting to the DB:
Use Case 1 - Spring Configuration with annotations:
//package, imports etc. here
#Configuration
public class MongoConfiguration {
public #Bean MongoDbFactory mongoDbFactory() throws Exception {
return new SimpleMongoDbFactory(new MongoClient(), "Test1");
}
public #Bean MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongoDbFactory());
}
}
Using the configuration class like this ...
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MongoConfiguration.class);
MongoOperations mongoOperation = (MongoOperations) ctx.getBean("mongoTemplate");
ctx.close();
for (String s : mongoOperation.getCollectionNames()) {
System.out.println(s);
}
.. creates this output:
documents
leute
system.indexes
system.users
Use Case 2 - XML configuration (SpringConfig2.xml):
<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"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<mongo:mongo host="127.0.0.1" port="27017" />
<mongo:db-factory dbname="Test1" />
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
</bean>
</beans>
Using the configuration file like this ...
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("SpringConfig2.xml");
MongoOperations mongoOperation = (MongoOperations) ctx.getBean("mongoTemplate");
ctx.close();
for (String s : mongoOperation.getCollectionNames()) {
System.out.println(s);
}
.. results in this error
java.lang.NullPointerException
at com.mongodb.DBTCPConnector.getClusterDescription(DBTCPConnector.java:404)
at com.mongodb.DBTCPConnector.getMaxBsonObjectSize(DBTCPConnector.java:653)
at com.mongodb.Mongo.getMaxBsonObjectSize(Mongo.java:641)
at com.mongodb.DBCollectionImpl.find(DBCollectionImpl.java:81)
at com.mongodb.DBCollectionImpl.find(DBCollectionImpl.java:66)
at com.mongodb.DB.getCollectionNames(DB.java:510)
at org.springframework.data.mongodb.core.MongoTemplate$13.doInDB(MongoTemplate.java:1501)
at org.springframework.data.mongodb.core.MongoTemplate$13.doInDB(MongoTemplate.java:1499)
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:394)
at org.springframework.data.mongodb.core.MongoTemplate.getCollectionNames(MongoTemplate.java:1499)
at test.main(Test.java:28)
When debugging DBTCPConnector.getClusterDescription, it seems that in the second case the private class variable cluster is for some reason not instantiated, leading to the described error.
What I'd like to know is: am I doing anything wrong within my XML-configuration or when using this config / context? Why does using XML-configuration end in an error, while using annotation configuration just works fine?
Basically (in the end) I just "copy+paste"'d the code examples from the official references for Spring / Spring Data MongoDB.
I'd appreciate any help / suggestions :)
Thanks to the hint from Tushar Mishra in the comments I was able to track down the origin of the error and why it occurs in one case but not in the other.
I'll try to explain in short, maybe it'll save someone some research time (or remember me if I perhaps run into this or a similar error again).
When closing either the AnnotationConfigApplicationContext-object (UC1) or the AnnotationConfigApplicationContext-object (UC2) with ctx.close(), from somewhere
org.springframework.beans.factory.DisposableBean#destroy() is invoked. As far as I understood, within there used singleton beans get destroyed by invoking the destroy()-methods
of each of those beans.
In short: closing the XXApplicationContext-object also destroys the MongoFactoryBean and with it closes the connection to the MongoDB.
So using c**tx.close()** at the described position leads to using a MongoOperations-object on a closed connection at the next line, resulting in the described NullPointerException.
And for why the sample code with Annotations (UC1) runs fine, whereas the sample code configured with XML (UC2) just breaks with an NullPointerException:
In UC1, the org.springframework.beans.factory.DisposableBean#destroy()-call is interupted by some DisposableBeanMethodInterceptor, which tries to redirect to a dispose() method.
But there is no method implemented in MongoFactoryBean, so the Mongo-connection stays alive and can be used even after ctx.close() was invoked. I think the connection will get killed later by the garbage collector, leading to the same error.
I'm not sure what to make of this, yet. If I should implement a dispose()-method myself or something alike. But at least I figured out, why this code sample behave different, although supposed to do the same thing.
Maybe it helps someone. Thanks again, Tushar, for giving a hint to the right direction.

Spring 3 bean is not being wired correctly

I have a web controller which I configure in the controller-config.xml using
<mvc:annotation-driven />
<context:annotation-config />
<context:component-scan base-package="com.ecommerce.web.controller" />
The controller has the #Controller annotation like below.
#Controller
public class HomeController
I have included the #Autowired annotation on the dependencies, but when I first start up the application I am unable to set any properties on the wired objects.
For example, I have a storeProfile object which when in debug mode I see has multiple properties set as it should.
But, when I try to set one of the storeProfile properties on an #Autowried bean it is still null or empty string!?
If you look at the attached images it shows that after I step past the line this.storeProfileContext.setStoreProfile(storeProf ile) the debugger still shows the storeProfile property as null
Actually, there are a couple dependencies which look like they are created (they are not null and the application functions), but I am unable to set anything on these objects.
I asked the same question on the Spring forums too - hoping to get this figured out.
Thanks so much!
That is because you are looking at the fields of the proxy, which gets created when you have <aop:scoped-proxy/>, if you invoke your getter for the set values, you should see the correct values retrieved from the proxied object.
The instances you are examining are CGLIB proxies.
CGLIB subclasses your beans, delegating all method invocations to the target beans.
So the fields of the super classes are still present but not used.

Categories

Resources