I'm wondering if it's possible to run a .exe from A web-server using the domain name as parameter.
It's working fine using a network shared folder
Process x = new ProcessBuilder("http://example.com/MAJ.exe","param1","param2").start();
Absolutely not. The javajavadoc is straight forward:
Constructs a process builder with the specified operating system program and arguments. This constructor does not make a copy of the command list. Subsequent updates to the list will be reflected in the state of the process builder. It is not checked whether command corresponds to a valid operating system command.
That constructor takes a command and arguments to that (as strings). It doesn't take a URL. It is as simple as that. This interface is intended to run a command that exists in the local machine, file system.
Also note the major conceptual flaws here:
what does it mean to run an EXE that lives on a server?
do you want to download it and run it locally?
or should the server invoke it? In what context? Where would the results go?....
So, the real answer is:
either you should provide a service to download that executable to your local machine, to run it locally
or your wrap that executable into some form of service that you can invoke remotely (like any other restful HTTP(S) service)
Related
I am working on a project using a Raspberry Pi and a web cam to detect motion.
I have got it to a stage whereby it takes an image and saves it on my computer. What I am wondering is, is it possible to let FileZilla automatically upload the image to my webserver when a new image is taken? Or is there any other ways that I could achieve this?
Since the post is tagged java, I'm assuming that you're using a Java program already or have the basic knowledge to create a Java program.
On to the answer: yes, you basically have two options.
1. Upload from within the Java program. FTP is probably the easiest since most web servers will have an FTP server running. Here is a tutorial you can use: http://www.codejava.net/java-se/networking/ftp/java-ftp-file-upload-tutorial-and-example
2. Use another utility outside your Java program to upload the file to your webserver. rsync would be the tool of my choice (tutorial here). When on a Linux machine (for example, the Pi) or a Mac, you can run a script that syncs the content of a local folder to a remote folder every x seconds:
while true; do <rsync command hier> sleep 5s; done
Note that that sleep period shouldn't be too short or you'll end up running multiple instances of rsync.
When on a Windows machine, you need to find another way to run a periodic process to trigger the rsync.
I am wrapping two java programs as services using yajsw (yet another java service wrapper) in order to have them run indefinitely on separate servers. I got one of them to work exactly as I expected (the service is installed on a server, behaves exactly as it does when run from cmd and restarts anytime it or the server goes down). However, when I do this with the second java project it does not work. It gets installed as a service and will run, but when it tries to run a powershell script (something the first project does not do) from within java, using ProcessBuilder(), it starts and powershell.exe shows up in task manager, but never closes or produces any of the expected side effects. Both things that work seamlessly when I run the .jar from the command line. Is there something different about the environments that services/processes run in that would explain this?
Update:
Within the script I have the following line:
$outlook = new-object -com outlook.application;
The problem is that $outlook is null after this and the script then fails to parse any emails resulting in no output. What about wrapping the java program as a service would mess up the creation of an outlook application object?
Q. Is there a way to have a java program run twice on a mac like on windows?
You do not specify if you want to start a simple .jar or an application-bundle so I will give examples for both. To run multiple instances of an application-bundle on OS X, you can use the following trick; open the Terminal and start the application with this command:
open -n /path/to/your/java.app
Each time you call this command, a new instance is opened up.
Attention: Just because it is possible to start several instances does not mean it is a good idea to do so. Make sure you will not run into trouble with concurrent write-access of multiple instances with the same file.
If you are trying to run a jar, you can simply call
java -jar /path/to/your/java.jar
several times to start up several instances.
To start up the java-application from inside a java-application under OSX, you have to do something like this:
In the case of a simple jar:
File jarFile = new File("/path/to/your/jarFile.jar");
Runtime.getRuntime().exec(new String[] { "java", "-jar", jarFile.getAbsolutePath() });
In the case of an application bundle:
File jarFile = new File("/path/to/your/jarFile.app");
final String[] command = { "open", "-n", jarFile.getAbsolutePath() };
Runtime.getRuntime().exec(command);
I don't really understand the problem. But why don't you abstract it to a method instead of naming it program and call that subroutine twice. Or spawn two threads?
Maybe this is a trick question, but I would open up two terminal windows and run it once on each terminal...
This depends on the nature of your Java program. If your program is running as both server and client, it may cause the problem when your run multiple instances. In many server program, it uses a fixed port number to simplify the setting and implementation. Since a given port number cannot be use by more than one application, you cannot open more than one instance of that application unless you can change the port number in your application settings.
Many Java application uses this trick to prevent user to open multiple instances of their program by checking if a certain port is in use. If this the case, then you cannot run more than one instance of the program.
For other Java application that do not use port or ports do not crash, you can open it twice or more via the terminal.
Assuming that you are running client version of the code on your system and trying to connect to a host. First you need to have the server running on both the machines, B and C in your case. Secondly the client code you are using should be reading the IP address and port to connect. It should not be hard coded or else you will have to change the code and rebuild it for server B. This should help you.
Guess I have answered your query.
:)
Is there an easy way of passing Linux/Unix commands to Java's args[] during program execution? I would like to use Java app with cron.
The JVM already does that for you:
public static int main(String args[]) {...
In args[] you will have the command line arguments.
If you want more sofistication (as named parameters, v.g. -title = MyTitle), you can try Apache Command Line Interface(CLI) library.
EDIT to answer featon's comment: That will not work, the OS will interpret it as a call to launch a new process. Also, the process name of all java processes is "java" (the OS runs the JVM and does not know what it does in inside).
If what you want is to communicate with a Java process already running, you must open a communication path. Two alternatives are:
Open a TCP port, launch another application (Java or not) that sends the message there.
Have the process periodically listing a directory, if any new file appears wait a while (so it is fully created), open it, read it and delete it.
Another path is getting to use J2EE application server that implement functionalities more oriented to Java process that run continuously (even equivalents to cron tasks), but they take some effort to become familiar with.
If you have command or two pass it within String[] arguments. If you got more commands, consider putting them in some file and only pass the path to that file as a java program argument.
I have a web application that runs as a user www. However at one point it needs to read a file from a Linux filesystem on behalf of users Alice and Bob.
One way of doing this would be to launch a shell (Runtime.exec()) and call a C setuid executable to change userid and read the file.
Is there a way to achieve this with JNI (the web app needs to run as www and not root)? I tried to write a Java JNI program that calls native methods on Linux (I made these native methods owned by root and have setuid bits set). But unless I run the Java program as root, it does not let me switch user ids. Is there something that I am missing? Is there a way to achieve this?
Thanks!
No. There is not. setuid and setgid can only be used in two cases (on ordinary Linux):
The process is root.
The process was launched from a file with the setuid or setgid bits in its modes.
In the former case, the process may call these functions willy-nilly to adopt any identity. In the later case, the process my only switch back and forth between the uid/gid of the parent and the uid/gid of the file it was launched from.
That is, if setuid, it may adopt the uid of the file, if setgid, the gid.
Since you are in java, the exec-ed program is java itself, and you don't want that to be setuid or setgid, not unless you want to create a colossal security exposure.
You could write a C or C++ program that started the JVM via the JNI invocation interface, and set that program to be setuid or setgid, and then JNI code invoked in there could make the appropriate calls to switch.
Yep, it's possible. You can see an example here:
https://github.com/kebernet/pretty/blob/master/src/main/java/com/reachcall/util/SetUID.java
Here's example of the code:
CLibrary INSTANCE = (CLibrary) Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"), CLibrary.class);
public static int setuid(int uid) {
if (Platform.isWindows()) {
return OK;
}
return CLibrary.INSTANCE.setuid(uid);
}
bmargulies's answer is not correct (or not quite correct).
A non-root process in UNIX can set uid or gid, if it has respective capabilities:
http://man7.org/linux/man-pages/man7/capabilities.7.html
CAP_SETUID
Make arbitrary manipulations of process UIDs (setuid(2),
setreuid(2), setresuid(2), setfsuid(2));
Since from OS prospective, your program is running as "java" process, this setguid capability must be enabled for the java executable itself:
$ sudo setcap cap_setuid,cap_setgid+ep /usr/java/latest/bin/java
Also notice that filesystem where java executable resides, isn't mounted with "nosuid" option.
Back to your original question
the web app needs to run as www and not root
Normally it's not a good idea to let web service to have a setuid capability.
It's better to drop uid in a shell wrapper script that starts up your web application.