Spring injecting or autowiring datasource bean to class - java

this may be a very novice question, but I have searched and either I have a large gap in my understanding or am doing something incorrectly that I cannot figure out.
In my context file here is an excerpt
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${datasource.driverClassName}" />
<property name="url" value="${datasource.url}" />
<property name="username" value="${datasource.username}" />
<property name="password" value="${datasource.password}" />
</bean>
<bean id="myBeanOne" class="a.b.c.myBeanOne">
<property name="dataSource" ref="dataSource" />
</bean>
Now in myBeanOne I have:
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
#Autowired
public void setDataSource (DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public void myMethod() {
String sql = "'My generic SQL update query'";
try {
this.jdbcTemplate.update(sql);
} catch (org.springframework.dao.EmptyResultDataAccessException ex) {
}
System.exit(0);
}
when I try to execute this on the line where setDataSource is invoked I get this error:
ERROR org.springframework.integration.handler.LoggingHandler
org.springframework.integration.MessageHandlingException:
java.lang.NullPointerException
on the line: this.jdbcTemplate.update(sql);
I have tried maybe ten different configurations to get this to work, but I cannot seem to do it. Any assistance is appreciated, thank you.
Edit: as per Luiggi's comment:
//in yet another classes run method
myBeanOne bOne = SomeOtherClass.create(); //just returns new myBeanOne
bOne.myMethod();
Neither SomeOtherClass or this class are classified as beans in the context or have any presence in the context.
I know that this is a very basic question but I am struggling with it.
Thank you for your patience.

As noted in comments, the problem is that you're manually creating the bean instead of letting Spring container create it. Basically, you're doing this:
new MyBeanOne()
So Spring container can't inject any of the fields you have configured thus being null e.g. jdbcTemplate field. There are some solutions to this:
Convert your SomeOtherClass into a bean managed by Spring container and let it inject the MyBeanOne instance (probably using #Autowired annotation).
If latter approach can't be done since you need to manually create the bean, you can create the bean manually as shown here: How to create spring beans dynamically?
But this implementation makes you hardcode somewhere the spring config file name and use it in your code. So, a better approach would be option 3.
Look at this solution: Creating New Spring Beans on Demand, where you create a client abstract class with a method that Spring will implement to retrieve a new instance of your Spring managed bean.
I found another way to handle this by using #Configurable annotation. By decorating your bean with this annotation, you can create a new instance of the bean on demand and Spring will manage the injection of Spring managed beans for you. But to achieve this, Spring needs to use aspects behind the scenes and you should activate usage of aspects for your project. The explanation is quite long, so I provide links that explain in depth this solution:
Spring Framework: 7.8 Using AspectJ with Spring applications
Using Spring's #Configurable in three easy steps
Note that in order to enable this feature, you have to add a java agent when starting the JVM that will weave the class at runtime using aspects.

NullPointerException on the line: this.jdbcTemplate.update(sql);
If the NPE is actually on that line, then this.jdbcTemplate is obviously null. If this is true then either:
The setDataSource(...) method is not being called in Spring, possibly because the #Autowired is not right somehow. It would be easy to add a System.out.println(...) or put a debugging breakpoint in setDataSource to see if it is being called.
If it is being called then maybe there are more than one instance of a.b.c.myBeanOne? Are you for sure getting the instance being called from another class from the Spring context? Put a breakpoint in setDataSource and notice the this object reference id. Then put a breakpoint on the this.jdbcTemplate.update(...) line and make sure that the this reference-id is the same.

Related

Non Singleton (prototype) Spring beans JMX moniterable

I'm newbie to Spring JMX. And i want to monitor the prototype beans in my project through Spring JMX, I created a sample project to register a bean(Singleton) with Spring's MbeanExporter that is working. Then i googled to register the Non-Singleton bean with Spring JMX and monitor it but i didn't found any thing helpful.
I came across a Spring forum post that describes my problem but that answer is not to the point.
I kept googling for this issue and i found few posts on the stackoverlow itself that really helped me. Just copying the code here:-
#Component("MyPrototypeScopedBeanName")
#Scope(value = "prototype")
#ManagedResource
public class MyPrototypeScopedBeanName implements SelfNaming
#Autowired
MBeanExporter exporter;
.
.
#PostConstruct
private void init() throws Exception {
exporter.registerManagedResource(this);
}
.
.
.
#Override
public ObjectName getObjectName() throws MalformedObjectNameException {
return new ObjectName("com.foobar", "name", this.toString());
}
Also, you may want to configure your exporter to ignore this during autodetect, because the way autodetect works with prototypes, it will create yet another instance for itself that will add an additional instance to your JMX console.
<property name="autodetect" value="true"/>
<!-- Done to prevent creation of additional prototype during autodetect routine -->
<property name="excludedBeans">
<list>
<value>MyPrototypeScopedBeanName</value>
</list>
</property>
Stackoverflow link
Another link
Courtesy:- #theJC

Spring Java Config using Autowired caused NPE

I am having difficulty understanding why something in Spring Java Config using #Autowired does not work.
First, I am trying to move all my #Autowired annotations in the Java Config classes. This has the effect of making my "POJOs" back into real POJOs. I can then not only test them easily outside of a Spring context, but can also use mock objects easily and readily.
So I first tried this:
#Configuration
public class Module3ConfigClass {
#Autowired
private Module1Bean1 module1Bean1;
#Autowired
private Module2Bean1 module2Bean1;
#Bean
public Module3Bean1 module3Bean1() {
return new Module3Bean1(module1Bean1, module2Bean1);
}
}
However, when the Module3Bean1 constructor is invoked, both passed in Beans are null. If you didn't follow my made up naming convention above, both of those beans would be created by a separate Java Config configuration file. Also note that everything is wired up correctly - I know this because everything works perfectly when the #Autowired tags are on the corresponding private member fields inside of Module3Bean1.
FWIW, I tried adding an #DependsOn annotation to module3Bean1() method, but had the same results. I guess I just would really like to understand this behavior, is it correct (I suspect it is, but why)?
Finally, I found an acceptable workaround shown here:
#Configuration
public class Module3ConfigClass {
#Bean
#Autowired
public Module3Bean1 module3Bean1(Module1Bean1 module1Bean1, Module2Bean1 module2Bean1) {
return new Module3Bean1(module1Bean1, module2Bean1);
}
}
This seems fine to me, but if anyone would care to comment on it, that would be welcome as well.
I think you came across same problem I just had. In my case problem was invalid xml configuration. In my module B I had config like :
<beans>
<context:component-scan base-package="com.moduleB"/>
<import resource="classpath:applicationContext-moduleA.xml"/>
</beans>
In moduleA context I placed "context:annotation-config" annotation.
When I change import/context order to :
<beans>
<import resource="classpath:applicationContext-moduleA.xml"/>
<context:component-scan base-package="com.moduleB"/>
</beans>
Autowiring for configuration class properties started to work.
We had the same issue and came to the conclusion that the error arose because we had a circular dependency where a BeanPostProcessor was involved.
A PropertyPlaceholderConfigurer (a BeanPostProcessor) has been configured to set its propertiesArray property with the help of another bean:
<bean id="globalPropertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
lazy-init="false" depends-on="javaLoggingConfigurer">
<property name="locations">
<list>
<value>classpath:config/host/${env.instance}.properties</value>
<value>WEB-INF/config/host/${env.instance}.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="true" />
<property name="propertiesArray" value="#{springPropertyFinder.findProperties()}" />
</bean>
The used springPropertyFinder bean to set the propertiesArray is not a BeanPostProcessor but a "normal" bean that gathers all Properties instances with:
public Properties[] findProperties() {
Map<String, Properties> propertiesMap = applicationContext.getBeansOfType(Properties.class);
for (String title : propertiesMap.keySet()) {
PropertiesLoggerUtil.logPropertiesContent(logger, "Springcontext Properties ("+title+")", propertiesMap.get(title));
}
return propertiesMap.values().toArray(new Properties[propertiesMap.size()]);
}
The #Configuration class contained a bean of type Properties
So our assumption is that the #Configuration class has been created without being processed by the ConfigurationClassPostProcessor (also a BeanPostProcessor), because the PropertyPlaceholderConfigurer depends on the springPropertyFinder, which depends on the properties bean in the #Configuration class. The order of the BeanPostProcessors is probably not setup right under these circumstances.
This described setup worked in XML, but not with Java config.

Properties Handling With Seam In A Spring-like fashion

One of the Spring features I like the most is how you can handle properties loaded from a file. You only to need to set up a bean like the one below
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/WEB-INF/app.properties" />
</bean>
Now you are able to inject the properties values loaded from the app.properties into your beans by using either xml (see below) or annotations.
<bean class="com.example.PersonDaoImpl">
<property name="maxResults" value="${results.max}"/>
</bean>
results.max is one of the properties.
I'm great fan of this feature because it enables me to create quite flexible applications that I can turn on/off some functionality by only changing one property - without redeploying the app.
Now I'm working with JBoss Seam and I've been struggling to find a way to do something similar using this framework.
Does anyone know how to do it? If not, does anyone have any idea of how I could handle properties in a nice way using Seam (I have seen some ways - but none of them were good enough).
Thanks.
If there's no appropriate way using you software stack (is there really no dependency injection!?). I'd say: Use Google Guice (https://code.google.com/p/google-guice/ , https://code.google.com/p/google-guice/wiki/Motivation?tm=6)!
Bad thing with Guice: You may have to read a lot to understand how it works, and what you can do with it. But after it's running you will simply inject your Properties object where you need it:
class YourClass {
#Inject Properties myProperties;
#Inject
public YourClass() { ... }
public void someMethod() {
use the property
}
}
or if you need the properties inside the constructor, you could also do:
class YourClass {
final Properties myProperties;
#Inject
public YourClass(Properties myProperties) {
this.myProperties = myProperties;
}
public void someMethod() {
use the property
}
}
Using Guice maybe enforces you to refactor your whole app.
But if you already have some DI framework, you should simply use that :)

Mockito - MockSettings with spring

I'm trying to setup mocked object (using Mockito) via spring bean configuration, however I don't know how to setup MockSettings for that object. Especially I would like to set up object serializable.
Programatically it is possible by:
Object serializableMock = mock(Object.class, withSettings().serializable());
<bean id="object" name="object" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="object" />
<constructor-arg value="org.mockito.MockSettings"> ??? </constructor-arg>
</bean>
Can somebody guide me how to do that ? Thanks in advance
BTW : I want to use pure XML configuration.
Only via XML, you can't.
Actually I wouldn't recommend you to have the usual practice of using Mockito mocks in spring for tests. Here's why :
Usually when Unit Testing, you want to test one class in isolation, it's unit testing after all, so Spring DI isn't necessary at all in this case. You just inject the collaborators of your test subject yourself or maybe via the handy #InjectMock annotation.
If however you need to test things with another system like a DAO with a Database, then indeed you probably need Spring wiring to connect to either the real DB or some in memory DB like H2. But in this case you are crafting an Integration Test. And you most probably don't need mocks in this case.
That said, you might have specific needs and the above point could be irrelevant in your specific bounded context. But then again, in my opinion if it's specific I don't think it's overkill to craft yourself a simple MockSettings factory bean (that could even be configurable).
E.g. you could write this once and for all in a technical module of your application :
public class SpringMockSettingsFactoryBean extends AbstractFactoryBean<MockSettings> {
#Override public Class<Multimap> getObjectType() {
return MockSettings.class;
}
#Override protected Multimap<String, String> createInstance() throws Exception {
// ... your code
return mockSettings;
}
}
There's a project springockito on bitbucket that tries to have a mockito focused namespace in spring. I don't think the project can do that, but the framework's author might be interested to implement the feature.
Hope that helps.
yes, you can do it via XML
<bean id="mockSettings" class="org.mockito.Mockito" factory-method="withSettings" init- method="verboseLogging">
</bean>
<bean id="sqsHelper" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="com.elsevier.vtw.aws.helper.SQSHelper"/>
<constructor-arg ref="mockSettings" />
</bean>

