Spring Boot's scheduled programmatic restart using RestartEndpoint failed to start intermittently - java

I wrote below scheduler which runs everyday midnight 12 am. This has to restart the spring boot web application ( self ) and it is working as expected most of the time.
But once in a week ( approximately), application shutdown happens successfully, but not starting up.
Because this is failing intermittently, I have no clue why this code failing.
In my eclipse IDE environment, it works almost everytime. ( I changed the scheduler to run every 5 mins)
#Service
final class AutoRestartScheduler {
#Autowired
private RestartEndpoint restartEndpoint; //private to protect outside access.
final Logger logger = LoggerFactory.getLogger(AutoRestartScheduler.class);
#Scheduled(cron = "0 0 0 * * *", zone="America/Los_Angeles") //everyday mid-night 12 AM PST
public void restartApp(){
logger.info("Going to restart Tomcat, programmatically.");
logger.info("restarting MyPollerApplication...");
restartEndpoint.restart();
}
}
NOTE:
I am NOT using below property in configuration, because I am NOT using Actuator's /restart endpoint but Spring's Scheduler.
management.endpoint.restart.enabled=true

Since you don't see your own log messages when it fails to restart, that tells us that the application isn't going through the restart code that you're showing; maybe something else is causing the application to shut down.
From the log message you show ("Going to restart Tomcat"), I suspect you might misunderstand what RestartEndpoint really does. It restarts the Spring ApplicationContext, not the JVM or OS process, and possibly not the Tomcat instance that's hosting the application. Take a look at the JavaDoc and source code for that class to make sure it's actually doing what you think it's doing, and that you're using it correctly. Consider enabling Spring's own logging for this class at DEBUG level to see more about what's going on.

Related

Spring Boot : Disable Quartz Scheduler

We are using Quartz Scheduler in our Spring Boot Application.
There is a scenario for which we want to disable it.
We have tried using #ConditionalOnProperty(name = Constant.QUARTZ_ENABLED) option on our class.
We have defined quartz.enabled = false property in application.properties file.
However when we run on Tomcat server locally on Spring Tool Suite it is working as expected (meaning it is not invoking the quartz scheduler).
But when same code is deployed on Weblogic, the scheduler is still running.
Should we try putting #ConditionalOnProperty(name = Constant.QUARTZ_ENABLED) annotation at method level. specifically the method where trigger is used?
We have gone through the options mentioned on various forums but still not reached the solution.
Is there any way we can
1. Stop the scheduler from starting
Or
2. Stop the Job from getting triggered
Thanks in advance.

Is it possible/advisable to run Spring Boot without controllers just for the #ScheduledTasks and ORM?

I'd like to run a Spring Boot service without any of the controller-related stuff. I'd like it to just run a scheduled task every hour and do work if needed. I'm wanting to use Spring Boot, because I already know how to set the Hibernate ORM up, and I'm re-using a lot of the same repositories as another Spring Boot service. So, I spun up a new Spring Boot project and left out the start-web package.
The main issue I'm running into is that despite having a scheduled task set up, the service starts and immediately quits without running the scheduled task. In my head, I imagined the service kind of just sitting there, running, waiting for the time to trigger the scheduled job I have configured and kind of just sleeping until then. Are my expectations bad, or do I just have it misconfigured?
I've solved the problem. It was a configuration issue causing the Spring Boot app to not recognize the presence of required configuration values in the application.properties file.
You can either remove spring-boot-starter-web from your dependencies or in your main class you can configure the SpringApplicationBuilder to not include the web server.
new SpringApplicationBuilder(YourApplication.class)
.web(WebApplicationType.NONE)
.run(args);
Use #EnableScheduling in main class and application won't shuts down.

Spring cron job working in local but not in amazon instance

