java.lang.NullPointerException in Spring Boot [duplicate] - spring

This question already has answers here:
Why is my Spring #Autowired field null?
(21 answers)
Closed 6 years ago.
I was able to use RestTemplate and autowire it. However I want to move my rest template related part of code into another class as follows:
public class Bridge {
private final String BASE_URL = "http://localhost:8080/u";
#Autowired
RestTemplate restTemplate;
public void addW() {
Map<String, String> x = new HashMap<String, String>();
W c = restTemplate.getForObject(BASE_URL + "/device/yeni", W.class, x);
System.out.println("Here!");
}
}
And at another class I call it:
...
Bridge wb = new Bridge();
wb.addW();
...
I am new to Spring and Dependency Injection terms. My restTemplate variable is null and throws an exception. What can I do it how to solve it(I don't know is it related to I use new keyword)?

Using Bridge wb = new Bridge() does not work with dependency injection. Your restTemplate is not injected, because wb in not managed by Spring.
You have to make your Bridge a Spring bean itself, e.g. by annotation:
#Service
public class Bridge {
// ...
}
or by bean declaration:
<bean id="bridge" class="Bridge"/>

Just to add further to Jeha's correct answer.
Currently, by doing
Bridge wb = new Bridge();
Means that, that object instance is not "Spring Managed" - I.e. Spring does not know anything about it. So how can it inject a dependency it knows nothing about.
So as Jeha said. Add the #Service annotation or specify it in your application context xml config file (Or if you are using Spring 3 you #Configuration object)
Then when the Spring context starts up, there will be a Singleton (default behavior) instance of the Bridge.class in the BeanFactory. Either inject that into your other Spring-Managed objects, or pull it out manually e.g.
Bridge wb = (Bridge) applicationContext.getBean("bridge"); // Name comes from the default of the class
Now it will have the dependencies wired in.

If you want to use new operator and still all dependency injected, then rather than making this a spring component (by annotating this with #Service), make it a #Configurable class.
This way even object is instantiated by new operator dependencies will be injected.
Few configuration is also required. A detailed explanation and sample project is here.
http://spring-framework-interoperability.blogspot.in/2012/07/spring-managed-components.html

Related

#autowire beans and #value properties after object mapper deserialized json

I am using spring framework.
I am using objectMapper to desiriale store.json file:
service:
objectMapper.readValue(new File(jsonFilePath), Store.class)
store.json:
{
"type": "Store",
"name": "myStore",
}
Store.class:
#Value("${store.size:1000}")
private Integer sroreSize;
#autowire
private storePersistency storePersistency;
public Store(#JsonProperty("name") String name) {
super(name);
}
I am trying find out how to #autowire beans and #value properties in store.class, beans and properties that exist in applicationContext.
In current example sroreSize and storePersistency still null.
I know that I can inject fields to object mapper and then use #JacksonInject annotation but I have a lot of field to inject - not a good option for me.
Custom desirializer also not a good option for me.
Is there any way not to use custom desirializer or not to inject every bean/property that I need in store.class?
Something that injects all the beans and properties and I simply can use it in Store.class.
So you want some Store fields like storePersistency and sroreSize to be initialized once at application startup (which is when Spring will setup the application context) and then at runtime create multiple different Store objects differing in some fields as name that are initialized by Jackson.
I suggest annotating Store with #Component to get Spring to initialize #Value and #Autowired fields. The #Scope annotation will cause a new independent Store instance to be created each time. Simplified example:
#Component
#Scope(SCOPE_PROTOTYPE)
class Store {
private String name;
#Value("${store.size:1000}")
private Integer sroreSize;
}
Then the key is method readerForUpdating where you can pass an existing instance of Store and Jackson will update that instead of creating a new one as usually:
Store store = context.getBean(Store.class);
objectMapper.readerForUpdating(store).readValue("{\"name\":\"myStore\"}");
Where context is a Spring ApplicationContext reference that I autowired in a test class. You don't need to use the return value of readValue in this case, just inspect the existing store variable and name will be updated.

Creating Spring beans dynamically runtime using method

I have to use company's custom made libraries with Spring Boot and wondering if I'm able to create bean like this in runtime and add it to Spring application context.
#Bean(name = {"customConnectionFactory"})
public ConnFactory connector() {
return new SimpleConnFactory(configuration(), "prefix");
}
So this worked fine when I was allowed to wire beans normally when starting the application. Now requirements have changed and I should be able to do this dynamically runtime. I've done some research and it seems that it's possible to add class to spring context runtime, but how about running method which returns new object?
Could be something like this
DefaultListableBeanFactory beanFactory = //get and store the factory somewhere
MyBean newBean = new MyBean();
beanFactory.initializeBean(newBean,"TheBeanName"); //could be class' canonical name
beanFactory.autowireBeanProperties(newBean, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
beanFactory.registerSingleton("TheBeanName", newBean);

Null Pointer Exception In Spring Proxy Class and Kotlin

I am facing some problems with kotlin in conjunction with spring.
I have a controller bean (without an interface btw) which has an auto-wired service bean via the primary constructor.
It works perfectly unless I use caching annotations for the controller. Apparently springs caching generates a proxy class under the hood which deals with the caching.
My code looks like this:
#RestController
#RequestMapping("/regions/")
open class RegionController #Autowired constructor(val service: RegionService) {
#RequestMapping("{id}", method = arrayOf(RequestMethod.GET))
#Cacheable(cacheNames = arrayOf("regions"))
fun get(#PathVariable id: Long): RegionResource {
return this.service.get(id)
}
}
The problem now is a null pointer exception when the method is executed, actually this.service is null which technically is not possible as it is a nonnull variable in kotlin.
I assume that class proxies generated by spring initialize the class with null values instead of the autowired bean. This must be a common pitfall using kotlin and spring. How did you circumvent this problem?
In Kotlin both classes and members are final by default.
For the proxying library (CGLIB, javaassist) to be able to proxy a method it has to be declared non final and in a non final class (since those libraries implement proxying by subclassing). Change your controller method to:
#RequestMapping("{id}", method = arrayOf(RequestMethod.GET))
#Cacheable(cacheNames = arrayOf("regions"))
open fun get(#PathVariable id: Long): RegionResource {
return this.service.get(id)
}
You probably see a warning in console regarding RegionController methods not being subject to proxying.
The Kotlin compiler plugin
The Kotlin team has acknowledged this difficulty and created a plugin that marks the standard AOP proxy candidates e.g. #Component with open.
You can enable the plugin by in your build.gradle:
plugins {
id "org.jetbrains.kotlin.plugin.spring" version "1.1.60"
}
Soon this might not be a problem any longer.
There is work in progress that any lib (including spring for example) can specify a list of annotations a file in META-INF. Once a class is annotated with one of these, it will default to open for the class itself and all its functions. This is also true for classes inheriting from an annotated class.
For more details, have a look at https://github.com/Kotlin/KEEP/pull/40#issuecomment-250773204

Spring - Retrieve all scanned packages

I'm creating a Spring Starter project and need to get all classes which are marked with a custom annotation. The annotated class is not a spring bean.
My current solution is to use the ClassPathScanningCandidateComponentProvider to find the required classes.
ClassPathScanningCandidateComponentProvider scanner =
new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AnnotationTypeFilter(CustomAnnotation.class));
candidates = scanner.findCandidateComponents("THE MISSING PACKAGE NAME");
The problem is that I'm currently provide an empty package String so that all packages/classes are scanned which slows the startup down.
I need to access the packages which are scanned by Spring to avoid the scanning of all packages and classes.
Is there a way to retrieve all packages programmatically which are scanned by Spring or is there an alternative solution to retrieve custom annotated classes which are not Spring beans.
Greets
One solution without the need to make a full classpath scan is to use the AutowiredAnnotationBeanPostProcessor:
private List<Class<?>> candidates = new ArrayList<>();
#Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if(beanClass.isAnnotationPresent(YourAnnotation.class)){
candiates.add(beanClass));
System.out.println(beanClass);
return new Object();
}
}
#Bean
public CandiateHolder candidates() {
return new CandidateHolder(candidates);
}
You can check if the bean class which should be instantiated has the required annotation. If its the case you add the class to a property to expose it later as a bean. Instead of returning null you have to return an instance of a new Object. The returned object can be used to wrap the class in a proxy. Cause I don't need an instance I will return a simple new object. Its maybe a dirty hack but it works.
I have to use this kind of hack cause an instantiation of the needed object will result in an runtime error cause it has to be instantiated in the framework I use.

