`I have written a below code for running exe that presently is ran through windows service. I want to call it by java program. But i am getting below error in image. I dont know how to go through installutil or debug this error. Please help me on this.
`
import java.io.*;
public class exec {
public static void main(String[] args)throws Exception {
try {
String cmd = "D://OGLWindowsService//OGL_21052014//OGL_25_Feb_2015//OGLService.exe";
Runtime run = Runtime.getRuntime();
Process pr = run.exec(cmd);
}
catch(Exception ex) {
System.out.println(ex.getMessage());
}
}
}
You actually have the answer for your question in your first screen. windows tells you that this program is designed to be the Service and could not run from the command line. It also suggests that you use insyalutil to set your program as a service and then Windows will run it when it will need it.
Ususally service runs for some events. Most common - user connects to particular port associated with this service (for example port 80) and when such request occurs then Windows starts service progarm (IIS to answer http call) and delegate this request to this new program. Or delegeates it immediately if program is already running.
So, as you can see, Windows is in charge of the service programs. You cannot start them from command line of from another process (that's your example). You can start/stop/restart process manually in the service control window but that's still not command line or your process.
Related
Info about the project: I am creating a C++ console application that manages a Minecraft server by listening to port activity. When server port is pinged, it starts the server and then periodically checks if there are established connections on that port. If none, the server is shut down and app goes into listening mode once again.
The problem arises when the server is stopped. Somehow my main console app is getting killed by the child server process and I can't seem to find out how and why or any solutions to this.
My console app creates a new cmd.exe child process that runs a "java -jar server.jar" command when starting the server. When stopping the server a simple "stop" message is written to the standard input of the child process. This all works fine and the java server stops.
However as soon as the child process exits, the console app unexpectedly crashes and the Windows "Program has stopped working." dialog appears. The curious thing is that I have tested the application on my programming laptop that runs Windows 10 and it runs without any issues there both in release and debug mode. My server machine is running Windows 7 however, so it seems to somehow be a Windows 7 problem.
Now there's no code I can really show you since it's the java and cmd.exe child process performing the exit and I of course didn't code the server.jar file. But I will attach an image link of the console when it crashes just for fun.
The child process does not have a separate window, it inherits handles from the parent console app and writes to the parent's STDOUT so messages from the child show in the main app's console.
I have tried starting the child process with CREATE_NEW_PROCESS_GROUP flag, still crashes.
I have tried ignoring SIGINT and SIGTERM signals, still crashes.
I have also verified that the application doesn't start execution of the commands following the server shutdown call (writing stop message to stdin of server process) so they can't be the problem.
If anyone has any tips or ideas about what could be the issue I'm all ears. Thanks!
Console application crashes, Windows "Program has stopped working." dialog is not shown on picture.
EDIT:
Okay, so I created a minimal reproducible example. Here is all the needed code (for C++ main function):
//security attributes for pipes
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
//handles for child standard input/output
HANDLE child_stdin_rd = NULL;
HANDLE child_stdin_wr = NULL;
if (!CreatePipe(&child_stdin_rd, &child_stdin_wr, &saAttr, 0))
return -1;
if (!SetHandleInformation(child_stdin_wr, HANDLE_FLAG_INHERIT, 0))
return -1;
STARTUPINFOW startupInfo;
ZeroMemory(&startupInfo, sizeof(STARTUPINFOW));
startupInfo.cb = sizeof(STARTUPINFOW);
startupInfo.hStdInput = child_stdin_rd;
startupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
startupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
startupInfo.dwFlags |= STARTF_USESTDHANDLES;
PROCESS_INFORMATION processInfo;
ZeroMemory(&processInfo, sizeof(PROCESS_INFORMATION));
//cmd.exe path
wstring exepath = L"c:\\windows\\system32\\cmd.exe";
//cmd command to start server
wstring command = L"cmd.exe /c java -Xms1G -Xmx4G -jar server.jar nogui";
LPWSTR com = new wchar_t[command.size() + 1];
copy(command.begin(), command.end(), com);
com[command.size()] = 0;
if (!CreateProcessW(exepath.c_str(), com, 0, 0, TRUE, CREATE_NEW_PROCESS_GROUP, 0, 0, &startupInfo, &processInfo))
return -1;
//sleep for 1 min, letting server start up
this_thread::sleep_for(chrono::minutes(1));
//command to stop server
string stopCmd = "stop\n\0";
DWORD stopCmdByteSize = stopCmd.size() * sizeof(char);
if (!WriteFile(child_stdin_wr, stopCmd.c_str(), stopCmdByteSize, 0, 0))
return -1;
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
CloseHandle(child_stdin_wr);
To reproduce this, your machine would need to be running Windows 7 and in the same folder as the application must be a Minecraft server.jar file (version 1.15.2 at time of writing this) which you can get from their website. Also, the server might need some setting up first, running it for the first time by double-clicking .jar file creates all needed server files, you must open "eula.txt" and accept the EULA by changing eula=false to eula=true. Then the server should be good to go.
Like stated before, I didn't code the server.jar file and thus do not know the complete behavior of the java server program.
Bug found! Problem solved!
Ahh, after some vigorous thinking and reading the docs again to verify the code is correct I found the culprit.
In the call to the WriteFile() function I forgot to give it a pointer to a DWORD so that it can update the number of bytes the function has written.
So the following code:
if (!WriteFile(child_stdin_wr, stopCmd.c_str(), stopCmdByteSize, 0, 0))
return -1;
Needed to be changed to:
DWORD bytesWritten = 0;
if (!WriteFile(child_stdin_wr, stopCmd.c_str(), stopCmdByteSize, &bytesWritten, 0))
return -1;
So I guess it was a kind of undefined behavior that Windows 10 could handle but Windows 7 couldn't, resulting in the program crashing.. Kind of feel embarrassed for writing this lengthy post because of a small error in a function call, but there you have it folks! Thanks to those who gave tips! :)
You may have better luck using RCON, which is a protocol built into the Java edition server used to remotely manage a server with a simple TCP packet format, rather than trying to write commands to the standard input of the server directly.
See wiki.vg's page on RCON for an explanation on the packet format.
I have my middle layer jar file running on the linux server. I want that jar file running in background non-stop.
nohup java -jar RushMiddleLayer.jar &
But when i re-run this command, another new instance of the jar created and running.
I have searched through google. They suggested some options.
"Bind a ServerSocket". But which is not working for me. Process killed after press enter or Ctrl+C.
I want to have two benefits from the jar. One is always running with fail. Another if restart the jar using the same command (nohup java -jar RushMiddleLayer.jar &).
It should replace the existing jar, not create the new instance.
Just to make sure I understand what you want, you want a jar file that runs in the background and it is only able to be launched once and once only?
If this is what you want, there is two ways to achieve this:
Use a port as a semaphore (as you suggested)
Use a file as a semaphore.
For option 1,
The code should be as simple as something like:
try {
serverSocket = new ServerSocket(port);
} catch (IOException e) {
System.out.println("Could not listen on port: " + port);
// ...
}
An IOException will be thrown, if you cannot open server socket on this port. However, this could also occur if some other application is using this port. So be careful what port number you choose.
For option 2,
You simply use a FileWriter and create a dummy file and keep this file open until the jar/program is finished (or closed). When a second instance of the jar attempts to open, an exception will be thrown and it won't be able to start due to the fact that it will try to open the file for writing which produces an IOException because only one process can have a write handle to a file at the same time.
I have written a simple code of server side programming that is waiting for the response from client, this runs successfully on the cmd.exe but while executing it on the eclipse it is throwing exception, the details of exception are as follows;
Exception in thread "main" java.net.BindException: Address already in
use: JVM_Bind
this is happening in eclipse only could anyone please tell me how it is working in eclipse & how in cmd.exe
the code of server side program is :
package networking;
import java.io.*;
import java.net.*;
public class Server1 {
public static void main(String args[]) throws Exception {
ServerSocket sock = new ServerSocket(5000);
Socket s1 = sock.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(
s1.getInputStream()));
String msg = br.readLine();
}
}
The socket is open when 'Server1' is started.
This can happen if:
Server1 is already running. ( you didn't kill it, seems to be the likely case...)
Another process is listening on port 5000.
The port isn't closed down quite yet, but is stuck in a "waiting" state for a while. (It can happen if a server is killed when sockets are connected.)
But! Instead of guessing, You should simply check what's going on: Download Microsoft's TCPView and have a look:
http://technet.microsoft.com/en-us/sysinternals/bb897437
(You could also use netstat -a in a cmd window.)
Some notes:
The port number
You should probably not use port 5000, as it seems to be used by uPnP - you may find that the port is always open on some machines... Check here:
http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers.
Try a 5-digit number :-)
Time_wait
Check this question about Java network server and TIME_WAIT:
The should-be-accepted answer gives the following options to reduce the window,
setSoLinger(true,0)
setReuseAddress(true)
(With the risk of losing data when killing the server as the client may not become aware of that the send failed. In the old days, data could get mixed up too, but that is no longer the case.)
This used to happen to me all the time in eclipse. Make sure nothing else with respect to your server is running. In eclipse, make sure you click the red box to terminate all instances. To double check, if in windows, go to task manager and make sure no processes related to your server are running. That should do the trick.
I am running rsync through my java application.(Solaris Evn)
The Java application will sync the files with remote machine. During our connection failure testing we noticed an issue running rsync through java program. The java application which is running at source side is not receiving any error message if there are any connection issues during the sync process.
Brief details about the test scenario:
We run the Java Program
The java program starts the rsync command and sync the large number of files from source to remote destination
During the sync process we run the ps -ef | grep rsync to check whether the processes are running or not at both(source and dest) side. Both side rsync processes are running.
We identify the rsync process id at target machine and kill the process with kill -9 <pid>
The java code didn't receive any error message and didn't exit. It just hung.
And also noticed that the rsync process is still running at source side and rsync process is also not printing any log message in the log file.
Note : If we run the rsync command directly (not through java program) , then everything is working fine. When we stop the rsync process at target the source process will be stopped.
When RSYNC terminated at target, the Java program and RSYNC is not detecting that the target has issues. No log files written , Java program will hang and becomes unresponsive.
Through perl its working fine. Not sure what the problem with java...!!!
I don’t have any clues to debug this issue.
Please share your thoughts and pointer to debug.
In your Java side I recommend creating two additional threads to consume the p.getInputStream() and p.getErrorStream() streams of your Process p. I think that helps rsync feel more loved and cared for.
Something like this (I'm ignoring IOExceptions for simplicity --- you'll have to deal with them!):
final Process p = Runtime.exec("rsync"); // however you do this...
Runnable consumeIn = new Runnable() {
public void run() {
InputStream in = p.getInputStream();
InputStreamReader isr = new InputStreamReader(in, "UTF-8");
BufferedReader br = new BufferedReader(isr);
String line;
while ( (line = br.readLine()) != null ) {
// Throw away the data? Or do something with it if you like!
}
}
};
Runnable consumeErr = new Runnable() {
public void run() {
InputStream in = p.getErrorStream();
// etc... (very similar to consumeIn)
}
};
new Thread(consumeIn).start();
new Thread(consumeErr).start();
I have a class with a method that works just find when I run it from the command line. Nothing seems to happen when I call it in a JSP file though. Could I be missing something here? Are there some configuration changes I need to make to have this code working.
public static void toText(String pdfFile, String textFile) {
try {
String[] cmd = {"pdftotext", pdfFile, "/tmp/text1984.txt"};
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
} catch (Exception e) {
System.out.print(e.getMessage());
}
}
Regards,
Phiri
This can have 2 causes:
Your webbrowser doesn't run at the same machine as webserver while you're expecting that Java from webserver also runs in webbrowser (which is ultimately untrue).
The servletcontainer where the JSP runs simply failed to execute the command, which can have a lot of causes, such as insufficient permissions or the command just error'ed.
Cause #1 is to be solved by running the Java code in webbrowser instead. This can be done with help of a signed(!) applet. As to cause #2, to nail down its root cause, read this article to learn how to understand and debug "Runtime.exec() does nothing" problems. Read all the 4 pages.
I think most probably it's a matter of the security settings of the server where the JSP files, probably the server (doesn't allow exec calls). So you will have to tune the security settings of the server to allow the call.
Be aware that this may be a security risk.