Home arrow static arrow Java Programming [Archive] - jsp / servlet / tomcat
Warning: Creating default object from empty value in /www/htdocs/w008deb8/wiki/components/com_staticxt/staticxt.php on line 51
Java Programming [Archive] - jsp / servlet / tomcat
This topic has 9 replies on 1 page.

Posts:392
Registered: 3/7/03
jsp / servlet / tomcat  
Jul 5, 2004 8:15 PM



 
hi,
I am using tomcat server. The servlet uses Process class of java.
i.e.
Runtime.getRuntime.exec...

Now what happens is that, when many clients are using the system at the same time the output they receive gets mixed up.
e.g.
user1: print - "this is user one" , receive - "this is user two"
user2: print - "this is user two" , receive - "this is user one"

Since tomcat takes care of multi-threading and so there should not be any overlap. Is it possible that it is the that the process created may be causing such a mixup?
I am really confused about this please help.
 

Posts:14,142
Registered: 99-04-02
Re: jsp / servlet / tomcat  
Jul 6, 2004 9:33 AM (reply 1 of 9)



 
you must be mixing up some variables or not synchronzing or something... how about posting some code.
 

Posts:392
Registered: 3/7/03
Re: jsp / servlet / tomcat  
Jul 7, 2004 10:38 AM (reply 2 of 9)



 
Tomcat server is used.
When many clients do the request at the same time the pout.txt files is output empty.
i dont know why?

<codes>
// part of the codes
for(int i=1; i <= testcase; i++){ // Loop for getting the test case provided by the tutor
Process execProcess;
if((System.currentTimeMillis() < (startTime + (maxAllowTime*i)))){
File dir1 = null;
dir1 = new File(tempProgStore + "
");
execProcess = rt.exec(procPath,null,dir1);
BufferedWriter buffOut = new BufferedWriter(new OutputStreamWriter(execProcess.getOutputStream()));
BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(execProcess.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(tempProgStore + "/pout" + i + ".txt")));
File f= new File(sampleOutputStore +"/in" + i + ".txt");
String fRead = fo.ReadFile(f);
buffOut.write(fRead);
buffOut.flush();
while((System.currentTimeMillis() < (startTime + maxAllowTime))){ //for each test case, wait for it to complete
try{
String line;
if ((line = bufferedreader.readLine())!= null) {
out.println(line);
out.flush();
}
if(execProcess.exitValue() == 0){
break;
}else{ break; }
}catch(IllegalThreadStateException itse){ //the process hasn't finished
}
}
buffOut.close();
bufferedreader.close();
out.close();
endTime = System.currentTimeMillis();
execProcess.destroy(); //destroy the executed process
}
try{
Process killProcess = rt.exec(killProc);
fo.WaitOper(killProcess);
}catch(IOException ie){
}
}
</codes>
 

Posts:392
Registered: 3/7/03
Re: jsp / servlet / tomcat  
Jul 7, 2004 10:38 AM (reply 3 of 9)



 
Tomcat server is used.
When many clients do the request at the same time the pout.txt files is output empty.
i dont know why?

[codees]
// part of the codes
for(int i=1; i <= testcase; i++){ // Loop for getting the test case provided by the tutor
Process execProcess;
if((System.currentTimeMillis() < (startTime + (maxAllowTime*i)))){
File dir1 = null;
dir1 = new File(tempProgStore + "
");
execProcess = rt.exec(procPath,null,dir1);
BufferedWriter buffOut = new BufferedWriter(new OutputStreamWriter(execProcess.getOutputStream()));
BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(execProcess.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(tempProgStore + "/pout" + i + ".txt")));
File f= new File(sampleOutputStore +"/in" + i + ".txt");
String fRead = fo.ReadFile(f);
buffOut.write(fRead);
buffOut.flush();
while((System.currentTimeMillis() < (startTime + maxAllowTime))){ //for each test case, wait for it to complete
try{
String line;
if ((line = bufferedreader.readLine())!= null) {
out.println(line);
out.flush();
}
if(execProcess.exitValue() == 0){
break;
}else{ break; }
}catch(IllegalThreadStateException itse){ //the process hasn't finished
}
}
buffOut.close();
bufferedreader.close();
out.close();
endTime = System.currentTimeMillis();
execProcess.destroy(); //destroy the executed process
}
try{
Process killProcess = rt.exec(killProc);
fo.WaitOper(killProcess);
}catch(IOException ie){
}
}
[/codes]
 

