I noticed that in a JUnit test with Spring context property uuid always exists and has a specific value. What is the value and why it exists at all?
There are no properties files in my project, and the PropertyPlaceHolderConfigurer defined in the only spring context read by the test is empty, it doesn't load any properties.
My test class:
#ContextConfiguration(locations = {
"classpath:main-context.xml"
})
#RunWith(SpringJUnit4ClassRunner.class)
public class MyTest {
#Value("${uuid}") String uuidProp;
#Test
public void test() {
System.out.println("uuid = " + uuidProp);
System.out.println("uuid sys property = " + System.getProperty("uuid"));
}
}
main-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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
</bean>
</beans>
This always prints out the same values.
Related
I'm try to define a custome annotation include #Configuration and #ImportResource
but #ImportResource doesn't work
Any suggestions?
#Documented
#Configuration
#ImportResource
#Target({ElementType.TYPE})
#Order(Ordered.HIGHEST_PRECEDENCE)
#Retention(RetentionPolicy.RUNTIME)
public #interface EnableXXConfiguration {
#AliasFor(annotation = ImportResource.class , attribute = "value")
String[] value() default {};
}
#ImportResource contains two attributes value and locations. The value attribute is ultimately alias for locations attribute so using either of the aliases works fine. Keeping your Custom annotation(EnableXXConfiguration) declaration (the one using value attribute) as it, use below code snippet.
#EnableXXConfiguration(value = { "context1.xml", "com/example/stackoverflow/context2.xml"})
public class DemoApp {
#Autowired
private BeanA beanA;
#Autowired
private BeanB beanB;
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DemoApp.class);
DemoApp demoAppObj = (DemoApp) context.getBean("demoApp");
System.out.println("BeanA member: " + demoAppObj.getBeanA());
System.out.println("BeanB member: " + demoAppObj.getBeanB());
}
public BeanA getBeanA() {
return beanA;
}
public BeanB getBeanB() {
return beanB;
}
}
Assume we are using two xmlss placed at two different locations. context1.xml is placed in resource folder(src/main/resource) and context2.xml is placed at any other location (here at: src/main/java/com/example/stackoverflow)
context1.xml
<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.xsd">
<bean id="beanA" class="com.example.stackoverflow.BeanA" />
</beans>
context2.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="beanB" class="com.example.stackoverflow.BeanB" />
</beans>
Trying to autowire Spring bean with property, but still getting NPE. Snippets:
INFO: Loading XML bean definitions from class path resource [autoWireByName.xml]
Exception in thread "main" today do push-ups for 30 mins
java.lang.NullPointerException
at com.springAutoWireByName.KabadiCoach.getFortune(KabadiCoach.java:23)
at com.springAutoWireByName.AutoWireByName.main(AutoWireByName.java:13)
KabadiCoach.java
package com.springAutoWireByName;
public class KabadiCoach {
private SadFortune sadFortune;
/*public KabadiCoach(){
System.out.println("inside default Constructor");
}*/
public String getDailyWorkout()
{
return "today do push-ups for 30 mins";
}
public void setSadFortune(SadFortune fortune) {
sadFortune = fortune;
}
public String getFortune() {
return sadFortune.getSadFortune();
}
}
SadFortune.java
package com.springAutoWireByName;
public class SadFortune {
public String getSadFortune()
{
System.out.println();
return "your day wont be good enough Sorry!!!";
}
}
<?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">
<!-- bean definitions here -->
<bean name="Fortune" class="com.springAutoWireByName.SadFortune">
</bean>
<bean id="myCoach" class="com.springAutoWireByName.KabadiCoach" autowire="byName" />
<!-- this is just a prototype to define actual just make use of this file-->
</beans>
main
package com.springAutoWireByName;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AutoWireByName {
public static void main(String[] args) {
ClassPathXmlApplicationContext context =new ClassPathXmlApplicationContext("autoWireByName.xml");
KabadiCoach co = context.getBean("myCoach",KabadiCoach.class);
System.out.println(co.getDailyWorkout());
System.out.println(co.getFortune());
}
}
after running the above code I am getting the error message as listed and when I change the method to static
public static String getSadFortune()
{
System.out.println();
return "your day wont be good enough Sorry!!!";
}
In class 2 I got the desired output. Why?
Basically the SadFortune member is still null, which is why it works if the getSadFortune() method will be made static.
Until now you only tell Spring to instantiate a Fortune bean and a KabadiCoach, but you have to tell Spring that some members in the KabadiCoach need to be autowired too.
Try this in your Spring configuration file:
<bean id="fortune" class="com.springAutoWireByName.SadFortune"></bean>
<bean id="myCoach" class="com.springAutoWireByName.KabadiCoach" autowire="byName">
<property name="fortune" ref="fortune" />
</bean>
EDIT: Sorry, overread the autowire="byName" attribute. In this case you probably just have write the name in lower case.
<bean id="fortune" class="com.springAutoWireByName.SadFortune"/>
<bean id="myCoach" class="com.springAutoWireByName.KabadiCoach" autowire="byName"/>
My application uses struts and spring frameworks. I have a class FormA which has an autowired property in it. When I try to instantiate it while writing unit tests I get a Null Pointer Exception. Here is my code.
My ClassA:
public class FormA{
private String propertyOne;
#Autowired
private ServiceClass service;
public FormA(){
}
}
My unit test method:
#Test
public void testFormA(){
FormA classObj = new FormA();
}
#Autowired only works when object life cycle is managed by Spring.
You'll need to run your tests with #RunWith(SpringJUnit4ClassRunner.class), and instead of instantiating FormA manually, inject it in the test class as well, using #Autowired.
When you create an object by new, autowire\inject don't work...
as workaround you can try this:
create your template bean of NotesPanel
<bean id="notesPanel" class="..." scope="prototype">
<!-- collaborators and configuration for this bean go here -->
</bean>
and create an istance in this way
applicationContext.getBean("notesPanel");
PROTOTYPE : This scopes a single bean definition to have any number of object instances.
anyway a unit test should be
Test class
#RunWith( SpringJUnit4ClassRunner.class )
#ContextConfiguration(locations = { "classpath:META-INF/your-spring-context.xml" })
public class UserServiceTest extends AbstractJUnit4SpringContextTests {
#Autowired
private UserService userService;
#Test
public void testName() throws Exception {
List<UserEntity> userEntities = userService.getAllUsers();
Assert.assertNotNull(userEntities);
}
}
your-spring-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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="userService" class="java.package.UserServiceImpl"/>
</beans>
I'm trying to replicate something that works with XML config using annotated configuration classes. The problem I'm hitting is that property sources defined in the child context are not accessible.
The xml that works looks like
Parent 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="proxyChannelQueue" class="java.util.concurrent.ArrayBlockingQueue">
<constructor-arg value="10"/>
</bean>
</beans>
Child 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:p="http://www.springframework.org/schema/p"
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:property-placeholder location="proxy-host.properties"/>
<bean class="org.eclipse.jetty.server.Server"
p:handler-ref="proxyHostHandler"
init-method="start">
<constructor-arg value="${proxyHostPort}"/>
</bean>
<bean id="proxyHostHandler" class="com.sjl.web.ProxyHostHandler"
p:proxyChannelQueue-ref="proxyChannelQueue"/>
</beans>
Start up code :
ClassPathXmlApplicationContext parentContext = new ClassPathXmlApplicationContext("test/parent-context.xml");
ClassPathXmlApplicationContext childContext = new ClassPathXmlApplicationContext(new String[] {"test/child-context.xml"}, parentContext);
My attempt at doing this using configuration classes looks like.
Parent Context :
#Configuration
public class ParentConfiguration {
#Bean(name = "proxyChannelQueue")
public BlockingQueue<ProxyChannel> getProxyChannelQueue() {
return new ArrayBlockingQueue<ProxyChannel>(10);
}
}
Child Context :
#Configuration
#PropertySource("classpath:proxy-host.properties")
public class ChildContext {
private static final Logger LOGGER = LoggerFactory.getLogger(ChildContext.class);
#Autowired
private Environment environment;
#Resource(name = "proxyChannelQueue")
private BlockingQueue<ProxyChannel> proxyChannelQueue;
public static void main(String[] args) {
new HierarchicalAnnotationConfigApplicationContext(ChildContext.class);
}
#Bean
public Server getJettyServer() throws Exception {
int proxyHostPort = environment.getProperty("proxyHostPort", Integer.class);
Server server = new Server(proxyHostPort);
server.setHandler(getHandler());
server.start();
return server;
}
#Bean
public Handler getHandler() {
ProxyHostHandler proxyHostHandler = new ProxyHostHandler();
proxyHostHandler.setProxyChannelQueue(proxyChannelQueue);
return proxyHostHandler;
}
}
Start up code :
AnnotationConfigApplicationContext parentContext = new AnnotationConfigApplicationContext(ParentConfiguration.class);
AnnotationConfigApplicationContext childContext = new AnnotationConfigApplicationContext();
childContext.setParent(parentContext);
childContext.register(ChildContext.class);
childContext.refresh();
I'm getting a null pointer while trying to retrieve the proxyHostPort within the ChildContext getJettyServer method. Inspecting the environment variable shows that it contains only 2 property sources (systemProperties and systemEnvironment) and not the 3 I expect.
The same configuration works if I run them as a single combined context. E.g. :
AnnotationConfigApplicationContext parentContext = new AnnotationConfigApplicationContext(ParentConfiguration.class, ChildContext.class);
However I want the isolation that using parent contexts provide.
Cheers,
Peter
I'm writing a java application with Spring 3.It's working well with xml,but not working at all in annotation.
here's my snippet:
#Service("oracleDB")
public class OracleDatabase implements IDatabase
{
#Value("oracle.jdbc.driver.OracleDriver")
private String driverName;
#Value("jdbc:oracle:thin:#")
private String url;
public String getDriverName()
{
return driverName;
}
}
My ApplicationContext.xml is 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"
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">
<context:annotation-config />
<context:component-scan
base-package="com.pdiwt.database"></context:component-scan>
</beans>
MyInvoker is like that:
public class MyInvoker{
public static void main(String args[]){
XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
OracleDatabase oracelDB = beanFactory.getBean("oracleDB");
System.out.println(oracleDB.getDriverName());
}
}
guess what? The result is null. Is there anything wrong?
The problem here is using xmlbeanfactory, which is a common mistake. Try this instead, it will work perfectly:
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
OracleDatabase oracleDB = (OracleDatabase)context.getBean("oracleDB");
...
I think the beanfactory is simply not powerful enough to handle the #Value annotations. More information can be found here.
If you're already using Spring, why would you get a connection this way instead of using Spring's DataSources? Seems odd at best; wrong-headed at worst.
I'd be giving that Repository a JdbcTemplate.