Passing a signal from a .NET app to a Java app - java

I need to pass a signal from a .NET app to a Java app. No data is required, the signal itself is enough.
The most simple way that comes to my mind is by using a named synchronization object like this:
The .NET app creates a certain named synchronization object A.
The Java app creates a certain named synchronization object A - the name is the same as in (1).
The Java app has a thread waiting on the object to become signaled.
The .NET app signals the object.
The Java app thread awakens and acts upon the signal reception.
At least, this how I would do it if I knew how to create a named synchronization object in Java.
But looks like Java does not have any, which I find hard to believe. Does it mean that only Windows has named synchronization objects?
So, my question is this - how do I pass a simple signal (no data) from a non Java app to a Java app on Windows? Both processes run on the same host.
EDIT
Motivation - I want to signal to our headless Java process to terminate itself gracefully as soon as it can do so.

you can create a socket connection between your programs, and by send and receive specific pattern you can detect signal

I second thought, that i had done before by using ICE Framework, you can download and learn the ICE Framework from here,
ICE Framework is a cross framework for communication between processes a local system or on a network.
Download Ice Framework

For God's sake, I just want a single 1 bit signal from a C++/C# process to a Java process and there is no simple way to do it. I can't believe it.
Forget about it, I'll just use the file system. The C++/C# code is going to create an empty file at a well known location, which the Java code is going to poll every second.
Finito, end of story.

Related

How it is possible for JVM, to react on user's requests

Let's take spring application that is embedded in some tomcat container for example. I know that spring uses servlets under it's mask but I want to understand how it works internally, from JVM point of view. What communicates directly with JVM?
Standalone "static" application case is simple because code is compiled once, bytecode is interpreted by JVM/compiled by JIT, class are loaded and there is no interaction with the outside world - we can say that application is "invoked once" when started.
But when it comes to application that can have some interaction with user and so on, running in loop, using i.e. spring, how JVM knows that some methods were invoked by requesting i.e. "localhost:8080/users"? JVM is listening on some port? Reading from socket? Which component is responsible for it?
I would be very grateful for writing the whole path from the start of the application, user request to the interaction with JVM and what is happening on it.
First, your question is very broad and not suitable for StackOverflow.
In short, the JVM is no special from any other operating system process here. You (or your vendor) writes a Java/C/Go/Python/whatever code which listens on a socket.
When an incoming network request comes, the operating system "notifies" the process (your running program) that there are new data so it can interpret it and react in whatever way it wants (such as saving user data into a database and returning a proper response).
The Java/JVM code for interacting with operating system specific facilities like sockets are written in native code (that is C/C++) and provided by JVM to your Java program via wrappers ("native methods").
As an example there's an internal PlainSocketImpl.java class with a bunch of native methods implemented in the corresponding PlainSocketImpl.c native code: https://github.com/AdoptOpenJDK/openjdk-jdk14/blob/master/src/java.base/unix/native/libnet/PlainSocketImpl.c
(e.g. the socketAccept implementation: https://github.com/AdoptOpenJDK/openjdk-jdk14/blob/master/src/java.base/unix/native/libnet/PlainSocketImpl.c)
I suggest you find a good resource on general socket programming; you may find these useful:
https://docs.oracle.com/javase/tutorial/networking/sockets/index.html
https://www.tutorialspoint.com/java/java_networking.htm

Sending a unix signal to a scala application [duplicate]

I'm using a custom signal handler to catch TERM, ABRT and INT signals in a custom java daemon. I have this handler in the code so that I can send TERM signals to it and gracefully shutdown the program via the kill command. The signal handler works right now, but when I compile the code I'm receiving the following warning (many times over):
warning: sun.misc.SignalHandler is Sun proprietary API and may be removed in a future release
while using these classes:
import sun.misc.SignalHandler;
import sun.misc.Signal;
Is there a better way to send signals to a running JVM to initiate a shutdown of the main thread? I don't like having my code tied to this API when it could be removed in the future.
This code works on Solaris and HPUX today using 1.5.0_22 JVM. Any help or suggestions would be much appreciated. I used this document, from IBM, to develop the signal handler:
http://www.ibm.com/developerworks/java/library/i-signalhandling/
First of all, understand that this is just a standard warning for sun.misc package. They're letting you know that the API you're using is not a standard Java API. It doesn't mean that they're actively planning to remove this API in the future. http://java.sun.com/products/jdk/faq/faq-sun-packages.html
As far as your question, it's not quite clear to me why the default way java process handles kill signals is not sufficient for you: How to stop java process gracefully?. If you need to add additional logic, you can add a shutdown hook.
Still, If you're looking for other ways to let your java process know it's time to exit, you can have it listen on a socket, or stdin, or a named pipe...
You might also want to look into JVMTI
You could do this via JMX.
JMX is a standard set of apis that can be used to monitor and manage java applications.
Here are some links to get you started :
http://onjava.com/pub/a/onjava/2004/09/29/tigerjmx.html
http://www.ibm.com/developerworks/java/library/j-jtp09196/index.html?ca=drs
The main idea is this :
a) You will have a boolean variable, say isShutDownTrigerred. You will have a thread that will run a infinite loop, sleep for 2s, and keeps checking this variable value. When the value is true, you will execute code that will shutdown the application.
b) Then you write a mxbean (check the links above). This mxbean will be used to change the "isShutDownTrigerred" value to true. You can use a tool like jconsole /jManage to see and modify the mxbeans of a java application. As soon as the "isShutDownTriggered" is set to true, the above thread is going to know it and will execute the shutdown of the application

