I'm making a core server-management system for my company, and both the server manager and server itself are Java jar files. What I need to do is boot up the server from the server manager, and the server needs to be able to read console input. However, the way I currently have it coded, it ignores console input. I believe the while loop is freezing the thread, but IDK what to do about it. Any ideas?
Process process = Runtime.getRuntime().exec("sh start.sh");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while((line = reader.readLine()) != null){
System.out.println(line);
}
Technically, your while loop isn't freezing the thread - the call to reader.readLine() is. I'd recommend you listen to both your InputStream and ErrorStream, and to do both at the same time you either need to use Threads or java NIO. For a Threaded solution, I built and used DataFetcher for specifically this kind of purpose. All you need to do is create a DataFetcher around an InputStream, add a FetcherListener, and start the DataFetcher with a new Thread
Related
Following security vulnerability has been reported on our application -
The call to readLine() at xyz.java line 119 might allow an attacker to
crash the program or otherwise make it unavailable to legitimate
users.
Code with vulnerability
Commented line reported -
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpConnection.getInputStream()));
String inputLine;
StringBuffer okResponse = new StringBuffer();
while ((inputLine = reader.readLine()) != null) { //readLine() on this line has been reported
okResponse.append(inputLine);
}
reader.close();
return okResponse.toString();
The remediation for the same says -
Validate user input to ensure that it will not cause inappropriate
resource utilization.
But, it is not clear what exactly can be validated. Any pointers?
In theory an attacker could send you an unlimited amount of data via the httpConnection. Since you try to consume all of it, it might crash your application (OutOfMemory).
I´d assume you have a certain format and length for the okResponse in mind,
so you would be better off checking that.
Make sure you read to read the answer from Subhas linked by Luis Muñoz (Most Robust way of reading a file or stream using Java (to prevent DoS attacks)),
that has some more implementation details for reading content from a stream.
Another issue might be that the attack just keeps the connection open without sending any data. I`d assume there should be a timeout in place to cut the connection at some point, else the thread might be blocked forever.
Edit:
Since you code does not have it explicitly, you also should add a try ... finally ... block to make sure that the resources are properly closed.
I have a Java program that will freeze during the rush hour currently. I am looking for the reason. Right now, my idea is that it is because some of the codes are not AJAX, so it will hangs in there when requesting JSON object from server during rush hour (Internet speed is slow during rush hour). But I am not very sure that it is not AJAX though. I cannot paste all the codes here because it is related to company's property, so I am going to write some piece of codes/pseudocode. The program uses the following to do the request.
URL url = new URL("http://www.xxxxxxxx.com/");
URLConnection conection = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(conection .getInputStream()));
String inputLine;
String content = "";
while ((inputLine = in.readLine()) != null) {
content += inputLine;
}
in.close();
json = new JSONObject(content);
The above codes are some snippet of the program where I think it causes the freezing. My question is that, This piece of code does not seem to use any AJAX and it is not multithreading, right? So it hangs in there (freezing) when the Internet connection is very slow? I am not very experienced about this. Please help.
If you do not think this is the main reason that causes the freezing, what could be the most possible reason for this kind of problem in general speaking.
Thank you in advance.
Edits/Update:
My program is a swing program that runs in client side. There is no
real server side codes for this application. The URL address is a
3rd party server that provides some kind of data that the program
needs. I did not see the program uses any threads. It is basically core Java without using any threads as I see, and I am not very familiar with multi-threading, so I am not sure. (The program is not written by me, it is written by some former programmers) That is why I am considering that maybe it did not use other threads to run this server request when it should be.
What I mean by freezing is that the UI will freeze for a few seconds during the rush hour when it try to run some specific functions. The above code I wrote is some snippet from those functions. After the UI freezes for awhile, it then works as expected in the rest. However, in non-rush hour, it works like a charm.
Specifically, BufferedReader in = new BufferedReader(new
InputStreamReader(conection .getInputStream())); is what I think
that causes the problem. Could anyone confirm that?
All asynchronous methods like HTTP POST/GET, implement in separate Thread. User don't interest to see what your application does in background.
In addition, its not good practice to use String for appends, like jlordo says, use StringBuilder or StringBuffer.
StringBuilder buff= new StringBuilder();
while ((inputLine = in.readLine()) != null) {
if(!"".equals(line).trim){
buff.append(line).append("\n");
}
}
in.close();
You can add timeout to your session to be sure that application doesn't stuck at all.
[EDIT]
Regard to question changes, I don't think that
BufferedReader in = new BufferedReader(new InputStreamReader(conection .getInputStream()));
it's your problem.
You can try to do followed flow but I still thinks about separate Thread with GUI Thread
InputStream is = conection .getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ( (line = br.readLine()) != null) {
You probably want to use a SwingWorker thread to do the call to the server. That way, when it is busy, the UI won't freeze.
However, remember, you won't see the resulting changes on the screen that the new data would provide until the new data arrives.
See Oracle SwingWorker JavaDocs
Tutorial with example similar to yours
I am currently trying to make a litlle handy tool, you see I am a network administrator and my boss told me that he wanted me to monitor the network and block certain sites and ip for some game servers, so for the monitoring part we are going to redirect all traffic on the network to a server where we can monitor the traffic before sending it to the gateway.
For this we are going to use arpspoof in linux and I have finished a solution for the blocking of sites and servers, and what I am going to make is a GUI that makes it easier for me to handle and control these things and when I tried running arpspoof from java using a ProcessBuilder it does not work and I get no output?
It also does not enter the while loop. I can't really think of more to write atm, but if I can think of more I will update this thread.
My code:
new Thread() {
public void run() {
try {
System.out.println("running arpspoof...");
Process prb = new ProcessBuilder("gksudo", "arpspoof", "-i", "wlan0", Gateway).start();
InputStream is = prb.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println("Output: " + line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
I have never used gksudo, but I googled it and it says it's a GUI version of sudo. I'm guessing that you just launched a GUI app which does not write anything to stdout and which does not return. If so, then the code is doing what I would expect. It is blocking until the process writes a line of text that it can read - which never occurs so it blocks indefinitely.
First test your ProcessBuilder code using a trivial command like "echo" to make sure your Java code is working as expected. Then work your way back. Try running your program as root so you don't need the sudo argument and see if that works. Then finally try to run it using sudo instead of gksudo.
I think #user is on the right track, but there are a couple of other possible explanations.
The gksudo command could be asking for a password. I'm not sure where it would ask, but there's a good chance that it won't be the "stdout" stream of the "gksudo" process.
If "gksudo" or the command that you are "gksudo"-ing fails to launch, there is a good chance that it will write an error message to its "stderr" stream. But you are not reading "stderr".
To help diagnose this, you need to try the following:
Look in the log file that for "sudo" - it is "/var/log/secure" on my box.
Use "ps -efl" (or similar) to see what processes exist while your application is blocked waiting for output. (If that is happening ...)
Look to see if "gksudo" is prompting for a password in an unexpected place.
Try temporarily tweaking the "sudoers" file to allow the "arpspoof" command to be "sudo"-ed without a password.
I am building a simple telnet connection daemon for communications between internal network applications, and I ran into an issue when reading the first line from BufferedReader.
This code snippet is not complete due to the fact there is a lot of other junk in there so I have stripped it down only to include the object creation and read from the steam.
in = new BufferedReader(new InputStreamReader(this.client.getInputStream()));
out = new PrintWriter(this.client.getOutputStream(), true);
String line;
while (true) {
out.println(flag); // flag is just an integer
System.out.println(line);
// Processing the line and updating 'flag' accordingly
}
Entering test into the telnet connection yielded v? v v? v' ²? v? ²?test in the console that was running the program. This does not happen to lines sent after the first one.
Is there a way to clear that garbage out before the user interfaces with it so it doesn't get sent with the first line? or is this issue caused by my telnet client (and might be fixed when I write a client that interfaces with this)?
I strongly suspect it's the telnet protocol negotiation. Ideally, you should handle it having read RFC 854 carefully.
Note that you shouldn't just use InputStreamReader without specifying the character encoding - it's very unlikely that the platform default encoding is the one you want.
I have used TaskExecutor from spring and futures to get the future from the task,but now when some task doesnt respond in some time I have to stop those tasks.I have tried using Future.cancel() method but its of no use the thread stills seems to be running .Can you suggest me some method to stop it?
My thread is waiting on reading the Html content from a link..so how do i stop the task
Edit: the relevant code:
URL link = new URL(Content);
URLConnection yc = link.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
String inputLine;
StringBuffer Sbuff = new StringBuffer();
while (((inputLine = in.readLine()) != null) &&
((Calendar.getInstance().getTimeInMillis() - TimeatStart) / 1000) < 4) {
Sbuff.append(inputLine);
}
Generally speaking, you don't do that. If you want the HTTP request to stop after hanging for a while, then set a timeout on it. It's always best to let the thread finish whatever work it's been given to do.
Edit: Based on your source code, the first thing you need to do is make sure to call connect() on the URLConnection. Otherwise, nothing will happen. Take a look at Working with URLs in the Java Tutorial. After that, if you still want to set timeouts, use setConnectTimeout() to set the amount of time it should try to connect before timing out and setReadTimeout() to set the amount of time it should wait to receive data after a request is sent.