Posts:392
Registered: 3/7/03
Re: jsp / servlet / tomcat  
Jul 7, 2004 10:40 AM (reply 4 of 9)



 
I am sorry!

Tomcat server is used.
When many clients do the request at the same time the pout.txt files is output empty.
i dont know why?

// part of the codesfor(int i=1; i <= testcase; i++){ // Loop for getting the test case provided by the tutorProcess execProcess;if((System.currentTimeMillis() < (startTime + (maxAllowTime*i)))){File dir1 = null;dir1 = new File(tempProgStore + "\\");execProcess = rt.exec(procPath,null,dir1);BufferedWriter buffOut = new BufferedWriter(new OutputStreamWriter(execProcess.getOutputStream()));BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(execProcess.getInputStream()));PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(tempProgStore + "/pout" + i + ".txt")));File f= new File(sampleOutputStore +"/in" + i + ".txt");String fRead = fo.ReadFile(f);buffOut.write(fRead);buffOut.flush();while((System.currentTimeMillis() < (startTime + maxAllowTime))){ //for each test case, wait for it to completetry{String line;if ((line = bufferedreader.readLine())!= null) {out.println(line);out.flush();}if(execProcess.exitValue() == 0){break;}else{ break; }}catch(IllegalThreadStateException itse){ //the process hasn't finished}}buffOut.close();bufferedreader.close();out.close();endTime = System.currentTimeMillis();execProcess.destroy(); //destroy the executed process}try{Process killProcess = rt.exec(killProc);fo.WaitOper(killProcess);}catch(IOException ie){}}
 

Posts:21,719
Registered: 98-02-20
Re: jsp / servlet / tomcat  
Jul 7, 2004 10:48 AM (reply 5 of 9)



 
You have several empty catch blocks. That's a terrible thing to do. You should at least log those exceptions so you can see if something goes wrong.

You're not using Runtime.exec() properly:

http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html

I'd wrap that Runtime request in a separate object for starters and make sure that it worked correctly on its own. Then I'd have the servlet instantiate it to accomplish the task.

Servlets aren't synchronized. They're multi-threaded objects, unless you use the SingleThreadedModel, so it's your responsibility to make sure that they're thread-safe.

%
 

Posts:392
Registered: 3/7/03
Re: jsp / servlet / tomcat  
Jul 7, 2004 10:52 PM (reply 6 of 9)



 
thank you for going through the codes,
i have been doing this for two days non-stop now without any positive outcome.
I think you know what i am trying to do. "i receive programs from multiple clients and then i run it" sounds simple, but has been unpredictable.

How do I make sure that the servlets are thread safe?
with one client asking to run the program the program works fine.
but when several of them do it together some of the ppl do not get the output.
I did read the information provided and in the codes above i think i do use the buffered input and output streams.

would it be ok? if i email you the ".txt" file?
 