Grails Dependency Injection Outside of Services?

I have a Grails application that needs to run a strategy that will likely be swapped out over time. I know Spring underlies Grails, so I was wondering if I had access to Spring's IoC container so that I could externalize the actual dependency in an xml file (note: I have never actually done this, but just know of it, so I may be missing something). My goal is to be able to do something like the following:
class SchemaUpdateService {
public int calculateSomething(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
IStrategy strat = (IStrategy) ctx.getBean("mystrat");
}
}
And then map the appropriate implementation in the beans.xml file. I assume this is supported in Grails. Does anyone have any documentation on how this would work? Do I really just need the Spring IoC library and it will just work? Thanks!
You define your beans in resources.xml or resources.groovy. The grails documentation is very clear about how to access the Spring application context.
You can access the application context from any Grails artefact using
ApplicationContext ctx = grailsApplication.mainContext
You can then use this to retrieve whichever beans you're interested in:
IStrategy strat = (IStrategy) ctx.getBean("mystrat")
In classes that don't have access to grailsApplication, you could use a helper such as the following to access the application context and the beans therein
class SpringUtils {
static getBean(String name) {
applicationContext.getBean(name)
}
static <T> T getBean(String name, Class<T> requiredType) {
applicationContext.getBean(name, requiredType)
}
static ApplicationContext getApplicationContext() {
ApplicationHolder.application.mainContext
}
}
However, this should only be necessary if you need to retrieve different implementations of the same bean at runtime. If the required bean is known at compile-time, just wire the beans together in resources.xml or resources.groovy
First of all, you want to define your strategy in your grails-app/conf/spring/resources.groovy:
beans = {
myStrat(com.yourcompany.StrategyImpl) {
someProperty = someValue
}
}
Then, you simply def the a property with the same name into your service:
class SomeGrailsService {
def myStrat
def someMethod() {
return myStrat.doSomething()
}
}
In any Grails artefact (such as services and domain classes), Grails will automatically give the myStrat property the correct value. But don't forget, in a unit test you'll have to give it a value manually as the auto-wiring does not happen in unit tests.
Outside of a Grails artefact, you can use something like:
def myStrat = ApplicationHolder.application.mainContext.myStrat
In Grails 2.0, Graeme et al are deprecating the use of the *Holder classes (such as ApplicationHolder and ConfigurationHolder), so I'm not quite sure what the Grails 2.0 approach would be...

Resources