I use JBoss 7.1.1.Final. Here I have a startup singleton. At startup I initialize something, at shutdown I terminate/cleanup my stuff.
But now I found out, that the termination I can do whatever I want for 1 second! After one second the application is just away, and sometimes 1 second is not enough time for a real cleanup.
Code:
#Singleton
#Startup
public class ShutdownTest {
#PostConstruct
public void initialize() {
LOG.info("Initialization");
}
#PreDestroy
public void terminate() {
for(;;) {
LOG.info("loop in terminate...");
Tools.sleepQuietly(100); // just sleeps for 100 milliseconds
}
}
}
This class does report the initalization at startup, but at termination I get 10 times the output, after this, the JBoss is dead.
How can I configure this time until JBoss kills itself even if some PreDestroy methods are still running?
Currently I start and stop JBoss from Eclipse (Poller are set to Web Port).
There is no way to do this on JBoss 7 at the shutdown event (based on this answer of Tomaz Cerar from the JBoss / WildFly team).
On windows I can confirm that there is no way to do this (and I assume so for Linux).
I found it works if you halt the application before shutting the server down. That is: log on to the webconsole, navigate to Runtime (Tab on the upper right) -> Manage Deployments (menu) -> Button "Disable" for your application.
In WildFly 8 you get the "timeout" option for the shutdown. See this post on how to use it.
Related
I have a requirement to process the big file using these 2 case
(1) Pull from file directory and push to FTP
(2) Pull from one FTP and push to another FTP
I am creating a java maven dependency project which use camel components to process above use-case of file transfer, so I decided to use org.apache.camel.main.Main class to start my route, but the problem is my program is not getting closed even after file is processed successfully. Somewhere I read that using "System.exit()" would solve the problem but still problem exists.
My code-
Main camelMain = new Main();
camelMain.enableHangupSupport();
camelMain.addRouteBuilder(getRouteBuilderLocaltoFTP());
camelMain.run();
RouteBuilder
public void configure() throws Exception {
from(<File-Path>).routeId("local-to-ftp")
.onCompletion().process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
exchange.getContext().stop();
}
})
.toD(<FTP-Path>);
Also tried using control-Bus
.toF("controlbus:route?routeId=%s&action=stop&async=true", "local-to-ftp")
But in both the cases, routes are shutting down gracefully not closing the program.
Seek help in this.
You can configure on the main to shutdown the application after X period of time, or after processing N number of messages. And you can set both of them AFAIR, eg shutdown after 2 minutes, and after 1 message processed.
Just check the methods on camelMain. Mind that this requires a recent version of Apache Camel.
Various ways of Graceful Shutdown is documented here. You can try this code to shutdown a particular route
camelContext.getRouteController().stopRoute("routeId");
camelContext.removeRoute("routeId");
I want to write a JUnitTest, which ensures that my Karaf Server is started fine and all (needed) Bundles are installed and active.
For this I have a Test, calling a helper method "assertBundleState" which ensures, that the given Bundle is in the given State. The test looks like following:
#Test (timeout=30000L)
public void testBundlesStarted() throws Exception {
assertBundleState("bundle.Name", BundleLifecycleState.Active);
... <other bundles in similar way>
}
This worked fine in the past. The timeout was never reached.
Unfortunately I now have to load a bundle, which need a bit longer for startup. So the Bundles are not yet started, when the test is executed. And so the test fails.
I have tried it with a sleep in a BeforeClass method, but I am not really happy with this solution. Because I can't ensure that the given sleep time is enough on every machine at every time. So I am looking for some event-based solution to interact with Karaf.
#BeforeClass
public static void init() throws Exception {
Thread.sleep(120000L);
}
Does anybody have an idea how I can solve it in a better way?
Thanks
It sounds like assertBundleState can successfully determine whether the Karaf server has started and 'is ready'. But the issue is that you don't know how long to wait before checking this; if you don't wait long enough you risk a false negative, if you wait too long then your build elapsed time is falsely prolonged.
I presume you cannot register some sort of listener or callback hook which the Karaf server will invoke when it 'is ready'. Indeed, even if that was possible you would still have to cater for the failure case i.e. where the Karaf server does not start (and hence could never invoke a listener).
So, I think you just have to wait for the Karaf server to become available and hide the ugliness of Thread.sleep calls and the potential lost time in waiting too long. You could use Awaitility to tick those boxes. For example:
#Test
public void aTest() {
// run your test
// this will wait until Karaf is available for at most 10 seconds
// and will check every 100ms so if Karaf becomes available earlier
// than 10 seconds then the test will complete almost as soon as
// it becomes available but if Karaf does not become available
// within 10 seconds then the test will fail
await().atMost(10, SECONDS).until(karafIsAvailable());
// assert
// ...
}
private Callable<Boolean> karafIsAvailable() {
return new Callable<Boolean>() {
public Boolean call() throws Exception {
// return true if your condition has been met
// e.g. assertBundleState
return ...;
}
};
}
In my application I have written the shut down hook. But some third party code is calling that shut down hook.
This shut down hook should not be called by any third party code.
I have written the code to block shut down hook by third party but it did not help. (This code worked in my standalone test program. but did not worked in my application.)
Below are the code where something different behaviour is occurring:
final SecurityManager securityManager = new SecurityManager() {
public void checkPermission(Permission permission) {
System.out.println("In checkPermission:{" + permission.getName() + "}");
if ("exitVM.0".equals(permission.getName())) {
throw new ExitTrappedException();
}
}
};
When I execute this code in Test program then when shut down being called its giving me "In checkPermission:{exitVM.0}". So that it comes in if condition and my shut down hook gets blocked.
Now when I tried same thing in my application then this "exitVM.0" is not getting printed and shut down hook is getting called.
Any suggestions? Is there any different permission.getName() which can call shutdown hook?
It could be exitVM.1, exitVM.2, etc, since the number is just the shutdown code. The actual permission is called exitVM. (see http://docs.oracle.com/javase/7/docs/technotes/guides/security/permissions.html). So you could use permission.getName().startsWith("exitVM").
But what you're trying to do (prevent application being shut down) sounds like it might not be the best idea. What's the context?
I am trying to come up with a microservice using dropwizard.
The documentation tells how to start the application, but says nothing about terminating it gracefully. Fir example, apache tomcat has both startup and shutdown scripts.
So does anyone know how to terminate a dropwizard application other than pressing Ctrl+C of kill ?
Dropwizard Jetty has shutdown hooks. So kill -SIGINT <pid> works out really well.
Inspired by praveenag's answer, I dug into Jetty's code.
If you start DropWizard providing:
-DSTOP.PORT=xxxx -DSTOP.KEY=my_secret_key
as Java options,
It tells Jetty to listen on that port for a stop request.
You can then write to that socket to tell Jetty to shutdown. I did this from R like this:
socket = make.socket("localhost", 8082)
write.socket(socket, "my_secret_key\r\n")
write.socket(socket, "stop\r\n")
close.socket(socket)
I guess you can do the same from any other language.
The other answers here are great, but if you want to go a bit further up the stack and easily add custom logging / security / arbitrarily complex shutdown logic, then adding a shutdown hook via a dropwizard admin Task is a nice pattern.
Create a shutdown Task with any logic you like
import io.dropwizard.servlets.tasks.Task;
public class ShutdownTask extends Task {
public ShutdownTask() {
super("shutdown"); // the task name, used in the endpoint to execute it
}
public void execute(
ImmutableMultimap<String, String> immutableMultimap,
PrintWriter printWriter
) throws Exception {
// kill the process asynchronously with some nominal delay
// to allow the task http response to be sent
new Timer().schedule(new TimerTask() {
public void run() {
// any custom logging / logic here prior to shutdown
System.exit(0);
}
}, 5000);
}
}
Register the task in Application.run()
environment.admin().addTask(new ShutdownTask());
And then execute it via a POST to the following endpoint on the admin port
http://localhost:<ADMIN PORT>/tasks/shutdown
I am assuming this is not a question for your development environment but for your deployments. The answer depends on your deployment strategy. In the past we have handled deployments where the drop wizard application is bundled as a java process that can be started and the pid being recorded and forcefully kill the process. Or bundle the java process in an upstart/init script to gracefully start and shutdown the system.
On the other hand when you start a dropwizard application what it eventually does is start a jetty server. http://eureka.ykyuen.info/2010/07/26/jetty-stop-a-jetty-server-by-command. This can maybe shed some light on how you can pass the stop port as arguments when you start the dropwizard application.
Programmatically, you can also do:
environment.getApplicationContext().getServer().stop();
That's the environment you get in your Application:
#Override
public void run(ApplicationConfiguration configuration, Environment environment) throws Exception { ... }
In Java:
// In case vm shutdown
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run()
{
// what should be closed if forced shudown
// ....
LOG.info(String.format("--- End of ShutDownHook (%s) ---", "APPLICATION_NAME"));
}
});
Build your own strategy, how to shutdown your app.
I am using glassfish 3.1.2 build 5. I have two servers and each have 1 cluster. Each cluster have 2 instances. In my J2EE application i have schedulers(Cron Quartx schedulers) which will run every day at night 12 and also simply running below code at 30000(milli secs) interval
public synchronized void run() {
/** Some set of functions **/
/** Calling procedure **/
if count >0{
/** forming xml and updating web service**/
}else {
Thread.sleep(Integer.parseInt(30000));
}
My problem is when i deploy my application as a stand alone instance its running fine . When i deploy the same in above cluster and load balancing structure either i am facing null pointer exception or my applications got processed for 4 times. But it should happen only one for each application ? How to avoid this concurrency ?