NullPointerException: #Autowired does not set field - java

I am learning SPRING and this is not web application code; I am getting NLP while using #Autowired annotation in field level.
Q1) Please help what is wrong?
Q2) If i have #Scope annotation at the class level; do i still need at XML bean level?
#Controller
#Scope(value = BeanDefinition.SCOPE_SINGLETON)
public class StreamingController implements psConsolePortListener.Implementation{
#Autowired
#Qualifier("scMgr")
private StreamingControllerManager streamingMgr = null;
public static void main(String[] args) {
logger.info("StreamingController testing");
XmlBeanFactory factory = new XmlBeanFactory (new ClassPathResource(BEAN_FILE));
StreamingController obj = (StreamingController) factory.getBean("streamingController");
obj.streamingMgr.test();
}
}
#Service
#Scope(value = BeanDefinition.SCOPE_SINGLETON)
#Qualifier("scMgr")
public class StreamingControllerManager {
/** Logger */
private static final Logger logger = LoggerFactory.getLogger(StreamingControllerManager.class);
private StreamingControllerManager(){
logger.info("StreamingControllerManager is called!!");
}
public void test(){
logger.info("StreamingControllerManager test!!");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<context:annotation-config />
<context:component-scan base-package="com.xxx.streamingController"/>
<bean id="scMgr" class="com.xxx.streamingController.StreamingControllerManager">
</bean>
<bean id="streamingController" class="com.xxx.streamingController.StreamingController">
</bean>
</beans>
Output:
Exception in thread "main" java.lang.NullPointerException
at com.pactolus.streamingController.StreamingController.main(

Use an ApplicationContext instead of a BeanFactory.
public static void main(String[] args) {
logger.info("StreamingController testing");
ApplicationContext ctx = new ClassPathXmlApplicationContext(BEAN_FILE);
StreamingController obj = (StreamingController) ctx.getBean("streamingController");
obj.streamingMgr.test();
}
Also remove <context:annotation-config /> that is already impllied by <context:component-scan /> and remove the bean declarations. You are using component-scanning so no need to declare the beans.
Basically leaving you with.
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<context:component-scan base-package="com.xxx"/>
</beans>

Related

'javax.servlet.ServletContext' that could not be found

I have a Springboot application as follows:
#SpringBootApplication
#ImportResource("classpath:/config/applicationContext.xml")
public class TaxBatchMain {
#Autowired
TaxIdService taxIdService;
private static final Logger LOGGER = LogManager.getLogger(TaxBatchMain.class);
public static void main(String[] args) {
new SpringApplicationBuilder(TaxBatchMain.class).web(false).run(args);
TaxBatchMain taxBatchMain = new TaxBatchMain();
}
public TaxBatchMain() {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
#PostConstruct
public void checkForTransactions() {
try {
////
String tab = "someother content";
String footer = taxIdService.formatFooter();
////
////
}catch(){
//////////
}
}
}
TaxIdServiceImpl class is as follows:
#Service
#Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class TaxIdServiceImpl implements TaxIdService {
#Autowired
private ServletContext servletContext;
private String formatFooter(String footer) {
String[] searchList = {"<ENVIRONMENT_NAME>", "<MS_ENV_NAME>"};
String[] replacementList = {(String) servletContext.getAttribute(ServletContextKey.EMAIL_HOST_NAME.name()),
(String) servletContext.getAttribute(ServletContextKey.MS_EMAIL_HOST_NAME.name())};
return StringUtils.replaceEach(footer, searchList, replacementList);
}
}
Application Context looks like:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"....................///
<context:annotation-config />
<context:property-placeholder location="classpath:/config.properties" />
<util:properties id="configProperties" location="classpath:/config.properties" />
<!-- <context:property-placeholder location="classpath:data/application.properties"/> -->
<context:component-scan base-package="com.tax.main" />
<context:component-scan base-package="com.tax.service" />
<context:component-scan base-package="com.tax.model" />
<context:component-scan base-package="com.tax.mapper" />
<context:component-scan base-package="com.tax.util" />
/////
When I run the main class i get foll. error
APPLICATION FAILED TO START
Description:
Field servletContext in com.tax.service.TaxIdServiceImpl required a bean of type 'javax.servlet.ServletContext' that could not be found.
Action:
Consider defining a bean of type 'javax.servlet.ServletContext' in your configuration.
Try enabling webEnvironment. It appears your SpringApplicationBuilder is not enabled with web environment.
new SpringApplicationBuilder(TaxBatchMain.class).web(true).run(args);
Since you are using spring-boot you can consider using Annotation based approach rather xml based.

Spring Autowiring when using Configuration Class

I have a xml bean file
<?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/>
<bean id="helloWorld" class="com.a.b.HelloWorld">
<property name="attr1" value="Attr1 from XML"></property>
</bean>
<bean id="helloWorld2" class="com.a.b.HelloWorld2">
<property name="attr2" value="Attr2 from XML"></property>
</bean>
</beans>
And I have use constructor autowiring like this
public class HelloWorld2{
private String attr2;
public void setAttr2(String message){
this.attr2 = message;
}
public void getAttr2(){
System.out.println("getAttr2 == " + attr2);
}
}
public class HelloWorld{
private String attr1;
private HelloWorld2 helloWorld2;
public HelloWorld(){
}
#Autowired
public HelloWorld(HelloWorld2 helloWorld2){
System.out.println("hhh");
this.helloWorld2 = helloWorld2;
}
public void setAttr1(String message){
this.attr1 = message;
}
public void getAttr1(){
System.out.println("getAttr1 == " + attr1);
}
public void getH(){
helloWorld2.getAttr2();
}
}
And autowiring is working fine.
Now I want to move my beans to Configuation class.
But then how to move the code so as autowiring works?
I have tried like this, but its not working
#Configuration
public class Config {
#Bean
public HelloWorld helloWorld(){
HelloWorld a = new HelloWorld();
a.setAttr1("Demo Attr1");
return a;
}
#Bean
public HelloWorld2 helloWorld2(){
HelloWorld2 a = new HelloWorld2();
a.setAttr2("Demo Attr2");
return a;
}
}
I think what you want to achieve is the injection of a HelloWorld2 instance into the method that creates the HelloWorld #Bean?
This should do it:
#Configuration
public class Config {
#Bean
public HelloWorld helloWorld(HelloWorld2 helloWorld2){
HelloWorld a = new HelloWorld(helloWorld2);
a.setAttr1("Demo Attr1");
return a;
}
#Bean
public HelloWorld2 helloWorld2(){
HelloWorld2 a = new HelloWorld2();
a.setAttr2("Demo Attr2");
return a;
}
}
This might be a duplication of these questions:
Understanding Spring Autowired usage
Converting Spring XML file to Spring configuration class

In Spring, annotation and xml must be used together?

A class
public class A {
private String name;
public A() {
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
BeanFactory class
public class BeanFactory implements InitializingBean, DisposableBean{
private A a;
public BeanFactory(){
}
public BeanFactory(A a){
this.a = a;
}
public void printAName(){
System.out.println("Class BeanFactory: beanFactory.printAName -> a.getName() = " + a.getName());
}
}
Main
public class Main {
public static void main(String[] args) {
AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"ApplicationContext.xml");
BeanFactory beanFactory = applicationContext.getBean("beanFactory",
BeanFactory.class);
beanFactory.printAName();
}
}
ApplicationContext
<?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 />
<bean id="beanFactory" class="testSpring.BeanFactory">
<constructor-arg ref="a1"/>
</bean>
<bean id="a1" class="testSpring.A">
<property name="name" value="I am A!"></property>
</bean>
</beans>
Result of run: Class BeanFactory: beanFactory.printAName -> a.getName() = I am A!
Like you can see, here I don't use no annotation. But the code works thanks to xml file.
So xml doesn't need annotation..? Can I use one or the other?
If I would use, in this application, the annotation (#Autowired for example) instead of bean xml, it's possible? Can you show me how?
Or the annotation must require xml reference?
So.. annotation and xml must be used together? Thanks
You should use annotation configuration, this is the idea
#Component
class Bean1 {
public Bean1() {
System.out.println(getClass());
}
}
#Configuration
#ComponentScan("test")
public class Config {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
}
}
For details see Spring docs

AOP using AspectJ not working in spring?

My Aspect class will be ,
#Configuration
#EnableAspectJAutoProxy
#Component
#Aspect
public class AspectClass {
#Before("execution(* com.pointel.aop.test1.AopTest.beforeAspect())")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before running the beforeAspect() in the AopTest.java class!");
System.out.println("Hijacked Method name : " + joinPoint.getSignature().getName());
System.out.println("************************");
}
}
My other java Class
public class AopTest {
public void beforeAspect() {
System.out.println("This is beforeAspect() !");
}
}
My Main Class is
public class MainMethod {
public static void main(String[] args) {
ApplicationContext context = new FileSystemXmlApplicationContext("ApplicationContext/applicationContext.xml");
AopTest test = (AopTest)context.getBean("bean1");
test.beforeAspect();
}
}
My applicationContext.xml is ,
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<bean id="bean1" class="com.pointel.aop.test1.AopTest" />
</beans>
In this the #Before("execution(* com.pointel.aop.test1.AopTest.beforeAspect())") in the AspectClass will not be executed before the beforeAspect() in the AopTest , when running Main method.
Good answers are definitely appreciated.
First of all if you're going to use an annotation based configuration, use AnnotationConfigApplicationContext instead of FileSystemXmlApplicationContext. And get rid of the applicationContext.xml file and simply add a #Bean method in your configuration class. Something like this:
#Configuration
#EnableAspectJAutoProxy
#ComponentScan(basePackages = "your.aspect.package")
public class AspectConfig {
#Bean
public AopTest aopTest() {
return new AopTest();
}
}
In your main
public class MainMethod {
public static void main(String[] args) {
AnnotationConfigApplicationContextcontext = new AnnotationConfigApplicationContext(AspectConfig.class);
// don't forget to refresh
context.refresh();
AopTest test = (AopTest)context.getBean("aopTest");
test.beforeAspect();
}
}
In AspectClass you should have #Component, #Aspect, and your method should have the advice or pointcut annotation like #Before. It needs to be a #Component, so that Spring knows to scan it.
Here some code need to add in xml to use annotations-
1.for #component annotation.
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
2.after that use component scan to get all annotated bean class which use #component annotation,and use aop autoproxy-
<context:annotation-config/>
<context:component-scan base-package="mypackage"></context:component-scan>
<aop:aspectj-autoproxy>
</aop:aspectj-autoproxy>
for examples visit-www.technicaltoday.com/p/spring.html
You are missing the point cut definition in your aspect class.
For example;
#Pointcut("execution(* *.advice(..))")
public void logBefore(){}
#Before("logBefore()")
public void beforeAdvicing(){
System.out.println("Listen Up!!!!");
}
You first have to defin the point to weave your aspect to. You do this by using Point cuts.It is the point cut name you give within your #Before annotation. Have a look at my blog post for more information # http://dinukaroshan.blogspot.com/2010/06/aop-with-spring.html
I don't see your AspectClass in the beans configuration. You should also declare it as a Bean.

Define Spring #PropertySource in xml and use it in Environment

In spring JavaConfig, I can define property source and inject into Environment
#PropertySource("classpath:application.properties")
#Inject private Environment environment;
How do I do that if in xml?
I am using context:property-placeholder, and on the JavaConfig class #ImportResource to import the xml. But I cannot retrieve property defined in the properties file using environment.getProperty("xx")
<context:property-placeholder location="classpath:application.properties" />
AFAIK, there is no way of doing this by pure XML. Anyways, here is a little code I did this morning:
First, the test:
public class EnvironmentTests {
#Test
public void addPropertiesToEnvironmentTest() {
ApplicationContext context = new ClassPathXmlApplicationContext(
"testContext.xml");
Environment environment = context.getEnvironment();
String world = environment.getProperty("hello");
assertNotNull(world);
assertEquals("world", world);
System.out.println("Hello " + world);
}
}
Then the class:
public class PropertySourcesAdderBean implements InitializingBean,
ApplicationContextAware {
private Properties properties;
private ApplicationContext applicationContext;
public PropertySourcesAdderBean() {
}
public void afterPropertiesSet() throws Exception {
PropertiesPropertySource propertySource = new PropertiesPropertySource(
"helloWorldProps", this.properties);
ConfigurableEnvironment environment = (ConfigurableEnvironment) this.applicationContext
.getEnvironment();
environment.getPropertySources().addFirst(propertySource);
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}
}
And the testContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<util:properties id="props" location="classpath:props.properties" />
<bean id="propertySources" class="org.mael.stackoverflow.testing.PropertySourcesAdderBean">
<property name="properties" ref="props" />
</bean>
</beans>
And the props.properties file:
hello=world
It is pretty simple, just use a ApplicationContextAware bean and get the ConfigurableEnvironment from the (Web)ApplicationContext. Then just add a PropertiesPropertySource to the MutablePropertySources
If what you need is just access the property "xx" of the file "application.properties", you can accomplish that without Java code by declaring the following bean in your xml file:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="application.properties"/>
</bean>
Then if you want to inject the property in a bean just reference it as a variable:
<bean id="myBean" class="foo.bar.MyClass">
<property name="myProperty" value="${xx}"/>
</bean>

Categories

Resources