Java Shutdown hook is getting called without exitVM.0 from permission.getName() - java

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?

Related

Java shutdown hook not running

I have a product service in Java. In our code I am creating shut down hook, but when I stop service it is not calling shut down hook consistently. Out of 5 stop calls it has called shutdown hook only once.
Runnable shutdownHandler = new Runnable() {
#Override
public void run() {
s_log.info("Shutting down thread..");
}
};
Runtime.getRuntime().addShutdownHook(
new Thread(shutdownHandler, "shutdownthread"));
Can anybody please tell me what could be the reason behind this not getting called consistently?
Check the following code:
Runnable shutdownHandler = new Runnable() {
#Override
public void run() {
System.out.println("Shutting down thread..");
}
};
Runtime.getRuntime().addShutdownHook(
new Thread(shutdownHandler, "shutdownthread"));
and if it gives you expected output, you need to check the documentation of your logging framework.
I am also finding that my framework (Jooby) and Java shutdown hooks work fine on my Mac on IntelliJ which sends a kill SIGINT (-2) however on Ubuntu Server 20.04 LTS they don't run.
As my Java app is a webapp I came up with a simple workaround:
Setup a controller to listen to some url that isn't easily guessable e.g.
/exit/fuuzfhuaBFDUWYEGLI823y82941u9y47t3u45
Have the controller simply do the following:
System.exit(0)
Do a curl or wget from a script to the URL and the shutdown hooks all fire as JVM comes down.
I suspect for some reason on Linux there is a bug and no matter what interrupt that I use besides SIGKILL they all effectively behave like SIGKILL and the JVM comes down hard/abruptly.

Java program exit with code "130"

When I close a java program in intellJ, the following log appears in the console:
"Process finished with exit code 130"
Some times, the code is "1".
I know this is the very basic, but I googled Internet and still couldn't find the explanation for the exit code.
What does the code mean? Where can I find the explanation?
To steal #Baby 's answer from the comments and formalize it, the 130 exit code is given by bash, and Mendel Cooper's Bash-Scripting Guide states that it indicates that the process was terminated by a SIGTERM. Generally this is the user pressing Ctrl-C.
This answer is applicable if you want to get the behavior of many native apps that return code 0 after a graceful shutdown.
You can register a hook that performs the graceful shutdown, for example releasing resources retained by the app. If the graceful shutdown succeeds, this hook can also override the exit code to 0. The hook will be called on SIGTERM (happens when the user is pressing Ctrl+C).
Runtime.getRuntime()
.addShutdownHook(
new Thread(
() -> {
//graceful shutdown steps
Runtime.getRuntime().halt(0); //override the exit code to 0
}));
The solution above will prevent other hooks that may exist to run after this one. It will also prevent files to be deleted that had .deleteOnExit() called.
Another approach may be implementing and registering a SecurityManager that looks like this:
static class Converting130To0SecurityManager extends SecurityManager {
#Override
public void checkExit(int status) {
if (status == 130) {
System.exit(0);
} else {
super.checkExit(status);
}
}
#Override
public void checkPermission(Permission perm) {
// Allow all activities by default
}
}
...
System.setSecurityManager(new Converting130To0SecurityManager());
Such a security manager will always transform 130 code into 0 irrespectively to the graceful shutdown.

Java Shutdown function not executing

Within the main() of my application I have the following code to back up data so it doesn't get lost in the event of a system shut down.
//add hook to trigger Production Shutdown sequence
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run() {
Production.shutdown();
}
}));
However, whether I press the Stop button in my IDE or rely on input via the log (code shown below) it never seems to save data to the database or write any logs to the console.
ctx.deploy(server);
server.start();
//start the production process
Production.init();
System.in.read();
server.stop();
How come this shutdown function is not being executed?
You need to use the Exit button, not Stop, see my answer here for more details.
Note that this feature is currently available only in Run mode, not in Debug.
System.exit(0)
add this line in your code. Debug from here onwards

How can I "capture" System.exit(-1) from different thread?