Is this a good design for Java and C/D to communicate?

I have a java program where certain parts are computationally intensive.
I wish to make that part (which essentially generates an image according to some text data) in C/D.
(Multiple instances of the C program might be running at the same time).
Now, I want to be able to track the progress of the C/D program, so the java code
needs to read the status (progess, errors) of the C/D program somehow.
My idea is to use the environment variables in the OS, to store the status, "TIME_LEFT=2h10m42s" sort of.
Questions:
Is this a good idea, or is there something really bad about this design?
Are there some alternatives, (using sockets, stdin/stdout, other)?
EDIT: The Java works as a front-end, so the C/D code should NOT include anything specifically written for Java. The C/D code is essentially a stand-alone program, Java (or other) provides with GUI.
You cannot use environment variables for this, as you cannot communicate environment variables to another program by other than setting it before you start a new process. So you can't run a C program that changes environment variables that your parent java program can see.
Write line based status to stdout in your C (or D) program rather and read it in your java program.
Using environment variables is a bad idea. Environment variables are inherited by new running processes. They aren't register-type variables that you can just pump and access from any process, so to speak :) You could use JNI and keep checking the time remaining in MS on the Java side, or have the C/D code poll the Java code with the time remaining in its loop (I prefer the other way, however).
Well you can do the other way around .From Java to poll the status of execution.On each 5 seconds to call via JNI the status (progress) of the heavy execution.
I agree with Chris Dennett that this is a bad idea. I would avoid JNI - it is a terrific way to introduce subtle bugs that crash your JVM.
I would implement this by creating a C/D HTTP server running on the local host. The server accepts a POST request to /image/ to start creating the image, a long running process. That POST request returns immediately with a token. I would then GET /image/token which would return either the progress information or the image, depending on if it is done or not. Your Java process can then poll the GET /image/token URL.
Instead of using environment variable use JNA. It is easier than JNI and reliable method to communicate with the program. Another approach is you use Message Queue like ActiveMQ for which C API also available and this is open source. It will decouple the application.

Reliable non-network IPC in Java

Is there a reliable, cross-platform way to do IPC (between two JVMs running on the same host) in Java (J2SE) that doesn't rely on the network stack?
To be more specific, I have a server application that I'd like to provide a small "monitoring" GUI app for. The monitor app would simply talk to the server process and display simple status information. The server app has a web interface for most of its interaction, but sometimes things go wrong (port conflict, user forgot password) that require a local control app.
In the past I've done this by having the server listen on 127.0.01 on a specific port and the client communicates that way. However, this isn't as reliable as I'd like. Certain things can make this not work (Windows's network stack can be bizarre with VPN adapters, MediaSense, laptops lid closing/power saving modes). You can imagine the user's confusion when the tool they use to diagnose the server doesn't even think the server is running.
Named Pipes seem plausible, but Java doesn't seem to have an API for them unless I'm mistaken. Ideas? Third party libraries that support this? My performance requirements are obviously extremely lax in case that helps.
One of my specialties is really low-tech solutions. Especially if your performance requirements aren't critical:
The low-low tech alternative to named pipes is named FILES. Think yourself up a protocol where one app writes a file and another reads it. If need be, you can do semaphoring between them.
Remember that a rename is pretty much an atomic operation, so you could calmly write a file in some process and then make it magically appear in its entirety by renaming/moving it from somewhere that wasn't previously visible.
You can poll for data by checking for appearance of a file (in a loop with a SLEEP in it), and you can signal completion by deleting the file.
An added benefit is that you can debug your app using the DIR command :)
Depending on how much data you need to pass between the server and the diagnostic tool you could:
go low-tech and have a background thread check a file in the file system; fetch commands from it; write ouput into a second to be picked up by the diagnostic tool.
build a component that manages an input/output queue in shared memory connecting to it via JNI.
Consider JMX. I do not know if any of the Windows JVM's allow JMX over shared memory.
Does Windows even have named pipes? I was going to suggest it. You'd just have to use an exec() to create it.
Map a read_write byte buffer into memory from a FileChannel. Write status information into the byte buffer, then call force() to get it written out. On the monitor side, open up the same file and map it into memory too. Poll it periodically to find out the status.

