0

i have a run method that launches a new thread and want to launch another method from it after it ends but this is not working. at the end of the method i put some printout statements and they only show a few times like when the i first load the java program. usually they don't show.

i wanted to know why they are not showing up and it there is a reliable way like a callback method such as in AsyncTask's onPostExecute() that i can use on Java threads.

have no idea why the printout statements don't show 98% of the time. any ideas?

a little confused here. as i thought that the file would reach the end and the count variable in the while loop and it would get to 0 or -1 then the while loop would end and the execution of the process and it would exit the while loop and continue on with the thread. this is not happening and it does not make sense.

the file i am receiving with this code is complete and there are no problems. however i need to launch another thread method to send a message back to the Android client to tell it that the file had been received successfully.

the rest of the code

 @Override
public void run() {

    FileOutputStream fos = null;
    BufferedOutputStream bos = null;
    BufferedInputStream bis = null;
    DataInputStream dis = null;
    int bufferSize = 0;

    File file = new File("/Users/UserName/sampleFile.db");

    // get input streams
    try {
    fos = new FileOutputStream(file);
    bos = new BufferedOutputStream(fos);
    bis = new BufferedInputStream(socket.getInputStream());
    dis = new DataInputStream(bis);
    } catch (IOException ex) {
        Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
    }

    try {
        bufferSize = socket.getReceiveBufferSize();
    } catch (SocketException ex) {
        Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
    }

    int fileSizeFromClient = 0;
    long serialNumber = 0;

    try {
        fileSizeFromClient = dis.readInt();
        serialNumber = dis.readLong();
    } catch (IOException ex) {
        Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
    }

    String serialString = String.valueOf(serialNumber);

    System.out.println("filesize " + fileSizeFromClient);
    System.out.println("serialNumber " + serialString);
    System.out.println("bufferSize " + bufferSize);

    int count = 0;
    try {
        bos.flush();
    } catch (IOException ex) {
        Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
    }

    byte[] buffer = new byte[fileSizeFromClient];
    try {
        while((count = dis.read(buffer)) > 0){
            bos.write(buffer, 0, count);

           if(count == -1){ // <-- this line does not help break out of loop
             break;
            }


        }

        System.out.println("size of file written " + buffer.length); // <-- does not print out
        socket.close();

        System.out.println("test out 1"); // <-- does not print out

    } catch (IOException ex) {
        Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);

     } catch (Exception ex) {
            Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
        }

  System.out.println("test out 2"); // <-- does not print out

}  // end run

EDIT: forgot to mention that this is for a Java desktop app, not Android, but the client it is connecting to is an Android device. there is no problem with the sending and receiving of any file, socket and TCP/IP file networking has no problems

Kevik
  • 9,181
  • 19
  • 92
  • 148
  • Do you have a reference to the thread you are launching? I had a similar issue with C#, because I did not keep a reference the thread was Garbage Collected... – Leon Sep 23 '13 at 13:03
  • 1
    `while ( count ... > 0)` makes the `if` dead code, never succeeding. And `bos.close()` already does `fos.close()` (same for bis). – Joop Eggen Sep 23 '13 at 13:05
  • by reference do you mean for the thread variable? this thread is launched by another class every time an new socket connection is set up, like this; MultiThreader multi = new MultiThreader(socket); Thread t = new Thread(multi); t.start(); – Kevik Sep 23 '13 at 13:06
  • yes that is correct. if the loop is ending normally the inner if would be dead code – Kevik Sep 23 '13 at 13:08
  • Check out this answer, maybe it will help http://stackoverflow.com/questions/2220547/why-doesnt-system-out-println-work-in-android Especially the comment about System.out tag. – nio Sep 23 '13 at 13:08
  • forgot to mention. the server code here is for a Java Desktop application, it is connecting to a client that is Android, so the Java app itself should get system.out.println on the console – Kevik Sep 23 '13 at 13:10
  • The `if ...` can be removed, as there: `count > 0`. – Joop Eggen Sep 23 '13 at 13:10
  • that was an interesting comment about the possibility of garbage collection. but i would not imagine that the system would garbage collect before the thread was complete. – Kevik Sep 23 '13 at 13:13
  • Are you positive about the way you get file size and serial number. Is that the exact protocol? readint and after readlong. – user2259824 Sep 23 '13 at 13:14
  • if in this particular case the system.out.println shows that function calls located after the for loop would not be reliable of actually happening, i wonder if there is something that i can use like onPostExecute() in Android, if there is something similar for java threads, that would be great – Kevik Sep 23 '13 at 13:16
  • yes the readInt and readLong are both working with no problems, these two values are being printed out on the console with a system.out.println statement, they were sent from the client, and both values are received before the actual file is received. so three things are being sent with TCP/IP. all using DataInputSream, which is a wrapper for BufferedInputStream. it allows sending primitive types of values over the socket connection. – Kevik Sep 23 '13 at 13:18
  • could it be that you get some exception other then IOException? try to put sys.out into the last catch-block catch(Exception ex){...} – JohnnyAW Sep 23 '13 at 13:31
  • yes I did look at the Exceptions. I finally found out the answer and posted it, check it out. – Kevik Sep 23 '13 at 14:02

1 Answers1

2

I found the answer to the question.

the Java server gets stuck or hangs on this line:

  while((count = dis.read(buffer)) > 0){
        bos.write(buffer, 0, count);

because of the outputStream object in the Android client that the sever is connected to. if you close the outputStream in the client like this:

 dos.close();   // for DataOutputStream dos;

The InputStream object in the client has no effect, it is only the OutputStream. if OutputStream in the client is closed right after the for loop then it stops the blocking or hanging of the Java Sever in it's for loop.

code from the Android client

   while ((count = bis.read(bytes)) > 0) {
          dos.write(bytes, 0, count);
         }
             dos.close();

after this adjustment, all of the System.out.println statements in the Java sever after the for loop now work. all the way the last line of the run method.

Kevik
  • 9,181
  • 19
  • 92
  • 148