I'm still pretty new to Spring, but I'm currently facing an issue of which I don't know the cause and I can't figure it out with only a nullpointerexception.
I have 2 classes that both implement the same Abstract class. InventoryService and InventoryMailService. All 3 are in the same package that is successfully being scanned with component-scan. I'm trying to use my globalPrefService bean, which I can succesfully use in my InventoryService but somehow not in my InventoryMailService.
This is my AbstractService that I use to wire my services together:
package com.paperfoam.inventory.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("abstractService")
public abstract class AbstractService {
protected InventoryService inventoryService;
protected FinancialCalculationService financialCalculationService;
protected SupplierService supplierService;
protected UserService userService;
protected GlobalPrefService globalPrefService;
@Autowired
public void setGlobalPrefService(GlobalPrefService globalPrefService) {
this.globalPrefService = globalPrefService;
}
@Autowired
public void setInventoryService(InventoryService inventoryService) {
this.inventoryService = inventoryService;
}
@Autowired
protected void setFinancialCalculationService(FinancialCalculationService financialCalculationService) {
this.financialCalculationService = financialCalculationService;
}
@Autowired
protected void setSupplierService(SupplierService supplierService) {
this.supplierService = supplierService;
}
@Autowired
protected void setUsersService(UserService userService) {
this.userService = userService;
}
}
This is the the InventoryService (minus some non-related functions), when I try to call my GlobalPrefService it works just fine:
package com.paperfoam.inventory.service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.paperfoam.inventory.dao.InventoryDao;
import com.paperfoam.inventory.dao.InventoryLogItemDao;
import com.paperfoam.inventory.objects.InventoryItem;
import com.paperfoam.inventory.objects.InventoryLogItem;
@Service("inventoryService")
public class InventoryService extends AbstractService {
private InventoryDao inventoryDao;
private InventoryLogItemDao inventoryLogItemDao;
public InventoryDao getInventoryDao() {
return inventoryDao;
}
@Autowired
public void setInventoryDao(InventoryDao inventoryDao) {
this.inventoryDao = inventoryDao;
}
@Autowired
public void setInventoryLogItemDao(InventoryLogItemDao inventoryLogItemDao) {
this.inventoryLogItemDao = inventoryLogItemDao;
}
// This is the method where I succesfully use my GlobalPrefService
public List<InventoryItem> getAllInventoryItems() {
System.out.println(globalPrefService.getPreferenceValue("mailusername")); // this succesfully prints my preferenceValue to the console
return inventoryDao.getInventoryList();
}
}
However, I have my other class (same package) that extends the same AbstractService that returns a NullPointerException when I try to use it:
package com.paperfoam.inventory.service;
import java.io.File;
import java.util.logging.Logger;
import javax.mail.internet.MimeMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.mail.MailParseException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import com.paperfoam.inventory.config.JavaBeanConfig;
import com.paperfoam.inventory.objects.InventoryItem;
import com.paperfoam.inventory.objects.Supplier;
@Service("inventoryMailService")
public class InventoryMailService extends AbstractService {
public void sendMessageWithAttachment(String to, String subject, String text, String pathToAttachment) {
System.out.println(globalPrefService.getPreferenceValue("mailusername")); // NullPointerException on the globalPrefService!
/*
JavaBeanConfig javaBean = new JavaBeanConfig();
JavaMailSender mailSender = javaBean.getJavaMailSender(globalPrefService);
try {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(text);
Resource file = new ClassPathResource(pathToAttachment);
helper.addAttachment("hoera.png", file);
mailSender.send(message);
} catch (Exception e) {
e.printStackTrace();
}
*/
}
}
The error I get:
SEVERE: Servlet.service() for servlet [paperfoam] in context with path [/bulletjournal] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException
at com.paperfoam.inventory.service.InventoryMailService.sendMessageWithAttachment(InventoryMailService.java:30) // This is the system.out line
at com.paperfoam.inventory.controllers.InventoryController.showInventoryStatistics(InventoryController.java:165)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1115)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
I have been staring at this for a while and I can't figure out what causes this. Everything is annotated in the same way, they extend the same class that autowires the bean in, they are in the same package that is being scanned and the access modifiers are also the same.
I also tried to clean/rebuild my project a few times, does anyone have any idea what I am missing here?
Thank you for reading.
In response to the comment:
My InventoryService gets Autowired in the controller.
protected InventoryService inventoryService;
@Autowired
public void setInventoryService(InventoryService inventoryService) {
this.inventoryService = inventoryService;
}
But I manually instantiate my InventoryMailService (and I'm starting to think thats the mistake) for debugging.
@RequestMapping(value = { "/statistics", "/" })
public String showInventoryStatistics(Model model) {
Map<Integer, Long> calculated = financialCalculationService.getSuppliersWithTotalWorth();
List<Supplier> allSuppliers = supplierService.convertSupplierHashmapToObjectList(calculated);
List<InventoryItem> lowItems = inventoryService.getLowInventoryItems();
List<InventoryLogItem> recentChanges = inventoryService.getRecentChanges();
model.addAttribute("suppliers", allSuppliers);
model.addAttribute("lowitems", lowItems);
model.addAttribute("recentchanges", recentChanges);
InventoryMailService mail = new InventoryMailService();
System.out.println(mail.toString());
mail.sendMessageWithAttachment("Redacted@gmail.com", "betere mail", "test123", "com/paperfoam/inventory/mail/success.png");
return JspPage.INVENTORY_STATISTICS;
}
I didn't even stop to think that that might affect the autowiring down the road, does that matter to spring?