Your project depends on undefined behavior.
Any signal handler can safely make calls only for asynchronous signals. Any other function call causes undefined behavior. Relying on the Java / Dalvik / ART virtual machine to limit itself to being safe for asynchronous signals, function calls in any situation are unrealistic at best and most likely simply incorrect.
Your handler for an arbitrary signal can be called at any time, leaving the VM in any possible state. It is not possible to make Java calls safely from the JNI signal handler, and it is unreasonable to expect anyone to even try to support such calls - as virtual machine developers would allow the signal to interrupt any synchronized method if the signal handler were allowed to make synchronized calls on the same object? If they did, they would violate the language, violating the very meaning of synchronized . But if they did not, they will allow blocking, since such calls will try to block an object that can never be unlocked, because signal processing is interrupted.
In short, Java calls through JNI from a signal handler are fundamentally unacceptable.
The fact that they worked for you only gave you hope that they would continue to do so.
You're lucky in the past.
It no longer works, and you cannot expect it to work in the future.
And even if you somehow hack it into work, you are still fundamentally unfounded. The only calls that can be safely made from a signal handler are beyond the POSIX standard :
The following table defines a set of functions that should be either reentrant or not interrupted by signals and an asynchronous safety signal. Therefore, applications can refer to them without restriction, from signal capture functions:
_Exit() _exit() abort() accept() access() aio_error() aio_return() aio_suspend() alarm() bind() cfgetispeed() cfgetospeed() cfsetispeed() cfsetospeed() chdir() chmod() chown() clock_gettime() close() connect() creat() dup() dup2() execle() execve() fchmod() fchown() fcntl() fdatasync() fork() fpathconf() fstat() fsync() ftruncate() getegid() geteuid() getgid() getgroups() getpeername() getpgrp() getpid() getppid() getsockname() getsockopt() getuid() kill() link() listen() lseek() lstat() mkdir() mkfifo() open() pathconf() pause() pipe() poll() posix_trace_event() pselect() raise() read() readlink() recv() recvfrom() recvmsg() rename() rmdir() select() sem_post() send() sendmsg() sendto() setgid() setpgid() setsid() setsockopt() setuid() shutdown() sigaction() sigaddset() sigdelset() sigemptyset() sigfillset() sigismember() sleep() signal() sigpause() sigpending() sigprocmask() sigqueue() sigset() sigsuspend() sockatmark() socket() socketpair() stat() symlink() sysconf() tcdrain() tcflow() tcflush() tcgetattr() tcgetpgrp() tcsendbreak() tcsetattr() tcsetpgrp() time() timer_getoverrun() timer_gettime() timer_settime() times() umask() uname() unlink() utime() wait() waitpid() write()
All functions not listed in the table above are considered unsafe with respect to signals. If there are signals, all functions defined by this IEEE Std 1003.1-2001 volume must behave as defined when a signal capture function is called or interrupted, with one exception: when a signal interrupts an unsafe function and a signal- catching function calls an unsafe function, the behavior is undefined .
Since you can never guarantee that calling Java through the JNI from a signal handler will only make calls that are protected from asynchronous signals, you can never expect anything other than undefined behavior.