coundn't get bean when running a jar packed from a springboot project

Yi Tian :

I can run my springboot project in IDEA nicely but when packed it to a jar and run with the java command, just got the java.lang.NullPointerException when getting a bean from spring context.

the first class which just got errors:

@Service
public class MdspiImpl extends CThostFtdcMdSpi {
public MdspiImpl(CThostFtdcMdApi mdapi) {
        m_mdapi = mdapi;
        logger.info("MdspiImpl is creating...");
        ***mdr = SpringContextUtil.getBean("marketDataRobot");//this is the error code***
    }
}

the second class:

@Service
public class MarketDataRobot {
}

the SpringContextUtil class:

@Component("SpringContextUtil")
public class SpringContextUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
    public static <T> T getBean(String name) {
        return (T) applicationContext.getBean(name);
    }
}

the gradle file:

jar {
    baseName = 'programmingTrading'
    version =  '0.1.0'
    manifest {
        attributes 'Main-Class': 'com.blackHole.programmingTrading'
    }
}

the running exception:

WARN main[AbstractApplicationContext.java:557 Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mdspiImpl' defined in URL [jar:file:/E:/workspace/simuPrd/programmingTrading-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/blackHole/programmingTrading/infrastructure/MdspiImpl.class]: Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.blackHole.programmingTrading.infrastructure.MdspiImpl]: Constructor threw exception; nested exception is java.lang.NullPointerException] 
[com.blackHole.programmingTrading.infrastructure.MdspiImpl]: Constructor threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:184)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:300)
    ... 27 common frames omitted
Caused by: java.lang.NullPointerException: null
    at com.blackHole.programmingTrading.SpringContextUtil.getBean(SpringContextUtil.java:35)
    at com.blackHole.programmingTrading.infrastructure.MdspiImpl.<init>(MdspiImpl.java:46)

It also stem from another problem: @Autowired annotation doesn't work... when using like this:

@Component
public class Scu{
}

in another class:

@Autowired
private Scu scu;
logger.info(String.format("MdspiImpl is creating...[%s]", scu.toString()));

will get a java.lang.NullPointerException: null

spring-boot configuration like this:

@SpringBootApplication
public class ProgrammingTrading {
    public static void main(String[] args) {
        SpringApplication.run(ProgrammingTrading.class, args);
    }
}

that is part of reasons of using SpringContextUtil to get the bean... thanks a lot!

buræquete :

SpringContextUtil shouldn't be a accessed statically like you are doing... Since you define it as a @Component do the following;

@Service
public class MdspiImpl extends CThostFtdcMdSpi {

    @Autowired
    private SpringContextUtil springContextUtil;

    public MdspiImpl(CThostFtdcMdApi mdapi) {
        m_mdapi = mdapi;
        logger.info("MdspiImpl is creating...");
        ***mdr = springContextUtil.getBean("marketDataRobot");
    }
}

Due to SpringContextUtil not being injected via Spring, but simply accessed statically, the applicationContext inside of it is ignored and is null in your case.

Also remove the static modifier;

@Component
public class SpringContextUtil implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    // include getter/setter for applicationContext as well

    public <T> T getBean(String name) {
        return (T) applicationContext.getBean(name);
    }
}

edit

The trouble from the latest example project;

@Service
public class ExampleService {
    @Autowired
    private Logger logger;

    public ExampleService() {
        this.logger=logger;
        logger.info("Im working");
    }
}

Here the Logger will be null, when the ExampleService constructor is triggered, since the constructor is called before the injection starts, but you can merge this behaviour if you incorporate the injection through the said constructor as follows;

@Service
public class ExampleService {

    private final Logger logger;

    public ExampleService(Logger logger) {
        this.logger = logger;
        logger.info("Im working");
    }
}

Works perfectly without any trouble...

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=122641&siteId=1