Programmatically access exit status from shutdown hook - java

Wondering how to programmatically access the exit status in System.exit from a shutdown hook? Different types of shutdowns need to lead to different logics in my application (how "hard" to shutdown), there's a few ways I'm thinking of doing this but this would be the simplest.

Check out the question I linked if you're really set on this. However, you shouldn't need to access the code from the hook. When you set the exit code, you know exactly which "type" of shutdown you need. It's possible to dynamically specify the shutdown behavior at that time. Instead of registering your shutdown hook(s) at the beginning of execution and then doing this:
startShutdown(int code) {
System.exit(code);
}
You could do something along these lines:
private Map<Integer, Thread> shutdownHandlerLocator; // initialize this on startup with all of the exit codes and their corresponding handlers
startShutdownTypeA(int code) {
Runtime.getRuntime().addShutdownHook(shutdownHandlerLocator.get(code));
System.exit(code);
}
This basic approach can be modified to fit the design needs of your project and the complexity of your teardown logic. There's opportunity to apply inheritance. You could also create a number of very small and specific hooks and register them individually depending on the behavior you need (recommended). The possibilities are really endless and without knowing the exact details of what you're trying to do it's difficult to recommend a more specific design.
Now this is all well and good, but here's the thing- teardown is supposed to be as minimal as possible, because execution is in a fairly fragile state when your shutdown hooks are running. If you're finding that you need really complicated behavior, you may want to reexamine your overall design.
I should also probably mention that there's some memory management implications in using threads in the manner above.

Related

Find out all java code places where a blocking operation happens

In our Netty application. We are moving all blocking calls in our code to run in a special backgroundThreadGroup.
I'd like to be able to log in production the threadName and the lineNumber of the java code that is about to execute a blocking operation. (i.e. sync File and Network IO)
That way I can grep for the logs looking at places were we might have missed to move our blocking code to the backgroundThreadGroup.
Is there a way to instrument the JVM so that it can tell me that?
Depends on what you mean by a "blocking operation".
In a broad sense, any operation that causes a voluntary context switch is blocking. Trying to do something special about them is absolutely impractical.
For example, in Java, any method containing synchronized is potentially blocking. This includes
ConcurrentHashMap.put
SecureRandom.nextInt
System.getProperty
and many more. I don't think you really want to avoid calling all these methods that look normal at a first glance.
Even simple methods without any synchronization primitives can be blocking. E.g., ByteBuffer.get may result in a page fault and a blocking read on the OS level. Furthermore, as mentioned in comments, there are JVM level blocking operations that are not under your control.
In short, it's impractical if not impossible to find all places in the code where a blocking operation happens.
If, however, you are interested in finding particular method calls that you believe are bad (like Thread.sleep and Socket.read), you can definitely do so. There is a BlockHound project specifically for this purpose. It already has a predefined list of "bad" methods, but can be customized with your own list.
There is a library called BlockHound, that will throw an exception unless you have configured BlockHound to ignore that specific blocking call
This is how you configure BlockHound for Netty: https://github.com/violetagg/netty/blob/625f9d5781ed85bfaca6fa4e826d0d46d70fdbd8/common/src/main/java/io/netty/util/internal/Hidden.java
(You can improve the above code by replacing the last line with builder.nonBlockingThreadPredicate(
p -> p.or(thread -> thread instanceof FastThreadLocalThread)); )
see https://github.com/reactor/BlockHound
see https://blog.frankel.ch/blockhound-how-it-works/
I personally used it to find all blocking call within our Netty based service.
Good Luck

Is it safe to let "this" escape in the last statement of a constructor if it has happens-before guarantees?

