I autowired some beans from my testConfig.xml, and it works fine but when I want to autowire a properties file it gives null, the properties file is near of my xml in selenium folder. My testConfig.xml looks like this :
<?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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd" >
<bean id="base" class="java.net.URI">
<constructor-arg value="http://localhost:8080/MySite" />
</bean>
<bean id="siteBase" class="java.net.URI">
<constructor-arg value="http://localhost:8080/MySite/site" />
</bean>
<bean id="adminBase" class="java.net.URI">
<constructor-arg value="http://localhost:8080/MySite/admin" />
</bean>
<bean id="firefoxDriver" class="org.openqa.selenium.firefox.FirefoxDriver" destroy-method="quit"/>
<context:annotation-config/>
<util:properties id="seleniumSelectors" location="classpath:selenium/selenium-selectors.properties"/>
</beans>
and here I want to autowire it:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "/testConfig.xml" })
public abstract class AbstractUITest extends TestCase{
#Autowired
protected URI base;
#Autowired
protected URI siteBase;
#Autowired
protected URI adminBase;
#Autowired
protected WebDriver firefoxDriver;
#Autowired
#Qualifier("seleniumSelectors")
protected Properties selectors;
protected By getBySelectorKey(String key){
if(key.endsWith(".xpath")){
return By.xpath(selenium.getProperty(key));
}
}
Just the selectors object is null and I don`t know why, any suggest?
UPDATE 2:
I made a mistake everithing is null when the selector is null.I cheked Initialization in my test runs before autowired, somehow this
public class AdminCandidatesPageUITest extends AbstractAdminUITest {
private By COMPONENT_QUERY_TEXTBOX_EMAIL = getBySelectorKey("admin.candidates.edit.textbox.email.xpath");
private By COMPONENT_QUERY_TEXTBOX_EMAIL_ERROR = getBySelectorKey("admin.candidates.edit.textbox.email.errors.xpath");
should run after seleniumSelector is autowired. Any suggest?
Try to move tag <context:annotation-config/> one line down. I am not sure but it seems that wiring triggered by this tag happens before creating of seleniumSelectors, so it is still null at the moment.
BTW if you mark your properties as #Required the context will fail to start and throw exception because one of the properties is not wired. This is probably preferable than failing later at runtime.
Related
I faced a problem with Spring Framework: #Autowired are null, but Spring doesn't throw any exceptions, and I can't understand, why are these fields null.
I have a class:
package com.processing.gates;
public class Main {
private final ApplicationContext context = Context.getContext();
#Autowired private PaymentGateFactory paymentGateFactory;
#Autowired private CalculatorChooser calculatorChooser;
//...
}
And for example I have the following class:
package com.processing.gates.comission;
#Component
public class CalculatorChooser {
//...
}
Here is my Spring configuration xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc.xsd">
<context:annotation-config />
<context:component-scan base-package="com.processing.gates"/>
<bean id="logPath" class="java.lang.String"> <!-- путь к папке с логами -->
<constructor-arg value="/home/yoba/NetBeansProjects/processing/gates/log/"/>
</bean>
<!-- ... -->
</beans>
When I try to write in xml:
<bean id="calculator" class="com.processing.gates.comission.CalculatorChooser"/>
and get it from code:
CalculatorChooser cc = (CalculatorChooser)Context.getContext().getBean("calculator");
it works fine. But #Autowired doesn't work. How can I fix this? Thanks!
Let Spring manage the bean by either declaring a Main bean in the application context file or by using the #Component annotation as you've already done for CalculatorChooser
<bean id="mainBean" class="com.processing.gates.Main"/>
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.
I have a Spring controller that I think is getting instantiated more than once based on the object ids I see when I debug through the code.
Controller:
#Controller
#RequestMapping("/services/user")
public class UserController{
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
public UserService getUserService() {
return userService;
}
#RequestMapping(method = RequestMethod.POST, value = "/createUser")
public #ResponseBody String createUser(#RequestBody User user) throws UserNotCreatedException {
try {
userService.createUser(user);
return user.getEmail();
} catch (Exception e) {
e.printStackTrace();
throw new UserNotCreatedException("User not created");
}
}
Spring configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
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">
<!-- Scans the classpath of this application for #Components to deploy as
beans -->
<context:component-scan base-package="com.xyz.controller" />
<context:annotation-config />
<bean id="userController" class="com.xyz.UserController">
<property name="userService" ref="userService" />
</bean>
<bean id="userService" class="com.xyz.UserServiceImpl">
<property name="userDao" ref="userDaoMysql" />
</bean>
<bean id="userDaoMysql" class="com.xyz.UserDaoImpl" >
<property name="dataSource" ref="dataSource"></property>
<property name="template" ref="jdbcTemplate"></property>
</bean>
</beans>
I noticed the problem when I realized that userService is null when I make a request that goes through UserController. However; when I put break points, I see that userService does get set in another instance of UserController.
The other comments in this thread did not take into account the package of the UserController class. The supplied Spring config initializes component-scanning on com.xyz.controller as the base package. The UserController class looks like it is outside of this in com.xyz and thus would not be picked up by component-scanning (unless that is a typo #user269091 - which could be your problem!).
I should note that I don't understand why your controller would not be in your controller package. It would be cleanest to move the controller there, add #Autowired above the line private UserService userService; and remove the manual UserController definition in the Spring config, so that the component-scanning just picks up your bean automatically and wires up the UserService.
With that being said, I really don't see why there would be a problem with what you have shown. Do you have new UserController() anywhere in your code? Is there any other Spring configuration?
To build on #adashr's answer
If you remove the manual configuration, then you're now initializing things based on annotations. The #Controller annotation will correctly create the Controller, but nothing wires in the UserService now
You need a #Autowired for the UserService to instantiate it since your spring config is now annotation driven
You are mixing annotations and bean xml configuration.
If you are using #Controller annotaion, you do not need to define the controller bean in XML.
The instruction
<context:component-scan base-package="com.xyz.controller" />
takes care of registering the controller bean for you (your controller bean is inside that package).
I suggest you to use mvc namespace while configuring Spring MVC to keep configuration minimal and more readable.
Hi,
I am using spring 3.0 with Quartz in a scheduler class. I have created the application context by
private static final ClassPathXmlApplicationContext applicationContext;
static {
applicationContext = new
ClassPathXmlApplicationContext("config/applicationContext.xml");
}
The problem is that none of the #Autowired beans actually get auto-wired, so I have to manually set dependencies like this:
<bean class="com.spr.service.RegistrationServiceImpl" id="registrationService">
<property name="userService" ref="userService" />
</bean>
Example of where I'm using #Autowired:
public class RegistrationService {
#AutoWired private UserService userService;
// setter for userService;
}
public class UserService{
// methods
}
I also made sure to enable the annotation configuration in my Spring config:
<context:annotation-config/>
<bean id="registrationSevice" class="RegistrationService"/>
<bean id="userService" class="UserService"/>
Why is #Autowired not working for me?
You haven't provided the UserService class source code so I can't be sure about your problem. Looks like the UserService class is missing a 'stereotype' annotation like #Component or #Service. You also have to configure the Spring classpath scanning using the following configuration:
<?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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- Add your classes base package here -->
<context:component-scan base-package="your.package"/>
</beans>
Your beans must include one of the Spring stereotype annotations like:
package your.package;
#Service
public class UserService{
}
Atlast i got it resolved by adding the
<context:component-scan base-package="your.package"/>
in my applicationContext.xml. Thank u all for your support.
I'm using Spring's #Configuration, and I noticed that a #Bean does not get registered using JMX.
The bean is wired as
#Bean
protected CountingHttpInterceptor countingHttpInterceptor() {
return new CountingHttpInterceptor();
}
and the class definition is
#ManagedResource
public class CountingHttpInterceptor implements HttpRequestInterceptor, HttpResponseInterceptor { /* code here*/ }
This #Configuration file is processed after the main , XML-based, application context is built, and does not have the chance to take part in the discovery process which is activated using XML bean definitions ( org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource and frieds ).
How can I JMX-enable the beans from the #Configuration file?
Update: the xml configuration
<bean id="jmxExporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="assembler" ref="assembler"/>
<property name="namingStrategy" ref="namingStrategy"/>
<property name="autodetect" value="true"/>
</bean>
<bean id="jmxAttributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>
<bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
<property name="attributeSource" ref="jmxAttributeSource"/>
</bean>
<bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
<property name="attributeSource" ref="jmxAttributeSource"/>
</bean>
Despite the temptations of the #Configuration- based approach, some things remain better done with XML config. In particular, the namespace-based config such as <context:mbean-export>. These essentially represent "macros" consisting of complex arrangements of interacting objects.
Now, you could replicate this logic in your #Configuration class, but it's really more trouble than it's worth. Instead, I suggest putting such system-level stuff into XML, and importing it from your #Configuration class:
#ImportResource("/path/to/beans.xml")
public class MyConfig {
#Bean
protected CountingHttpInterceptor countingHttpInterceptor() {
return new CountingHttpInterceptor();
}
}
and then in /path/to/beans.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.xsd
">
<context:mbean-export/>
</beans>
Everything you have is correct. In your #Configuration class you need to add one more annotation to export your MBeans, #EnableMBeanExport.
Your configuration class would look something like this...
#Configuration
#EnableMBeanExport
public class SpringConfiguration {
#Bean
protected CountingHttpInterceptor countingHttpInterceptor() {
return new CountingHttpInterceptor();
}
}