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
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 writing a java/spring library to include in other projects that are using quartz.
I need it to log some information about the task/calling class everytime a job is executed.
For example, if a quartz job looks like this:
#Bean
public JobDetail jobADetail() {
return JobBuilder.newJob(QuartzTaskA.class)
.withIdentity("sampleJobA")
.storeDurably().build();
}
#Bean
public Trigger jobATrigger(JobDetail jobADetail) {
return TriggerBuilder.newTrigger()
.forJob(jobADetail)
.withIdentity("sampleTriggerA")
.withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * ? * * *"))
.build();
}
public class QuartzTaskA implements Job {
#Override
public void execute(JobExecutionContext jobExecutionContext) {
log.info("QuartzA - the time is now {}", dateFormat.format(new Date()));
}
}
I want it to log something like:
Job [QuartzTaskA] with details [sampleJobA] and trigger [sampleTriggerA] is starting
QuartzA - the time is now 12:07:39
I customize the SchedulerFactoryBean with a custom TaskExecutor that does a log before the task.run().
This works and I am able print the additional first line, but I can't figure out how to get the details/context to pass into the log.
#Configuration
public class SchedulerFactoryCustomizer implements SchedulerFactoryBeanCustomizer {
private static final Logger log = LogManager.getLogger(SchedulerFactoryCustomizer.class);
#Override
public void customize(SchedulerFactoryBean schedulerFactoryBean) {
Executor executor = SchedulerFactoryBean.getConfigTimeTaskExecutor();
schedulerFactoryBean.setTaskExecutor(new CustomExecutor(executor);
}
private static class CustomExecutor implements Executor {
final Executor executor;
private CustomExecutor(Executor executor) {
this.executor = executor;
}
#Override
public void execute(Runnable task) {
// This line here. How can I get the details/context to pass in?
//log.info("Job {} with details {} and trigger {} is starting");
task.run();
}
}
}
how can I get the details/context to pass into the log?
You can implement a JobListener/TriggerListener
public class LoggingTriggerListener implements TriggerListener {
#Override
public String getName() {
return null;
}
#Override
public void triggerFired(final Trigger trigger, final JobExecutionContext context) {
}
#Override
public boolean vetoJobExecution(final Trigger trigger, final JobExecutionContext context) {
return false;
}
#Override
public void triggerMisfired(final Trigger trigger) {
}
#Override
public void triggerComplete(final Trigger trigger, final JobExecutionContext context, final Trigger.CompletedExecutionInstruction triggerInstructionCode) {
}
}
It injects jobExecutionContext also.
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()
}
}
How to call a spring controller after all the bean get initialized?
I used ServletContextListener and tried to call one controller. But, it doesn't exixts since all the bean initialization are getting invoked after the contextInitialized method execution.
I'm loading one variable from db, in the application context which has some global value. That action has to be triggered once the application is deployed immediately.
What needs to be done?
You can use the #PostConstruct phase to simulate context initialization completion.
I assume you want to invoke methods on ControllerA, ControllerB and store the results of those method invocations elsewhere on app start up.
public class InitializationHook {
private ControllerA controllerA;
private ControllerB controllerB;
#Autowired
public InitializationHook(ControllerA controllerA, ControllerB controllerB) {
this.controllerA = controllerA;
this.controllerB = controllerB;
}
#PostConstruct
public void init() {
//do whatever you want with both the controllers
controllerA.getGlobalValueFromDB();
controllerB.doSomethingElse();
/*
* At this point, controllerA and controllerB would have been initialized completely
* along with their dependencies (could be connections to DB etc) and ready for use.
* You don't have to worry about the other beans getting initialized.
*/
}
}
When you want to execute some piece of code exactly before the application startup completes, you can CommandLineRunner.
#Component
public class ControllerRunner implements CommandLineRunner {
private static final Logger logger = LoggerFactory.getLogger(ControllerRunner.class);
#Override
public void run(String...args) throws Exception {
logger.info("Your application has been started");
//TODO - call your controller
}
}
I achieved my requirement using below code:
#WebListener
public class StartUpListener implements ServletContextListener {
private static final Logger logger = Logger.getLogger(StartUpListener.class);
#Override
public void contextInitialized(ServletContextEvent sce) {
logger.info("********* context Refreshed **********");
new Thread(new Runnable() {
public void run(){
try {
TimeUnit.SECONDS.sleep(10);
URL url = new URL ("http://localhost:8080/myapp/loadFeature");
URLConnection con = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
logger.info(inputLine);
}
in.close();
} catch (Exception e) {
logger.error(e);
}
}
}).start();
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
logger.info("********* context contextDestroyed **********");
}
}
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
}