Spring #Autowired comes as null - java

I have #Component, A, which AutoWires a class which contains simple configurations for class A. I've created a bin for configuration file. But for some reason it comes as null. Could you please help me to find out the problem?
#Component
public class SearchEngineDriver {
#Autowired(required = true)
private EngineContext context;
public SearchEngineDriver(){
String clusterName = context.getClusterName();
}
}
public class EngineContext {
private String clusterName;
public EngineContext(String clusterName){
this.clusterName = clusterName;
}
public String getClusterName(){
return this.clusterName;
}
}
3rd class.
#Autowired
private SearchEngineDriver searchEngineDriver;
mvc-dispatcher-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="org.electronsoftware" />
<mvc:annotation-driven/>
<mvc:resources mapping="/resources/**" location="/resources/" />
<import resource="classpath*:/application-context.xml"/>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
application-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:property-placeholder location="classpath:application.properties"/>
<bean id="searchEngineContext" class="org.electronsoftware.KGB.search.context.EngineContext" >
<constructor-arg value="${kgb.search.engine.clustername}"/>
</bean>
</beans>

You are accessing the autowired field from the constructor. At the time the constructor runs, Spring has not yet got the chance to initialize the field. Instead use a #PostConstruct method to perform logic which depends on the autowired value.

Related

Spring templateResolver configure

I have problem with correct configure templateResolver. When i try to get default page, its work fine. When i try go to the page with /someAddress i get
template might not exist or might not be accessible by any of the configured Template Resolvers
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<mvc:annotation-driven/>
<context:component-scan base-package="com.javapointers.controllers"/>
<bean id="templateResolver"
class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
</bean>
<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver"/>
</bean>
<mvc:resources mapping="/resources/**" location="/WEB-INF/resources/"/>
HomeController
#Controller
public class HomeController {
#RequestMapping(value="/", method = RequestMethod.GET)
public String viewHome(){
return "test";
}
#RequestMapping(value="/login", method = RequestMethod.GET)
public String login(){
return "login";
}
Does anyone know the correct configure?
I resolved the problem. In my app was another beans configuration in java class.

Spring #Transactional configuring xml

The rollback in my transaction doesn't work (Spring 3.1). I tried to edit my configuration xml file, like here but without result.
Here my xml file:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns="http://www.springframework.org/schema/beans"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:aop= "http://www.springframework.org/schema/aop"
xmlns:tx= "http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
">
<jee:jndi-lookup id="dataSourceUsrAppe1" jndi-name="jdbc/ZhabDS"/>
<bean id="utentiDAO" class="it.dao.UtentiDAO">
<property name="dataSourceUsrAppe1">
<ref bean="dataSourceUsrAppe1"/>
</property>
</bean>
<!-- doesn't work with this:
<tx:annotation-driven transaction-manager="txManager"/>
<property name="dataSourceUsrAppe1">
<ref bean="dataSourceUsrAppe1"/>
</property>
</bean>
</beans>
-->
</beans>
Should I add a transaction manager here?
Here's my service:
#Service
public class UtentiService {
#Autowired
private UtentiDAO utentiDAO;
#Transactional(rollbackFor={Exception.class}, propagation=Propagation.REQUIRED)
public boolean createUser(Zhabuten user) throws Exception
{
long idPrincipale;
idPrincipale = utentiDAO.insert(user, utentiDAO.query1);
idPrincipale = utentiDAO.insert(user, utentiDAO.query2);
if (idPrincipale!=0) throw new java.lang.Exception();
idPrincipale = utentiDAO.insert(user, utentiDAO.query3);
return false;
}
}
The exception is correctly thrown, it's catched from the controller and the database is not rollbacked.
Do I missing any configuration in the xml?
Use the following xml configuration.
<!-- Enable Annotation based Declarative Transaction Management -->
<tx:annotation-driven proxy-target-class="true"
transaction-manager="transactionManager" />
<!-- Creating TransactionManager Bean, since JDBC we are creating of type
DataSourceTransactionManager -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSourceUsrAppe1" />
</bean>

Spring #Value annotation and setter injection difference

When I am setting a value using #Value annotation from a property file, its not working, whereas setting using setter injection works.
my properties file like this.
app.work.dir=file:${user.home}/WORK
class file like below.
#Value("#{configProperties['app.work.dir']}")
private String workdir;
and this is my xml setting.
<util:properties id="configProperties" location="classpath:config.properties" />
when use setter injection like below then it works fine.
<bean id="sampleService" class="aaa.SampleService">
<property name="workdir" value="${app.work.dir}" />
</bean>
I'm not sure why and if possible i want to use #Value annotation.
please refer to junit test case below.
xml configulation:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<context:property-placeholder location="classpath:testconfig.properties" />
<util:properties id="sampleProperties" location="classpath:testconfig.properties" />
<bean id="exampleA" class="aa.sample.SampleA" />
<bean id="sampleB" class="aa.sample.SampleB" >
<property name="workdir" value="${work.dir}" />
<property name="tempdir" value="${work.dir.test}" />
<property name="aaa" value="${aaa}" />
</bean>
</beans>
sample service class:
package aa.sample;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
#Service
public class SampleA {
#Value("#{sampleProperties['work.dir']}")
private String workdir;
#Value("#{sampleProperties['work.dir.test']}")
private String tempdir;
#Value("#{sampleProperties['aaa']}")
private String aaa;
//getter setter deleted
}
properties file:
work.dir=file:${user.home}/WORK
work.dir.test=${work.dir}/TEST
aaa=bbb
and junit test class:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration({ "/testcontext.xml" })
public class ExampleTest {
#Inject
private SampleA sampleA;
#Inject
private SampleB sampleB;
#Test
public void testValueAnnotation() {
assertThat(sampleA.getAaa(), is("bbb"));//ok
String tempdir = sampleA.getTempdir();
String workdir = sampleA.getWorkdir();
assertFalse("[sampleA] temp dir should not have ${work.dir}", tempdir.indexOf("${work.dir}") >= 0);//ng
assertFalse("[sampleA] workdir dir should not have ${user.home}", workdir.indexOf("${user.home}") >= 0);//ng
}
}
The bean generated by
<util:properties id="sampleProperties" location="classpath:spring.properties" />
basically translates to a map. This notation
#Value("#{sampleProperties['work.dir']}")
requests one of its valued mapped with the key work.dir. There's no property resolution that occurs on the value returned. It's taken literally.
This, on the other hand,
<property name="tempdir" value="${work.dir.test}" />
requests a property, called work.dir.test which can be recursively resolved.

no declaration can be found for element 'mvc:annotation-driven'

I have the requirement of returning JSON/XML data from my controller.From what i found,I needed #ResponseBody in my method and for that I need <mvc:annotation-driven> enabled. I have tried all sorts of RnD but am still stuck! :(
Apparently my problem lies in my servlet.xml file (the schema isnt getting validated!)
I am using Spring 3.1.1 & have explicitly put in spring-mvc-3.1.1.jar in my classpath.
Here's my servlet-context file sample-servlet.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc-3.1 http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.sample.controller"/>
<mvc:annotation-driven/>
<!--Use JAXB OXM marshaller to marshall/unmarshall following class-->
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean id="xmlViewer"
class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg>
<bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.sample.model.SampleClass</value>
</list>
</property>
</bean>
</constructor-arg>
</bean>
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</list>
</property>
</bean>
My controller class looks like this :
#Controller
public class XmlController {
#RequestMapping(value="/getXml",method = RequestMethod.POST)
public #ResponseBody AssociateDetail getXml(){
System.out.println("inside xml controller.....");
AssociateDetail assoBean=null;
try{
AssociateService add=new AssociateService();
assoBean=add.selectAssociateBean();
}catch(Exception e){
e.printStackTrace();
}
return assoBean;
}
}
Now the problem is <mvc:annotation-driven /> gives error:
cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'mvc:annotation-driven'.
And I have tried all the workarounds suggested on this site and beyond. Have updated my schema namespaces, using Spring 3.1.1 and #ResponseBody.
As the error suggests there's something wrong with the schema declaration. You do not have the xsd s declared.
Use this instead.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
Add the following schemas to your schemaLocation declaration at the top:
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd

Spring 3 how to run a scheduled task with an interval from property file

I am using Spring 3 to create a scheduled-task.
I have to use XML based wiring to configure it, and would like scheduled task to run with an interval that is set in a properties file.
Spring Context file:
<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-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task">
<context:property-placeholder location="classpath:connector.properties"/>
<task:scheduler id="connectorScheduler" pool-size="10"/>
<task:scheduled-tasks scheduler="connectorScheduler">
<task:scheduled ref="connector" method="checkConnection" fixed-rate="${connector.connectionAttemptDelayMillis}"/>
</task:scheduled-tasks>
<bean id="connector" class="com.test.Connector" scope="singleton">
<constructor-arg index="0" value="${connector.user}"/>
<constructor-arg index="1" value="${connector.password}"/>
<constructor-arg index="2" value="${connector.connectionAttemptDelayMillis}"/>
</bean>
</beans>
The problem is that the ${connector.connectionAttemptDelayMillis} is not allowed in the fixed-rate value. This will work fine if i was to put a number in its place, but i need this value to come from a loaded property file.
Any help is much appreciated.
You could do it like that (downside, you can only do your task every 1s or more):
Connector class
package com.test.Connector;
#Component
public class Connector {
#Value("${connector.user}")
private String user;
#Value("${connector.password}")
private String password;
#Value("${connector.connectionAttemptDelayMillis:0}")
private long attemptDelayMillis;
#Scheduled(cron = "${connector.connectionAttemptCron}")
public checkConnection() {
// do the check
}
}
Xml context
<?xml version="1.0" encoding="UTF-8"?>
<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:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
<context:annotation-config />
<context:component-scan base-package="com.test" />
<context:property-placeholder location="classpath:connector.properties" />
<task:scheduler id="connectorScheduler" pool-size="10"/>
<task:annotation-driven scheduler="connectorScheduler" />
</beans>
Properties
connector.user = someuser
connector.password = somepassword
connector.connectionAttemptDelayMillis = 5000
connector.connectionAttemptCron = */5 * * * * *
This works because cron need a string.
References
http://static.springsource.org/spring/docs/3.0.x/reference/scheduling.html
http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/scheduling/annotation/Scheduled.html#cron()

Categories