I am trying to run following but I am facing null pointer at userService.getName();
without thread it is working fine but with thread it is throwing null pointer exception
public class Sheduler implements Callable{
private UserService userService;
private SchedulerExecuterService scheduler=Executers.newScheduledThreadpool(2);
#Inject
public Sheduler (UserService userService){
this.userService = userService;
}
Future future = scheduler.submit(new Callable(){
#override
public String call() throws Exception{
**return userService.getName();//NUll pointer Exception**
}
)}
public void startpool(){
final Runnable beeper = new Runnable(){
public void run(){
UserService userService = new UserService();
Sheduler scd=new Sheduler (UserService userService);
future.get();
}
}
scheduleAtFixedRate(beeper,5,5,TimeUnit.SECONDS);
}
public static void main(){
Sheduler scduler=new Sheduler();
scduler.startpool();
}
You use an #Injecton your Scheduler constructor but still instantiate it manually. Your UserService is never injected and therefore is null throwing the NullPointerException.
Related
Code explanation:
MainThread creates ChildThread based on the list of users - one Childthread per user. I am trying to write a unit test case for MainThread and I want to skip the implementation of ChildThread (a separate unit test case will be written for ChildThread). Below is the code snippet.
#Slf4j
public class MainThread implements Runnable {
private static final UserService USER_SERVICE = ApplicationContextUtils.getApplicationContext().getBean("userService", UserService.class);
private final String threadName;
public MainThread(String threadName) {
this.threadName = threadName;
}
public void run() {
log.info("{} thread created at {}", threadName, LocalDateTime.now());
List<UsersDTO> usersDTOs = USER_SERVICE.getUsers();
ExecutorService executor = Executors.newFixedThreadPool(usersDTOs.size());
usersDTOs.stream().map(ChildThread::new).forEach(executor::execute);
executor.shutdown();
}
}
#Slf4j
public class ChildThread implements Runnable {
private final UserDTO userDTO;
public ChildThread(UserDTO userDTO) {
this.userDTO = userDTO;
}
public void run() {
log.info("Child thread created for user: {}", userDTO.getName());
// some business logic
}
}
#TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class MainThreadTest {
#Mock
private ApplicationContext applicationContext;
#Mock
private UserService userService;
#BeforeEach
public void setUp() {
MockitoAnnotations.openMocks(this);
new ApplicationContextUtils().setApplicationContext(applicationContext);
}
#Test
void test() {
Mockito.when(applicationContext.getBean("userService", UserService.class)).thenReturn(userService);
Mockito.when(userService.getUsers()).thenReturn(MockObjectHelper.getUsersList());
ChildThread childThread = new ChildThread(MockObjectHelper.getUser());
ChildThread spy = spy(childThread);
doNothing().when(spy).run();
MainThread mainThread = new MainThread("TestingThread");
mainThread.run();
verify(userService, times(1)).getUsers(any());
}
}
Despite spying ChildThread, the run() method of ChildThread is executed. doNothing().when(spy).run(); is of no effect. For some reason, I cannot use PowerMockito. How to achieve this with mockito-inline (version 3.10.0) and java8?
Any help would be appreciated.
Instead of mocking ChildThread refactor MainThread so ExecutorService is injected in constructor.
Then mock ExecutorService and check if it is receiving correct ChildThread instances.
I am struggling to run a thread in background with autowired bean in spring boot. From all the internet source I found that if I create a new instance of the object it will throw null because it is not part of spring life cycle and I would instead need to use executorTask and inject it as bean. Here is what I have tried so far with no luck.
My Application.java file
#SpringBootApplication
#EnableAsync
public class Application {
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
SpringApplication.run(Application.class, args);
}
}
My ThreadConfig.java file [where I actually create the bean for task executor]
#Configuration
public class ThreadConfig {
#Bean
public TaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(4);
executor.setMaxPoolSize(4);
executor.setThreadNamePrefix("default_task_executor_thread");
executor.initialize();
return executor;
}
}
The AsyncService.java file
#Service
public class AsynchronousService {
#Autowired
private ApplicationContext applicationContext;
#Autowired
private TaskExecutor taskExecutor;
public void executeAsynchronously() {
NotificationThread myThread = applicationContext.getBean(NotificationThread.class);
taskExecutor.execute(myThread);
}
}
The actual thread that I want to run in background
#Component
#Scope("prototype")
public class NotificationThread implements Runnable {
#Autowired
private UserDao userDao;
public void run() {
while (true) {
System.out.println("thread is running...");
List<User> users = userDao.findAllByType("1"); //Used to get Error here when running directly from main
try {
Thread.sleep(1000 );
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Before when I directly create this thread in main I would get error as mentioned in the comment line. So i switched to taskexecutor.
NotificationThread is the thread i want to run in background. But its not working, not sure what changes to make. Would help guidance.
Need to call the service method executeAsynchronously() to start the flow.
You may auto-wire AsynchronousService to the ThreadAppRunner as follows and call service.executeAsynchronously().
#Component
public class ThreadAppRunner implements ApplicationRunner {
#Autowired
AsynchronousService service;
#Override
public void run(ApplicationArguments args) throws Exception {
service.executeAsynchronously()
}
}
I have a component that I would like to call a service method from. When I try to call nothing happens. The service method is completablefuture method that calls a rest api. Could this have anything to do with it?
I've tried calling it from different classes and it works. Only this class is an issue.
Snippet of the class I'm calling it from:
#Component
#Scope("prototype")
public class Reader{
///and other variable declarations used
#Autowired
private AsyncServices aService;
public void StartAsync() throws InterruptedException, IOException{
Runnable task = new Runnable() {
#Override
public void run() {
try {
StartInventory();
} catch (Exception ex) {
System.out.print("start inventory thread could not start:
"+ex.getLocalizedMessage());}
}
};
Runnable task2 = new Runnable() {
#Override
public void run() {
try {
StartTCPClient();
} catch (Exception ex) {
System.out.print("start tcpclient thread could not start: "+ex.getMessage());
}
}
};
tcpClientThread = new Thread(task2, "TCPClientThread");
tcpClientThread.setDaemon(true);
tcpClientThread.start();
inventoryThread = new Thread(task, "InventoryThread");
inventoryThread.setDaemon(true);
inventoryThread.start();
public void StartInventory() throws InterruptedException, ExecutionException, ParseException{
......
//calling the method in #service class
aService.findVehicle(rfidtag);
}
code for service:
#Service
public class AsyncServices {
private final RestTemplate appRestTemplate;
#Autowired
public AsyncServices(RestTemplateBuilder builder){
this.appRestTemplate=builder.build();
}
#Async
#Transactional
public CompletableFuture<BmwvehicleTest> findVehicle(String rfidtag) throws InterruptedException{
log.info("trying to find a vehicle test by rfidtag"+ rfidtag);
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity <BmwvehicleTest> entity = new HttpEntity <BmwvehicleTest>(headers);
BmwvehicleTest results=appRestTemplate.exchange("http://localhost/tag/"+rfidtag, HttpMethod.GET, entity, BmwvehicleTest.class).getBody();
return CompletableFuture.completedFuture(results);
}
I expect to be able to get the result from the service method which is getting results from a rest api.
I have started a thread but when it try to access entity Manager it throws exception as
javax.enterprise.context.ContextNotActiveException:
WebBeans context with scope type annotation #RequestScoped does not exist within current thread
How should I access EntityManger with thread
any solution?
public class SchedulerForData {
#Inject
private DefaultUserSevice userSevice;
public void beepForAnHour() {
long initialDelay;
final Runnable beeper = new Runnable() {
public void run() {
userSevice.getData();
}
scheduler.scheduleAtFixedRate(beeper, 60, 30, TimeUnit.SECONDS);
}
}
}
public class DefaultUserSevice {
#Inject
EntityManager entityManger;
public void getData(){
List resultList = entityManager.createNativeQuery("Select * from USER").getResultList();
}
}
If there is no other configuration on the service, you should make the service a managed bean and add transactional feature:
#Stateless
#TransactionManagement(TransactionManagementType.CONTAINER)
public class DefaultUserSevice
I have an application built upon Spring Boot. There is simple controller with a method which creates new Thread and starts it. However a runnable executes unix command (nc) (used ProcessBuilder for that). Thus when I'm runnning it on the windows I get exceptions from started thread. Indeed it can not run unix program. Now I would like to write a test for this controller, but I'm wondering is it possible and reasonable. I was thinking about changing behaviour of runnable task just for testing, although I don't know how can it be done. Thanks for any help and other ideas/solutions for this case.
Controller:
#Controller
public class TaskController {
ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat(task-%d").build();
#RequestMapping(value = "/startTask")
public #ResponseBody ResponseEntity<String> startTask() {
Runnable runnable= new Task();
threadFactory.newThread(runnable).start();
return new ResponseEntity<String>("Task started", HttpStatus.ACCEPTED);
}
}
Task:
public class Task implements Runnable {
#Override
public void run() {
// start unix process
}
}
Application class:
#ComponentScan
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Integration Test:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
#WebAppConfiguration
#IntegrationTest("server.port=0")
#DirtiesContext
public class ApplicationTest {
#Value("${local.server.port}")
private int port;
#Test
public void shouldStartTask() throws Exception {
// when
ResponseEntity<String> entity = new TestRestTemplate().getForEntity("http://localhost:" + this.port + "/startTask", String.class);
// then
assertThat(entity.getStatusCode()).isSameAs(HttpStatus.ACCEPTED);
}
}
You might find it easier to test your program if you the extract the processing logic of your application (which does things using threads) from your controller logic, placing the processing logic in a separate service layer, which your controller delegates to. Design the service layer to have an API that is easy to unit test, by providing methods for accessing its current state, not just for performing actions. Use dependency injection to connect your controller to your service layer.
So, something like this:
public interface Service
{
// Sets this.wasTaskStarted() == true
void startTask();
boolean wasTaskStarted();
void awaitCompletionOfTask();
}
#Controller
public class TaskController {
private final Service service;
#Autowired
public TaskController(Service service) {
this.service = service;
}
#RequestMapping(value = "/startTask")
public #ResponseBody ResponseEntity<String> startTask() {
service.startTask();
return new ResponseEntity<String>("Task started", HttpStatus.ACCEPTED);
}
}
public ServiceImpl implements Service {
private final ThreadFactor threadFactory = new ....;
private Thread taskTread;
#Override
public synchronized void startTask() {
if (taskTread == null) {
taskTread = threadFactory.newThread(new Task());
taskTread.start();
notifyAll();
}
// else already started
}
#Override
public synchronized boolean wasTaskStarted() {
return taskTread != null;
}
#Override
public synchronized void awaitCompletionOfTask() {
while (taskTread == null) {
wait();
}
taskTread.join();
}
}
To test that your controller starts a task, you just need to test that Service.wasTaskStarted() is true after calling TaskController.startTask().
You also have to test your service layer:
public class ServiceImplTest
{
#Test
public void testStartTask() {
final ServiceImpl service = new ServiceImpl(....);
service.startTask();
assert(service.wasTastStarted());
}
#Test
public void testRunTask() {
final ServiceImpl service = new ServiceImpl(....);
service.startTask();
service.awaitCompletionOfTask();
// Add assertions here to test that the task did what it ought to do
}
}
Thanks for the suggestion. You just opened my mind and I changed the design a bit. I resigned from an integration test. From business point of view, I don't need to check whether task has been started or even completed. Now it looks as follows:
Controller:
#Controller
public class TaskController {
private ThreadService threadService;
#Autowired
public TaskController (ThreadService threadService) {
this.threadService= threadService;
}
#RequestMapping(value = "/startTask")
public #ResponseBody ResponseEntity<String> startTask() {
// some conditions here which I would like to test
threadService.startNewThread(new Task());
return new ResponseEntity<String>("Task started", HttpStatus.ACCEPTED);
}
}
Task:
public class Task implements Runnable {
#Override
public void run() {
// start unix process
}
}
Thread service:
#Component
public class ThreadService {
ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("task-%d").build();
public void startNewThread(Runnnable task) {
threadFactory.newThread(task).start();
}
}
And I decided to unit test my controller, stubbing ThreadService with mockito:
#RunWith(MockitoJUnitRunner.class)
public class TaskControllerTest {
#Mock
ThreadService threadService;
#InjectMocks
private TaskController objectUnderTest;
#Test
public void shouldStartTask() throws FileNotFoundException {
// when
ResponseEntity<String> response = objectUnderTest.startTask();
// then
assertThat(response.getStatusCode()).isSameAs(HttpStatus.ACCEPTED);
// more assertions
}