I have the following
System.setSecurityManager(new SecurityManager() {
#Override
public void checkExit(int status) {
super.checkExit(status);
//custom exception extends SecurityException
throw new SystemExitCalledException();
}
});
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
//never reaches here somehow...
//maybe some3rdPartyStaticMethod sets this, too?
}
});
try {
//this method spawns threads and some call System.exit().
some3rdPartyStaticMethod.invoke(null, new Object[]{args});
} catch (SystemExitCalledException e) {
//it never reaches here because
//SystemExitCalledException is thrown on different thread??
//
}
Is there a way to prevent some3rdPartyStaticMethod's spawned thread's System.exit() call from halting jvm?
You can start the code in a separate process and communicate with it using RMI. If the third party code calls System.exit and kills its process, your process can continue to run and recreate the child process if necessary.
Note that there are some caveats with this approach:
The two processes don't share the same heap space.
You will need to marshal all data that is passed between the two processes. This means that the data must be serializable.
There will be a considerable overhead for every method call. This may give performance problems if you need to make many calls per second.
Writing a custom SecurityManager policy should help -- I've never done this myself :)
According to this post (scroll down to the bottom):
However, when anything in the VM tries to call System.exit(), the VM exits. Since this includes a brutal shotdown of mvn, the normal mvn process is interrupted. A SecurityManager can be used to prevent code from calling System.exit(), but nobody mentions the side-effects.
A colleague of mine mentioned that you can setup your policies system-wide, per-user and as a system-property when starting the VM and after a quick test this has proven to solve my problem. I've since managed to figure out how to set my own policy from my code (before setting up the SecurityManager) and this solves my problems.
I used the following code:
//Setup security to prevent System.exit()
SecurityManager sm = System.getSecurityManager();
URL policy = getClass().getClassLoader().getResource("jsdoc.policy");
System.setProperty("java.security.policy", policy.toString());
System.setSecurityManager(new JSDocSecurityManager(getLog()));
With a simple, wide-open, policy file reading this:
grant {
permission java.security.AllPermission;
};
If it works it supposed to capture the System.exit() request and throw a SecurityException instead

How JMS work in Java?

How does async JMS work? I've below sample code:
public class JmsAdapter implements MessageListener, ExceptionListener
{
private ConnectionFactory connFactory = null;
private Connection conn = null;
private Session session = null;
public void receiveMessages()
{
try
{
this.session = this.conn.createSession(true, Session.SESSION_TRANSACTED);
this.conn.setExceptionListener(this);
Destination destination = this.session.createQueue("SOME_QUEUE_NAME");
this.consumer = this.session.createConsumer(destination);
this.consumer.setMessageListener(this);
this.conn.start();
}
catch (JMSException e)
{
//Handle JMS Exceptions Here
}
}
#Override
public void onMessage(Message message)
{
try
{
//Do Message Processing Here
//Message sucessfully processed... Go ahead and commit the transaction.
this.session.commit();
}
catch(SomeApplicationException e)
{
//Message processing failed.
//Do whatever you need to do here for the exception.
//NOTE: You may need to check the redelivery count of this message first
//and just commit it after it fails a predefined number of times (Make sure you
//store it somewhere if you don't want to lose it). This way you're process isn't
//handling the same failed message over and over again.
this.session.rollback()
}
}
}
But I'm new to Java & JMS. I'll probably consume messages in onMessage method. But I don't know how does it work exactly.
Do I need to add main method in JmsAdapter class? After adding main method, do I need to create a jar & then run the jar as "java -jar abc.jar"?
Any help is much appreciated.
UPDATE: What I want to know is that if I add main method, should I simply call receiveMessages() in main? And then after running, will the listener keep on running? And if there are messages, will it retrieve automatically in onMessage method?
Also, if the listener is continuously listening, doesn't it take CPU??? In case of threads, when we create a thread & put it in sleep, the CPU utilization is zero, how doe it work in case of listener?
Note: I've only Tomcat server & I'll not be using any jms server. I'm not sure if listener needs any specific jms server such as JBoss? But in any case, please assume that I'll not be having anything except tomcat.
Thanks!
You need to learn to walk before you start trying to run.
Read / do a tutorial on Java programming. This should explain (among other things) how to compile and run a Java program from the command line.
Read / do a tutorial on JMS.
Read the Oracle material on how to create an executable JAR file.
Figure out what it is you are trying to do ... and design your application.
Looking at what you've shown and told us:
You could add a main method to that class, but to make an executable JAR file, you've got to create your JAR file with a manifest entry that specifies the name of the class with the main method.
There's a lot more that you have to do before that code will work:
add code to (at least) log the exceptions that you are catching
add code to process the messages
add code to initialize the connection factory and connection objects
And like I said above, you probably need some kind of design ... so that you don't end up with everything in a "kitchen sink" class.
if I add main method, should I simply call receiveMessages() in main?
That is one approach. But like I said, you really need to design your application.
And then after running, will the listener keep on running?
It is not entirely clear. It should keep running as long as the main thread is alive, but it is not immediately obvious what happens when your main method returns. (It depends on whether the JMS threads are created as daemon threads, and that's not specified.)
And if there are messages, will it retrieve automatically in onMessage method?
It would appear that each message is retrieved (read from the socket) before your onMessage method is called.
Also, if the listener is continuously listening, doesn't it take CPU???
Not if it is implemented properly.
In case of threads, when we create a thread & put it in sleep, the CPU utilization is zero, how doe it work in case of listener?
At a certain level, a listener thread will make a system call that waits for data to arrive on a network socket. I don't know how it is exactly implemented, but this could be as simple as an read() call on the network socket's InoutStream. No CPU is used by a thread while it waits in a blocking system call.
This link looks like a pretty good place with examples using Oracle AQ. There's an examples section that tells you how to setup the examples and run them. Hopefully this can help.
Link to Oracle Advanced Queueing

Categories

Resources