A common advice in Java is to not to let the "this" reference escape during construction of an object and therefore not start any threads in a constructor. But I find myself writing a lot of classes that should start a thread using an executor. According to the common advice, I should write an extra start() method that submits the task to the executor.
But submitting a task to an executor gives happens-before guarantees as documented here. So would it be fine to submit the task in the last statement of the constructor? Or the more general question: is it safe to let "this" escape in the last statement of a constructor if that statement provides happens-before guarantees?
The Answer by Stefan Feuerhahn is correct.
I’ll add the suggestion that embedding an executor service within the class performing the work can be a “code smell”, an indication of weak design.
Generally we want to follow the single responsibility principle in our designs. A class should have a single purpose, and should try not to stray from that narrow specific purpose.
If, for example, a class were written to create a report, that class should know only about that report. That class should not know about when that report should be run, or how often to run the report, or what other code cares about if the report has been run.
Such scheduling of when to run the report is tied to the lifecycle of the app. For one important thing, the executor service must eventually be shut down when no longer needed or when the app is exiting. Otherwise the backing thread pool may continue indefinitely like a zombie 🧟. Your report-generating class should not know about when it is no longer needed, nor should it know about when or why the app is exiting.
Another aspect of the issue is that configuring an executor service involves knowing about the deployment scenario. How much RAM, how many CPU cores, how much other burden on that host machine, all contribute to decisions about how to set up the executor service(s). Your report-generating code should not have to change because of changes to your deployment situation.
The report-generating class should not know anything about the calling app’s lifecycle, not know anything about the executor service. The report-generating app should know nothing more than how to generate that one report. Some other place in your code, perhaps some report manager class or your app’s lifecycle orchestration code, should handle how often and when to run the report.
Yes, this is safe, because the statement providing happens-before guarantees will make sure all fields are correctly initialized visible to other threads. One caveat is that a subclass could ruin this safety so its better to make the class final. But, as Holger pointed out, even then an additional constructor delegating to the one that started the thread could harm safety.
The general advice "don't let this escape from the constructor" exists mainly because it is easier and thus less error prone to follow this rule then to keep all nuances in mind (like subclassing).

What's is scope of setSecurityManager in Java?

I would like to enforce security manager for execution some 3rd party libraries classes, so I do something like that:
SecurityManager original = System.getSecurityManager();
System.setSecurityManager(for3rdOne);
try {
thirdparty.doStuff();
} finally {
System.setSecurityManager(original);
}
So far, so good, the code works perfectly limiting 3rd parties to certain constraints. However I have several doubts I can't find answer:
What if I execute this code in several threads, so if setSecurityManager has global scope then returning original security manager will open breach for 3rd party?
if setSecurityManager has scope of only current thread, do I need to worry to return original security manager if my thread ends after calling 3rd party?
Second doubt has certain trick for example new security manager for3rdOne doesn't allow calling setSecurityManager , so I need to do some action to allow it after my sand-boxed code exited.
setSecurityManager has global scope, so the simplest solution is to setSecurityManager(for3rdOne) once and forever. If, however, some parts of your code should be executed under different security policy, then that code should synchronize with third party code. One solution is to start a special thread with input queue, which executes all the code sensitive to security policy. The thread can be considered as a single-threaded executor, but for a special class of tasks: each task has a property securityManager which is examined and used to call to setSecurityManager before the task is executed.
If there are too much of security-sensitive code and single thread becomes a bottleneck, more sophisticated solutions can be elaborated, but I believe there is no universal solution, more information required to give an advice. Most parallel solution is to use separate JVM for each kind of security manager, but this may be inappropriate because of large amount of data floating between processes.
Update
the easiest way to differentiate security policy for different callers is to assign different permissions to different threads - because it is easy to determine current thread, and then determine its type (class or interface). Another way is read current context with SecurityManager.getSecurityContext(), scan it and check if there are classes with restricted capabilities.
You can have a look at ProtectionDomain and CodeSource. These allow you to setup different permission based on package names or originating code URL.

Java - how to stop a thread running arbitrary code?