I have developed a spring boot project.
It uses #EnableScheduling and #Scheduled annotations to schedule task. I have tried both ways to schedule my function.
1)
#Scheduled(initialDelayString = "${scheduler.initialDelay}", fixedDelayString = "${scheduler.fixedDelay}")
2)
#Scheduled(cron = "0 0 1 * * *")
In both ways when I run my code locally, It gets run perfectly fine. But when I deploy my code to AWS instance using auto scaling group, spring application gets start, but after that nothing is happening. I don't even see any logs or error about scheduler. Application is running but scheduler is not getting invoked.
It seems very strange to me. And since its working perfectly very well in local, it is difficult to debug also.
I had a similar issue, I believe its to do with the Springboot default threadpool for scheduling. It worked for me when i altered the below setting in application.properties / yaml
spring.task.scheduling.pool.size=20

Call method after JBoss deploy

I want to have some method run, only after my WAR has been deployed to JBoss.
The problem: Currently I am using #PostConstruct to load saved schedules from the DB. The problem is that I am creating instances of the Schedulers from this method, which in turn is starting the Quartz schedulers, which is stopping JBoss from completing the deploy.
If there are no schedules to load, my WAR deploys fine, but if there are schedules they are causing the deploy to fail, because JBoss is "waiting" for the schedules to actually complete.
Is there some way to delay the method call until after it is fully deployed?
Or alternatively, is it possible to make Async calls on the Server (from the Server code)?
Java EE specification heavily refrain any thread manipulation outside facility provided by the application server.
You shouldn't in any case use a container manged thread in an infinite loop; the container expect the thread to be returned. Thread creation can still be done without too much collateral damage (if you don't put several apps on the server as the container won't be able to manage the resources between all the applications) but the any container thread must be returned.
In the new Jboss 7 there is some Java EE scheduling facilities (#Scheduling and timer, with possible persistent timer). A quick search show some example how to run Quartz in JBoss 7: How to enable Quartz scheduling in Jboss AS 7.0?
In older JBoss more advanced integration exist (JCA integration is the only standard way to get finer thread management). Use google to find them.
Wouldn't the simple ServletContextListener solve the problem for you? Just implement whatever you need in contextInitialized method.
In JBoss 7, there is a management api.
Maybe you can use it to check if the server is started (with a singleton and a TimerService).
Sample code:
ModelControllerClient client = ModelControllerClient.Factory.create(InetAddress.getByName("localhost"), 9999);
ModelNode op = new ModelNode();
op.get(ClientConstants.OP).set("read-attribute");
op.get(ClientConstants.NAME).set("server-state");
ModelNode returnVal = client.execute(op);
if(StringUtils.equals(returnVal.get("result").toString(), "\"running\"")){
LOGGER.info("Server running, init start actions");
timer.cancel();
}else{
LOGGER.info("Server not running, wait");
}

Spring: Is there a simple non-web tutorial?

I'm attempting to create a Spring application (NOT web application) to perform some simple tasks. Eventually they will hook up with some other Spring apps around the network, but for now I'm keeping it simple. I have a CheckForNewItems class (extending Timer) which is configured to run every 10 seconds.
I can confirm it runs by calling it programmatically:
public class Tester {
public static ApplicationContext context;
private void loadContext() {
String filename = "beans.xml";
context = new FileSystemXmlApplicationContext(filename);
}
public static void main(String[] args) {
Tester test = new Tester();
test.loadContext();
CheckNewItemsTask task = (CheckNewItemsTask)context.getBean("checkNewItemsTask");
}
}
Running this works as expected, task.run() gets called every 10 seconds. Now I need to work out how to deploy this to either a JBoss or Tomcat server, in such a way that it automatically starts running the task.
Most of the tutorials I've found only describe how to get Spring MVC and servlets running, not a standalone application. Does anyone know better?
Cheers, Rob.
You don't need JBoss or Tomcat to do that. If the app is headless and you have no intention of adding a UI, consider jsvc for unix or procrun on windows. If you need the ability to monitor and control an app and do not need a proper UI for doing that, you might want to look at JMX. This will work on a daemon without the rest of the Java EE stack.
If you have a maven project and want an easy way to turn it into a deployable daemon app, you can use maven appassembler to automate the process of creating a deployable daemon, setting up a directory structure of the app, scripts to start and stop, libraries and config files.
You need a servlet that is set to autostart on deployment. The servlet can then call into your "Tester" class to trigger your "standalone" initialization process.
If you don't have a servlet (or potentially some other server related process) reference your code, then your initialization process will never be run.

Categories