Posts:6,147
Registered: 11/9/00
Re: jsp / servlet / tomcat  
Jul 8, 2004 1:14 AM (reply 7 of 9)



 
I can see a number of problems. The file you're writing appears to be the same file regardless of which client you are writing it on behalf of. I don't know what you are doing with this file but you need some way to make it unique to the client. For example you can use the File.createTempFile methods to create a random file name. (I'm guessing this is the cause of it sending the wrong answers to the wrong clients.)

Your timeout mechanism isn't going to work. When you do a read on the "bufferedreader" the thread will wait for the background process to send a line so if your background wiki/./process hangs it is almost certainly going to hang with your servlet stuck in the readLine(). Your timer won't get checked. You need to do copying the output and timing out on separate threads. I would probably farm out the copying process to a thread.

And, as has been pointed out, don't throw away your exceptions. If you don't have anything better to do with them "wrap" them in a ServletException so the system will display them.

e.g.
catch(IllegalStateException e) {   throw new ServletException(e);  } 
 

Posts:392
Registered: 3/7/03
Re: jsp / servlet / tomcat  
Jul 8, 2004 2:53 AM (reply 8 of 9)



 
thank you for the reply

"You need to do copying the output and timing out on separate threads. I would probably farm out the copying process to a thread."

any idea how to do that?

This program was handed down to me by someone.... there are many errors in it... and the cause of some which has been mysterious to me so far.
I have started doing the unit testing... and the first problem i have found where the system outs seem to repeat (i.e. the userids repeat) is the compilation part... i dont know how to solve it

--------//servlet            if(lang.equals("C") || lang.equals("P")){                C_Interpreter c_interpreter = new C_Interpreter();                c_interpreter.JudgeEngine(lang, countFileUploaded, inputUserInfo.getModfBy(), submInfo.getCourCode(), submInfo.getProbNum(), probInfo.getNumTCTesting(), Integer.parseInt(probInfo.getExpRunTime()), "T");             }---------//c_interpreter    public void JudgeEngine(String lang, int intNFU, String CurrentUserID, String CourCode, String ProbNum, int testcase, int expRunTime, String testingMode){        String compileError = Compilation(lang, intNFU, CurrentUserID, CourCode, ProbNum, testcase, expRunTime, testingMode);    }     public String Compilation(String lang, int intNFU, String CurrentUserID, String CourCode, String ProbNum, int testcase, int expRunTime, String testingMode){        try{            Runtime rt = Runtime.getRuntime();            Config config1 = new Config();            String tempProgStore = "";            String sampleOutputStore = config1.readKeyValue("online.storagepath")  + "\\" + CourCode + "\\" + ProbNum;             if(testingMode.equals("T")){ //T is the testing mode being used                tempProgStore = sampleOutputStore + "\\" + CurrentUserID + "\\temp";            }else if(testingMode.equals("S")){                tempProgStore = sampleOutputStore + "\\" + CurrentUserID;            }            File dir = new File(tempProgStore + "\\");            String compPath = config1.readKeyValue("onlinejudge.cppCompPath");  //Java Compile Path --- nmake            Process rd_mak = null;            Process compileProcess = null;            rd_mak = rt.exec("cmd /c dir /b " + tempProgStore + "\\*.mak > " + tempProgStore + "\\makname.txt");            fo.WaitOper(rd_mak);            LinkedList fileNameList_mak = fo.createFileList(tempProgStore + "\\makname.txt");             String mak_file = "";                for(int i=0; i<fileNameList_mak.size(); i++){                    mak_file = fileNameList_mak.get(i).toString();                }               compileProcess = rt.exec("cmd /c " + compPath + " " + mak_file + " > error_message.txt ", null, dir);               fo.WaitOper(compileProcess);        }catch(Exception e){System.out.println("Error : "+e.getMessage());        // i have done modifications here because after this part its just file reading and writing}--------------------
 

Posts:6,147
Registered: 11/9/00
Re: jsp / servlet / tomcat  
Jul 8, 2004 4:20 AM (reply 9 of 9)



 
You really want 3 threads running. One copying the output stream, one performing the timeout and one waitng for the external process to finish. Probably it's most straighforward to let the existing thread do the waiting.

All local variables used by the subordinate threads need to be declared as final

You need to interupt the timeout thread if the process terminates without it's aid.

Something like:

final long timeOutMillis = ....;final process p = Runtime.getRuntime.exec(...);final  fos = new FileOutputStream(....); class TimeoutClass extends Thread {     boolean timedOut = falsepublic void run() {         try  {            sleep(timeOutMillis);             sychronized(this) {                    p.destroy();                    timedOut = true;                    }            }        catch(InterruptedException e) {        }      }   public synchronized void processFinished() {        if(!timedOut)            interrupt();       }     }   TimeoutClass myTimeout = new TimeoutClass();     myTimeout.start();    Thread copyThread = new Thread(new Runable() {         public void run() {               try {                   InputStream in = p.getIntputStream();                   int ch;                   while((ch = in.get()) != -1)                       fos.put(ch);                   in.close();                   fos.close();                  } catch(IOException e) {                 }             });        copyThread.start();        int res = p.waitFor();        myTimeout.processFinished();         boolean timedOut = myTimeout.timedOut;        myTimout.join();         copyThread.join();

This is a bit lazy because I'm not dealing with the IOException in the thread.


}

 
This topic has 9 replies on 1 page.