In my application which runs user submitted code[1] in separate threads, there might be some cases where the code might take very long to run or it might even have an infinite loop! In that case how do I stop that particular thread?
I'm not in control of the user code, so I cannot check for Thread.interrupted() from the inside. Nor can I use Thread.stop() carelessly. I also cannot put those code in separate processes.
So, is there anyway to handle this situation?
[1] I'm using JRuby, and the user code is in ruby.
With the constraints you've provided:
User submitted code you have no control over.
Cannot force checks for Thread.interrupted().
Cannot use Thread.stop().
Cannot put the user code in a process jail.
The answer to your question is "no, there is no way of handling this situation". You've pretty much systematically designed things so that you have zero control over untrusted third-party code. This is ... a suboptimal design.
If you want to be able to handle anything, you're going to have to relax one (or preferably more!) of the above constraints.
Edited to add:
There might be a way around this for you without forcing your clients to change code if that is a(nother) constraint. Launch the Ruby code in another process and use some form of IPC mechanism to do interaction with your main code base. To avoid forcing the Ruby code to suddenly have to be coded to use explicit IPC, drop in a set of proxy objects for your API that do the IPC behind the scenes which themselves call proxy objects in your own server. That way your client code is given the illusion of working inside your server while you jail that code in its own process (which you can ultimately kill -9 as the ultimate sanction should it come to that).
Later you're going to want to wean your clients from the illusion since IPC and native calls are very different and hiding that behind a proxy can be evil, but it's a stopgap you can use while you deprecate APIs and move your clients over to the new APIs.
I'm not sure about the Ruby angle (or of the threading angle) of things here, but if you're running user-submitted code, you had best run it in a separate process rather than in a separate thread of the same process.
Rule number one: Never trust user input. Much less if the input is code!
Cheers
Usually you have a variable to indicate to stop a thread. Some other thread then would set this variable to true. Finally you periodically check, whether the variable is set or not.
But given that you can't change user code , I am afraid there isn't a safe way of doing it.
For Running Thread Thread.Interrupt wont actually stop as sfussenegger mentioned aforth (thanks sfussenegger recollected after reading spec).
using a shared variable to signal that it should stop what it is doing. The thread should check the variable periodically,(ex : use a while loop ) and exit in an orderly manner.
private boolean isExit= false;
public void beforeExit() {
isExit= true;
}
public void run() {
while (!isExit) {
}
}

Poor JUnit test using springframework has fragile Thread.sleep() calls. How to fix?

I have recently joined a group with some severe JUnit testing issues. One problem is an 8 minute long test! The test has several sections; each makes calls to org.springframework.context.ApplicationEventPublisher.publishEvent()
followed by Thread.sleep() of various amounts of time, then tests conditions.
There are several obvious problems with this approach, the timing of the Thread.sleep() calls is fragile:
tests occasionally fail on busy machines; and
tests take far too long when they do not fail.
Is the pool upon which these events are handled accessible for testing and is there a call to see if the event cascade has quiesced?
Worth mentioning is that test code that actually calls external services are integration tests and not unit tests. If you're truly unit testing here you should replace those calls with mocks. That way you can better control the values returned to your business logic and test for specific conditions. Also, as you've seen, this all but eliminates false positives due to external (non-code) situations. Obviously these tests aren't failing, the facility they expect to use is.
You can overwrite the default applicationEventMulticaster by adding this bean id to your application context.
Instead of the default SimpleApplicationEventMulticaster, you could set a TaskExecutor on this bean to perform the event publishing asynchronously in multiple threads.
Or you could implement your own multicaster, which prints out which event listener took so long or was blocking, for how long and on which events. That could help you to track down the real problem of the 8-Minute-Testcase.
Interestingly, the JavaDoc of the SimpleApplicationEventMulticaster, which is used by default by Spring when you are using ApplicationContext, states the following:
By default, all listeners are invoked in the calling thread. This allows the danger of a rogue listener blocking the entire application, but adds minimal overhead. Specify an alternative TaskExecutor to have listeners executed in different threads, for example from a thread pool.
I (intentionally) avoid Spring so I'm not sure I can help with the specifics but just looking at the sleep issue, you can use something like WaitFor in tempus-fugit (shameless plug) to poll for a Condition rather than "sleep and hope". It's not ideal and usually a change in the way you test (as suggested before) is preferable but it does mean you get finer grained "waits" which are more likely to avoid race-conditions / flaky tests and generally speed up the test.
See the project's documentation for details and post back if you find it useful!

Categories

Resources