Spring Config file consisting of List of Implementations

I Am very new to Spring. I have an Interface (MessageHandler ) which has a get method, this method returns a list of Implementations of another interface (messageChecker).
public interface MessageHandler {
public void process(BufferedReader br);
public void setMessageCheckerList(List mcList);
[B]public List getMessageCheckerList();[/B]
}
In my Spring XML configuration , i have something like this ,along with other beans
<bean id="messageHandler" class="com.XXX.messagereceiver.MessageHandlerImpl">
<property name="messageCheckerList" ref="checkerList"/>
</bean>
<bean id="checkerList" class="java.util.ArrayList">
<constructor-arg>
<list>
<ref bean="HL7Checker"/>
</list>
</constructor-arg>
</bean>
<bean id="HL7Checker" class="com.XXX.messagereceiver.HL7CheckerImpl">
<property name="messageExecutor" ref="kahootzExecutor"/>
</bean>
Here i am passing a checkerlist - which is a list of Implementations ( For now i have only 1) of the Interface (messageChecker)
Checkerlist is containing references to Bean Id's which are actual implementaions.
HL7Checker is an implementation of an Interface messageChecker.
But when i run the main program, When i inject the bean "messageHandler" and call the getMessageCheckerList, It returns a null value. These getter and setter methods are working fine without using spring.
I am not sure what seems to be the problem.
I don't know the answer for you troubles, but I would check:
is the setter setMessageCheckerList(List) in messageHandler bean called? (either using some debugger or some trace output like System.out...). If it's not, there's probably something wrong with your Spring XML configuration setup. The bean definition you posted requires the property to be set and Spring wouldn't create the messageHandler bean without setting the property.
who calls the setMessageCheckerList(List) setter? Or even more precise, what code writes to the field which stores the value of the property? Maybe the field is initialized properly by Spring but gets overwritten to null later on?
are you sure you call the getMessageCheckerList on the very same object Spring has configured for you (that is, the messageHandler bean). The definition you have posted clearly states an instance of MessageHandlerImpl is created by Spring, but it doesn't prevent other instances to be created in other ways. So maybe the instance created by Spring holds the proper value, but you run the get... on a wrong instance?

Categories