0

I have spring boot project, that is working very fine. But when i add the spring AOP it causes nullpointer when i used the @Autowired variable.

Here is my code for the AOP .

    @Autowired
    private Service service;
    
    private final org.apache.commons.logging.Log log = LogFactory.getLog(this.getClass());
    
    @Around("execution(* com.kpi.ninja..*.*(..))")
    public Object logTimeMethod(ProceedingJoinPoint joinPoint) throws Throwable {
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            System.out.println("Entering in Method :  " + joinPoint.getSignature().getName());
            System.out.println("Class Name :  " + joinPoint.getSignature().getDeclaringTypeName());
            System.out.println("Target class : " + joinPoint.getTarget().getClass().getName());
            Object retVal = joinPoint.proceed();

            stopWatch.stop();
            
            
            StringBuffer logMessage = new StringBuffer();
            logMessage.append(joinPoint.getTarget().getClass().getName());
            logMessage.append(".");
            logMessage.append(joinPoint.getSignature().getName());
            logMessage.append("(");
            // append args
            Object[] args = joinPoint.getArgs();
            for (int i = 0; i < args.length; i++) {
                logMessage.append(args[i]).append(",");
            }
            if (args.length > 0) {
                logMessage.deleteCharAt(logMessage.length() - 1);
            }

            logMessage.append(")");
            logMessage.append(" execution time: ");
            logMessage.append(stopWatch.getTotalTimeMillis());
            logMessage.append(" ms");
            log.info(logMessage.toString());
            
            return retVal;
    }

Here is the image that shows the null pointer error where i used the autowired variable

Birju Vachhani
  • 6,072
  • 4
  • 21
  • 43
Abhishek
  • 21
  • 8
  • its your LoginController#Home method line 284, can you add home method marking line 284. – HRgiger May 11 '18 at 12:50
  • List rootCompanyModulesUserList = (List) this.service .commenQuery("", ""); – Abhishek May 11 '18 at 12:52
  • Here **service** is a autowired variable – Abhishek May 11 '18 at 12:55
  • If you check the first line of stacktrace, you will notice that com.kpi.ninja.controller.LoginController.home throws exception on line 284, i think this is a good start to look at – HRgiger May 11 '18 at 12:55
  • Yep , But if i remove the **AOP** related files , it works like a boss . So what would be the issue ? – Abhishek May 11 '18 at 12:57
  • So you should post your AOP files here dude. – Mạnh Quyết Nguyễn May 11 '18 at 12:59
  • I already posted all the AOP related code above . That's it . – Abhishek May 11 '18 at 13:00
  • Post me the header of your class – Mạnh Quyết Nguyễn May 11 '18 at 13:02
  • `@Component @Aspect public class MyAspect ` – Abhishek May 11 '18 at 13:12
  • Welcome to SO. In order to reproduce and debug an AOP-related problem we need your aspect code (already there, thanks), configuration and application code such as AOP target class, because these three things work together, problems could be in any of them. This is why the rule on SO is to provide an [MCVE](http://stackoverflow.com/help/mcve). Developers here like to analyse, not to guess. But this is exactly what everybody is doing here. It is a waste of time. So please edit your question accordingly. Thank you. – kriegaex May 12 '18 at 04:08
  • @Abhishek Did you ever find what caused this? As i'm currently having the exact same issue. – Carrier Pigeon Protocol Mar 25 '19 at 11:58

5 Answers5

1

You're advising all of your methods: @Around("execution(* com.kpi.ninja..*.*(..))")

So I guess Spring AOP excludes your MyAspect class to avoid infinite recursion.

Try to narrow down the @Around poincut to a single method first to see if it works.

After that use Point cut annotation to exclude your logTimeMethod from being advised.

Mạnh Quyết Nguyễn
  • 17,677
  • 1
  • 23
  • 51
1

Please Make sure that the class in which you are using the @Autowired is annotated with @Component/@Service/@Bean.The code you have posted does not include the initial class definition nor the spring XML so am not sure you have added the annotation in it or not.

@Component or @Controller or @Bean or @Service/@Repository 
Class ACB{

@Autowired
private Service service;

.....

}

Autowiring happens by placing an instance of one bean into the desired field in an instance of another bean. Both classes should be beans, i.e. they should be defined to live in the application context.

1

This happens when you @Autowired a private variable. Because AOP is not able to delegate a private variable, the variable becomes null in the AOP delegate class. To avoid this, you can create and use a getter for the private, autowired variable in your class instead of using the private variable directly.

See this example:

@Autowired
private SomeClass someClass;

Instead of using someClass.doSomething(), you should create a getter and use getSomeClass().doSomething().

Birju Vachhani
  • 6,072
  • 4
  • 21
  • 43
Lubo
  • 11
  • 1
0

You are having nullpointer because spring cannot initialize the Service class, you need to add the service in spring context xml, so declare a new bean:

<bean id="service" class="[package].Service"></bean>

If you don't have the context, you should create one and add the annotation in class declaration to set the path location of context.xml:

   @ContextConfiguration(locations = { "classpath:/context.xml" })
   public class YourClass{
       @Autowired
       Service service

      ...methods
   }
joumvaer92
  • 252
  • 3
  • 14
  • Problem is not about the annotation autowired , it is working without spring AOP , but when i added it , it stopped initializing – Abhishek May 12 '18 at 07:36
0

[https://stackoverflow.com/questions/828747/why-does-springs-configurable-sometimes-work-and-sometimes-not/63498314#63498314]:here is the answer

I found the reason. Because custom beans regist without order. If your bean be used before the Spring bean "org.springframework.context.config.internalBeanConfigurerAspect" was loaded,then @Configurable autowire will not work. And my solution is like below:

@Configuration
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
@EnableLoadTimeWeaving(aspectjWeaving = AspectJWeaving.ENABLED)
@EnableSpringConfigured
@ComponentScan(basePackages = "zhibo")
public class AppConfig extends WebMvcConfigurationSupport {

    @Bean
    public DemoProcessor demoProcessor() {
        return new DemoProcessor();
    }
}


public class DemoProcessor implements BeanPostProcessor,BeanDefinitionRegistryPostProcessor {

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
    Stream.of(beanDefinitionNames).forEach(System.err::println);
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    String[] beanDefinitionNames = registry.getBeanDefinitionNames();
    Map<String, BeanDefinition> zhiboBeans = new LinkedHashMap<>();
    //1. remove your beans. let spring's beans go ahead
    Stream.of(beanDefinitionNames).forEach(beanName->{
        BeanDefinition bd = registry.getBeanDefinition(beanName);
        if(bd.getBeanClassName()!=null && bd.getBeanClassName().startsWith("zhibo.")) {
            registry.removeBeanDefinition(beanName);
            zhiboBeans.put(beanName, bd);
        }
    });
    //2. regist your beans again
    zhiboBeans.forEach((k,v)->registry.registerBeanDefinition(k, v));
    }
}
Jack
  • 1