In a Java thread running as root, how can we apply Unix rights specific to a logged-in user?

We have a Java program run as root on Unix, that therefore can read for example the content of the folders /home/user1 and /home/user2. However, if the Unix user "user1" is logged in in our application, he should not be able to access "/home/user2" data.
We would like to use directly the Unix rights and not recreate all the permissions in our application !
So, could we...
try to change the UID of our
program depending on the user logged
in ? Sounds difficult, and each file
access is in different threads so
the UID would be different on each
thread of our program...
use JNI to read permissions of
"/home/user2"...And then determine
if user1 has sufficient permissions
on "/home/user2" ? (how ?).
Use SecurityManager!
Put current unix user id into ThreadLocal
Create your own SecurityManager that checks unix user permissions on checkRead() and checkWrite()
System.setSecurityManager(new MySecurityManager())
Enjoy
Update
There is no, of course, standard library to read unix file permissions. It's not WORA.
But I have tried briefly to find a ready to use library, and found this one:
http://jan.newmarch.name/java/posix/ It uses JNI, but you don't need to write your own JNI code, which is a big relief. :) I'm sure there must also be others.
Class Stat from there gives you all required access information:
http://jan.newmarch.name/java/posix/posix.Stat.html
Update 2
As folks mentioned, this approach fails to check for "non-standard" unix security features, such as ACL or Posix Capabilities (may be; not sure if they apply to files). But if the goal of being totally in sync with host OS security is set, then we even more need to use SecurityManager, because it's a JVM-wide protection mechanism! Yes, we can start a child SUID-process to verify the permissions (and keep it running, talking to it via pipe running while the user is logged in), but we need to do so from SecurityManager!
The simplest and most portable way would be to spawn a child process, have it exec a wrapper written in C which changes the UID, drops all the privileges (be careful, writting a wrapper to do that is tricky - it is as hard as writing a setuid wrapper), and execs another java instance to which you talk via RMI. That java instance would do all the filesystem manipulation on behalf of the user.
For single-threaded Linux programs, you could instead use setfsuid()/setfsgid(), but that is not an option for portable or multithreaded programs.
if you only want the app to be allowed to read files by user1 i strongly suggest the app runs as user1.
If everything else fails, you can run a shellscript from java and parse the result.
Described for example here
For those who were wondering, it's apparently not possible to do this by calling setuid with JNI for each independent thread. setuid affects the whole process, not just the thread that invoked it.
Should you want to call setuid within a single-threaded Java program there's a good example at http://www2.sys-con.com/itsg/virtualcd/Java/archives/0510/Silverman/index.html.
Another option would be to invert the approach: instead of the code running as root most of the time and either changing the user ID or somehow checking the permissions whenever it has to use some restricted resource, run as the user most of the time and talk to a smaller daemon running as root when it needs to do something only root can do. This also has the added benefit of reducing the attack surface.
Of course, you then have to authenticate the connection from the process running as the user to the process running as root.
I am also having the exact problem as Mikael, and got to this page looking for answers.
None of the answers are 100% satisfactionary for me. So I am thinking of 4 alternatives:
Use a Linux group that has access to all the users. Run a single Java app under that group. This Java app can communicate to the 'root' app using whatever means.
Potentially, it can be "hotel"-ed. e.g. 1 "hotel" (app with group permissions) per 100 users (or as appropriate). So if you have 10,000 users you need 100 hotels, which is quite manageable.
Spawn a JVM for each child app under its own user ID. This is like calling a script, but rather than using stdin/stdio/stderr, use any communication protocol. In my case, I'm using XMPP and IO Data (which, since it's already in use by other components, it doesn't matter "where" aka which JVM it runs).
Create a Super-Server 'root' app. This can be part of the original 'root' app or a separate service dedicated to service management.
The Super-Server is responsible for handling incoming requests (i.e. it practically becomes a reverse proxy) for the user-specific sub-apps, and launching the real child apps (if they're not running already), and passing messages back and forth between the client and the child app(s).
Additionally, the child apps can be pooled (or even "passivated", if there's such thing), much in the way Java EE EJB Container does it. So even if there are 10,000 users and (potentially) 10,000 child apps servicing, the maximum number of child apps running are capped. Idle apps are shut down to make room for others.
Same as #3 but rather than creating a proprietary service management mechanism, integrate with Upstart (or the service management framework in the underlying OS). i.e. there is a 'root' service that can control Upstart. Upstart can start, stop, restart, can query the status of the child services, just like it can control mysqld, Apache, etc.
For me, now, the quickest and simplest to implement would be #1. However, my ideal solution would be #4, but it will take time and testing whether it works well. (the concept itself borrows from inetd/xinetd and EJB, so I think it's pretty sound fundamentally)

Categories

Resources