I am writing a Java program that feeds data into the git fast-import function. Currently, I know all my formatting works and conforms to https://git-scm.com/docs/git-fast-import#_signals However, my problem is sending the final "kill" command: SIGUSR1.
I get things to work right now by running this command type fast-import.script | git fast-import. That fact that this works tells me my formatting and such is proper. But, I know there is a way to continuously run git fast-import and feed commands into its standard-input, but the very last command has to be SIGUSR1
Without sending a SIGUSR1 the fast-import utility doesn't know to end. I have tried a few things:
1- Destroying the process using regular Java Process API commands such as
fastImportProcess.destroyForcibly();
2- Use a Java library WinProcess (Maven) to find the pid and kill it.
WinProcess wp = new WinProcess(fastImportProcess);
wp.killRecursively();
That didn't work either. And I tried combinations of things related to the Java Process API and the WinProcess API, etc. Although I can get WinProcess to force the fast-import utility to shut down, it doesn't actually create my commits.
3- Lastly, endlessly research what SIGUSR1 is and all I can come up with is SIGUSR is some kind of user-defined signal. C- what exactly is SIGUSR1 syntactically Not too helpful.
I don't think this issue is Java related per-se, its really about how to use git fast-import. I notice when I run fast-import in the CLI, when I press ctrl-c the commits execute. But I don't know exactly how to do this in Java.
Related
I built a GUI in JavaFX with FXML for running a bunch of different Python scripts. The Python scripts continuously collect data from a device and print it to the console as it's collected in a loop at anywhere from around 10 to 70 Hz depending on which script was being run, and they don't stop on their own.
I want the end-user to be able to click a button on my GUI which launches the scripts and lets them see the output. Currently, the best I have done was using Runtime.exec() with the command "cmd /c start cmd /k python some_script.py" which opens the windows command prompt, runs python some_script.py in it, and keeps the command prompt open so that you can see the output. The problem with this is that it only works on Windows (my OS) but I need to have universal OS support and that it relies on Java starting an external program which I hear is not very elegant.
I then tried to remedy this by executing the python some_script.py command in Java, capturing the process output with BufferedReader, creating a new JavaFX scene with just a TextArea in an AnchorPane to be a psuedo-Java-console and then calling .setText() on that TextArea to put the script output in it.
This kinda worked, but I ran into many problems in that the writing to the JavaFX console would jump in big chunks of several dozens of lines instead of writing to it line by line as the Python code was making Print() calls. Also, I got a bunch of NullPointerException and ArrayIndexOutOfBoundsException somewhat randomly in that Java would write a couple of hundred lines correctly but then throw those errors and freeze the program. I'm pretty sure both of these issues were due to having so much data at such high data rates which overflowed the BufferedReader buffer and/or the TextArea.setText() cache or something similar.
What I want to know is what approach I should take at this. I cannot migrate the Python code to Java since it relies on someone else's Python library to collect its data. Should I try to keep with the pseudo-Java-console idea and see if I can make that work? Should I go back to opening a command prompt window from Java and running the Python scripts and then add support for doing the same with Terminal in Mac and Linux? Is there a better approach I haven't thought of? Is the idea of having Java code call Python code and handle its output just disgusting and a horrible idea?
Please let me know if you would like to see any code (there is quite a lot) or if I can clarify anything, and I will try my best to respond quickly. Thank you!
My solution was to still call the Python code from the Java Processbuilder, but use the -u option like python -u scriptname.py to specify unbuffered Python output.
I have a process running using Systemctl, configured it with Restart=always
so that even if process crashes then it will restart by itself without manual intervention. When that process restarts I want to take some action in my java code. I don't want poll the process. is there anyway to achieve this?
Thanks in advance.
systemd has a D-Bus API that you can use to receive event notifications when a unit changes state, including changes to its ActiveState property that tells you whether it's currently running. See this answer on Unix & Linux StackExchange for more information.
To use this API from a Java program, you'll need a D-Bus library for Java. It looks like there's a DBus-Java library, though it hasn't been updated in a long time. Alternatively, you might be able to have your Java program invoke the command-line dbus-send and/or dbus-monitor programs and read their output.
I executed a Java program from the command line in terminal app A. I want to move the console to terminal app B without having to exit and re-execute the program.
I can think of a few potential ways to solve this, ranging from:
A) In Java implement a new InputStream and OutputStream that somehow can be wired to a new process started in terminal app B.
...to
B) Find a way to put the main Java process in terminal app A in the "background" so that original process can be reopened in a terminal app B.
Ideally, I want to be able to "log in to" and "log out of" my Java process from any terminal on my computer. Has anything like this already been accomplished, and which approach would be best to make it myself? I am open to solutions that involve Java code, shell scripts, or both.
My specs:
OSX: 10.12.4
Usually running zsh on iTerm
If I was using Linux, the perfect solution would be reptyr, a command line tool that allows you to easily switch terminal windows.
On Mac, the best solution I have found is screen. It can also be used to switch terminal windows but must be invoked before running java in order to work and seems a lot more complex.
My Java application has to work like this:
User select bash commands in GUI and press "send."
Application return distinct and independent answers for each command (e.g. we could store them in different files).
Commands each run interactively, not in a batch (it can't be something like "ls\n pwd \n" etc)
After each command, the application will check if the results are ok. If so, it will send the next command.
We need to execute su <user> on the remote host.
This will be a plugin for a bigger app, so answers like "try something else" (i.e. RPC, web services) will not help me :(
As far as i understand i have to use SHELL or at least keep channel connected.
I have tested jsch , sshj and ethz.ssh2 but with bad results.
I've dug throu stackoverflow answers for questions like: "sending-commands-to-server-via-jsch-shell-channel" etc. But they all focus on sending whole commands in one line. I need an interactive, persistent SSH session.
I've used ExpectJ (with a little hack of output stream). It has resolved points 1,3,4,5.
But there is a problem with point 2. In my app I need to get separated answer. But we will not know their length. Command prompts can be different. Anyone knows how to "hack" ExpectJ so it will be some how more synchronized? I am looking for acting like this : send , wait for full answer, send, wait... I've tried some basic synchronization tricks but this end in timeouts and connection lost usually.
You should use ExpectJ, a Java implementation of the Unix expect utility.
not sure if you still have the problems,
in any case, it might contribute to other people.
ExpectJ is indeed the Java implementation of Unix expect.
and you should definitely buy the "explore expect book" then look into it, it is worth it.
For your question:
when you spawn a process, you listen to the return output, match it to a prompt, then send some command.
if you want to analyze the output, you buffer that output, and do some actions before the next send()
to do so, you need to use the interact() method of the spawn class you used.
http://expectj.sourceforge.net/apidocs/index.html
and for interact and how it works:
http://oreilly.com/catalog/expect/chapter/ch03.html
look for this part: "The interact Command"
My Java application has to work like this:
User select bash commands in GUI and press "send."
Application return distinct and independent answers for each command (e.g. we could store them in different files).
Commands each run interactively, not in a batch (it can't be something like "ls\n pwd \n" etc)
After each command, the application will check if the results are ok. If so, it will send the next command.
We need to execute su <user> on the remote host.
This will be a plugin for a bigger app, so answers like "try something else" (i.e. RPC, web services) will not help me :(
As far as i understand i have to use SHELL or at least keep channel connected.
I have tested jsch , sshj and ethz.ssh2 but with bad results.
I've dug throu stackoverflow answers for questions like: "sending-commands-to-server-via-jsch-shell-channel" etc. But they all focus on sending whole commands in one line. I need an interactive, persistent SSH session.
I've used ExpectJ (with a little hack of output stream). It has resolved points 1,3,4,5.
But there is a problem with point 2. In my app I need to get separated answer. But we will not know their length. Command prompts can be different. Anyone knows how to "hack" ExpectJ so it will be some how more synchronized? I am looking for acting like this : send , wait for full answer, send, wait... I've tried some basic synchronization tricks but this end in timeouts and connection lost usually.
You should use ExpectJ, a Java implementation of the Unix expect utility.
not sure if you still have the problems,
in any case, it might contribute to other people.
ExpectJ is indeed the Java implementation of Unix expect.
and you should definitely buy the "explore expect book" then look into it, it is worth it.
For your question:
when you spawn a process, you listen to the return output, match it to a prompt, then send some command.
if you want to analyze the output, you buffer that output, and do some actions before the next send()
to do so, you need to use the interact() method of the spawn class you used.
http://expectj.sourceforge.net/apidocs/index.html
and for interact and how it works:
http://oreilly.com/catalog/expect/chapter/ch03.html
look for this part: "The interact Command"