I am using Java programming to approach Android Studio (Android API 32). The scenario is that some data received from an external device through WiFi are repeatedly stored in an array which will be converted in a Float List Object pitch_2, and at some point, this list will be averaged in next function.
This function is called in this loop:
private class Thread2 implements Runnable {
#Override
public void run() {
while (true) {
try {
byte[] buffX_2 = new byte[BUFFER_LENGTH*2-8];
if (btn_client_2.isEnabled()) {
int k_2 = inputStream_2.read(buffX_2);
byte[] c_2 = new byte[buffX_2.length + client2.length];
System.arraycopy(buffX_2, 0, c_2, 0, buffX_2.length);
System.arraycopy(client2, 0, c_2, buffX_2.length, client2.length);
fou.write(c_2);
float pitch_2 = from_bytes_to_float(buffX_2,18);
pitch_buff_2.add(pitch_2);
int [] data_2 = unpack(buffX_2);
if (message != null) {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (x%plot_freq==0) {
float value_2 = average_list(pitch_buff_2, plot_freq);
if (y>=4000) {
series_2.resetData(new DataPoint[] {new DataPoint(x, value_2)});
y = 0;
} else {
series_2.appendData(new DataPoint(x, value_2),true,500);
}
pitch_buff_2.clear();
Log.v("Plot Update","OK");
}
x += 1;
y += 1;
Log.v("Plot Update",String.valueOf(x));
}
});
} else {
Thread1 = new Thread(new MainActivity.Thread1());
Thread1.start();
return;
}
Thread.sleep(1);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
}
Here my function which is called average_list simply intends to take as input a List Object and do the average:
if (list == null) {
return 100/n_elements;
} else {
float value = 0;
for(int j = 0; j < list.size(); j++) {
value = value + list.get(j);
}
return value/n_elements;
}
}
In a totally randomic way, this function might generate the following error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapplication.smart_crutches_app, PID: 25434
java.lang.NullPointerException: Attempt to invoke virtual method 'float java.lang.Float.floatValue()' on a null object reference
at com.example.myapplication.smart_crutches_app.MainActivity.average_list
I have put a not-null control (following this suggestion What is a NullPointerException, and how do I fix it?) in the average_list function in order to avoid this error but still happens.
As far as I understand I call get method in a null object, but how is it possible if I have put an if statement?
I am hundred per cent sure I am forgetting something, but I cannot figure out what yet.
What do you think?
Your help would be really appreciated.
Thanks.
You're calling .floatValue() on an expression whose type is Float (SOURCE: Just read the error message you get!), but the expression resolves to null. Your if(list == null) check checks if the list is null which is therefore irrelevant to this problem: It's not about list being null. It's about some expression of type Float being null.
You don't appear to have any Float values anywhere; however, that's not quite true: Your list is filled with Float objects, and you are auto-unboxing it on your value = value + list.get(j) line. Java only supports numeric math on primitives (float - primitives are the direct value and cannot be null - null is a reference, as in, this variable can point at an object, but currently it points at nothing).
And lists can only contain objects.
So, seemingly, value = value + list.get(j) is impossible: list.get(j) returns objects (Floats to be specific, which aren't the same as floats), and objects don't do math.
However, what's happening here is auto-unboxing: Anytime the code doesn't make sense, but it would make sense if you 'unbox' the primitive wrapper type (Float is the wrapper type for float), then java assumes you meant to invoke .floatValue() on your Float object.
So java just inserts that for you. And like all instance method invocations, if the receiver (the thing to the left of the dot) is null, you get a NullPointerException - and that's where its coming from. list.get(j) is returning null and that causes an NPE.
So, the real question is, how did nulls end up in your list?
There's no way to answer that question; you did not include the relevant code. In general, when asking SO questions, try to paste a complete snippet that anybody can just paste into a terminal and run.
Here the entire code #rzwitserloot
//Some import
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.series.DataPoint;
import com.jjoe64.graphview.series.LineGraphSeries;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
#SuppressLint("SetTextI18n")
public class MainActivity extends AppCompatActivity {
ServerSocket serverSocket;
ServerSocket serverSocket_2;
ServerSocket serverSocket_3;
Thread Thread1 = null;
Thread Thread11 = null;
Thread Thread111 = null;
TextView tvMessages;
Button btnStart, btnEnd, btnConnect;
GraphView graph;
GraphView graph2;
LineGraphSeries<DataPoint> series;
LineGraphSeries<DataPoint> series_2;
LineGraphSeries<DataPoint> series_3;
LineGraphSeries<DataPoint> lc;
LineGraphSeries<DataPoint> lc2;
LineGraphSeries<DataPoint> lc3;
String message,current_time;
public static String SERVER_IP = "";
public static final int SERVER_PORT = 8080;
public static final int SERVER_PORT_2 = 50000;
public static final int SERVER_PORT_3 = 40000;
public static final int BUFFER_LENGTH = 20;
int x, y, client_connected;
int plot_freq;
private PrintWriter output;
private PrintWriter output_2;
private PrintWriter output_3;
private DataInputStream inputStream;
private DataInputStream inputStream_2;
private DataInputStream inputStream_3;
FileOutputStream fou;
OutputStreamWriter saveStream;
RadioButton btn_client_1,btn_client_2,btn_client_3;
byte [] client1 = {0,0};
byte [] client2 = {1,1};
byte [] client3 = {2,2};
Socket socket_3;
Socket socket_2;
Socket socket;
List<Float> pitch_buff_1 = new ArrayList<>();
List<Float> pitch_buff_2 = new ArrayList<>();
List<Float> pitch_buff_3 = new ArrayList<>();
List<Integer> lc_buff_1 = new ArrayList<>();
List<Integer> lc_buff_2 = new ArrayList<>();
List<Integer> lc_buff_3 = new ArrayList<>();
Map<Integer, String> data;
Map<Integer, Integer> sounds;
public int ID_audio;
public int flag_Acq = 1;
public int flag_Acq_1 = 1;
public int flag_Acq_2 = 1;
public int flag_Acq_3 = 1;
ColorStateList colorStateList = new ColorStateList(
new int[][]
{
new int[]{-android.R.attr.state_enabled}, // Disabled
new int[]{android.R.attr.state_enabled} // Enabled
},
new int[]
{
Color.GRAY, // disabled
Color.GREEN // enabled
}
);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvMessages = findViewById(R.id.tvMessages);
tvMessages.setMovementMethod(new ScrollingMovementMethod());
btnStart = findViewById(R.id.btnStart);
btnEnd = findViewById(R.id.btnEnd);
btnConnect = findViewById(R.id.btnConnect);
Spinner mySpinner_ID = findViewById(R.id.spinner);
graph = findViewById(R.id.graph);
graph2 = findViewById(R.id.graph2);
series = new LineGraphSeries<>();
series_2 = new LineGraphSeries<>();
series_3 = new LineGraphSeries<>();
lc = new LineGraphSeries<>();
lc2 = new LineGraphSeries<>();
lc3 = new LineGraphSeries<>();
series_2.setColor(Color.RED);
series_3.setColor(Color.DKGRAY);
lc2.setColor(Color.RED);
lc3.setColor((Color.DKGRAY));
graph.addSeries((series));
graph.addSeries(series_2);
graph.addSeries(series_3);
graph.getViewport().setScalable(true); // activate horizontal zooming and scrolling
graph.getViewport().setScrollable(true); // activate horizontal scrolling
graph.getViewport().setMinY(-201);
graph.getViewport().setMaxY(201);
graph.getViewport().setMaxX(2001);
graph.getViewport().setMinX(0);
graph.getViewport().setYAxisBoundsManual(true);
graph.setTitle("Pitch [°]");
graph2.addSeries((lc));
graph2.addSeries(lc2);
graph2.addSeries(lc3);
graph2.getViewport().setScalable(true); // activate horizontal zooming and scrolling
graph2.getViewport().setScrollable(true); // activate horizontal scrolling
graph2.getViewport().setMinY(400);
graph2.getViewport().setMaxY(2000);
graph2.getViewport().setMaxX(2001);
graph2.getViewport().setMinX(0);
graph2.getViewport().setYAxisBoundsManual(true);
graph2.setTitle("Applied Weight [N]");
SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy_HHmmss", Locale.getDefault());
current_time = sdf.format(new Date());
File folder = getExternalFilesDir("Data_Server_ClientS");
File output = new File(folder,current_time+".txt");
btn_client_1 = findViewById(R.id.btn_client_1);
btn_client_2 = findViewById(R.id.btn_client_2);
btn_client_3 = findViewById(R.id.btn_trunk);
btn_client_1.setButtonTintList(colorStateList); // set the color tint list
btn_client_1.invalidate(); // Could not be necessary
btn_client_2.setButtonTintList(colorStateList); // set the color tint list
btn_client_2.invalidate(); // Could not be necessary
btn_client_3.setButtonTintList(colorStateList); // set the color tint list
btn_client_3.invalidate(); // Could not be necessary
btn_client_1.setEnabled(false);
btn_client_2.setEnabled(false);
btn_client_3.setEnabled(false);
data = new HashMap<>();
data.put(1, "Vibration");
data.put(2, "Audio");
data.put(3, "Both");
sounds = new HashMap<>();
sounds.put(1, R.raw.crutch_left);
sounds.put(2, R.raw.crutch_right);
sounds.put(3, R.raw.trunk_down);
sounds.put(4, R.raw.trunk_up);
sounds.put(5,R.raw.sampling_sx);
sounds.put(6,R.raw.sampling_dx);
sounds.put(7,R.raw.sampling_trunk);
sounds.put(8,R.raw.start);
sounds.put(9,R.raw.end);
tvMessages.setText("Not yet connected crutches\n");
btnConnect.setOnClickListener(v -> {
try {
fou = new FileOutputStream(output);
saveStream = new OutputStreamWriter(fou);
Toast.makeText(MainActivity.this, "Done" + folder.getAbsolutePath(), Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
SERVER_IP = getLocalIpAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}
Thread1 = new Thread(new Thread1());
Thread1.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread11 = new Thread(new Thread11());
Thread11.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread111 = new Thread(new Thread111());
Thread111.start();
});
try {
fou = new FileOutputStream(output);
saveStream = new OutputStreamWriter(fou);
Toast.makeText(this, "Done" + folder.getAbsolutePath(), Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
SERVER_IP = getLocalIpAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}
Thread1 = new Thread(new MainActivity.Thread1());
Thread1.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread11 = new Thread(new MainActivity.Thread11());
Thread11.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread111 = new Thread(new MainActivity.Thread111());
Thread111.start();
/*
btnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
message = etMessage.getText().toString().trim();
if (!message.isEmpty()) {
new Thread(new MainActivity.Thread3(message)).start();
}
}
});
*/
btnStart.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onClick(View v) {
message = "S";
new Thread(new MainActivity.Thread3(message)).start();
plot_freq= 10;
ID_audio = Integer.parseInt(mySpinner_ID.getSelectedItem().toString());
if (btn_client_1.isEnabled()) {
pitch_buff_1.clear();
lc_buff_1.clear();
}
if (btn_client_2.isEnabled()) {
pitch_buff_2.clear();
lc_buff_2.clear();
}
if (btn_client_3.isEnabled()) {
pitch_buff_3.clear();
lc_buff_3.clear();
}
new Thread(new MainActivity.Thread2()).start();
new Thread(new MainActivity.Thread_BioFeedback(8,2)).start();
}
});
btnEnd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
message = "E";
new Thread(new MainActivity.Thread3(message)).start();
try {
new Thread(new MainActivity.Thread_BioFeedback(9,2)).start();
saveStream.close();
Thread.sleep(2000);
finishAndRemoveTask();
if (btn_client_1.isEnabled()) {
serverSocket.close();
socket.close();
}
if (btn_client_2.isEnabled()) {
serverSocket_2.close();
socket_2.close();
}
if (btn_client_3.isEnabled()) {
serverSocket_3.close();
socket_3.close();
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
});
}
#RequiresApi(api = Build.VERSION_CODES.O)
public void Vibrate(int time) {
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createOneShot(time,VibrationEffect.DEFAULT_AMPLITUDE));
} else {
//deprecated in API 26
vibrator.vibrate(time);
}
// vibrator.vibrate(VibrationEffect.createOneShot(time,VibrationEffect.DEFAULT_AMPLITUDE));
}
public void Sound(int action) {
int so_sound = sounds.get(action);
final MediaPlayer audio = MediaPlayer.create(this,so_sound);
audio.start();
}
#RequiresApi(api = Build.VERSION_CODES.O)
public void run_feedback(int sound_ID, int time_vibration, int ID){
switch (ID){
case 1:
Vibrate(time_vibration);
break;
case 2:
Sound(sound_ID);
break;
case 3:
Vibrate(time_vibration);
Sound(sound_ID);
break;
default:
Vibrate(time_vibration);
Sound(sound_ID);
break;
}
}
private String getLocalIpAddress() throws UnknownHostException {
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
assert wifiManager != null;
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipInt = wifiInfo.getIpAddress();
return InetAddress.getByAddress(ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(ipInt).array()).getHostAddress();
}
public static int[] unpack(final byte[] byte_array) {
final int[] integerReadings = new int[byte_array.length / 2];
for(int counter = 0, integerCounter = 0; counter < byte_array.length;) {
integerReadings[integerCounter] = convertTwoBytesToInteger(byte_array[counter], byte_array[counter + 1]);
counter += 2;
integerCounter++;
}
return integerReadings;
}
private static int convertTwoBytesToInteger(final byte byte1, final byte byte2) {
final int unsignedInteger1 = getUnsignedInteger(byte2);
final int unsignedInteger2 = getUnsignedInteger(byte1);
int unsignedInteger = unsignedInteger1 * 256 + unsignedInteger2;
if ((unsignedInteger)>32768) {
unsignedInteger = unsignedInteger - 65536;
}
return unsignedInteger;
}
private static int getUnsignedInteger(final byte b) {
int unsignedInteger = b;
if(b < 0) {
unsignedInteger = b + 256;
}
return unsignedInteger;
}
public static float from_bytes_to_float (byte [] array, int index) {
byte [] bytes = new byte [4];
for(int j = 0; j < bytes.length; j++) {
bytes[j] = array[index+j];
}
int asInt = (bytes[0] & 0xFF)
| ((bytes[1] & 0xFF) << 8)
| ((bytes[2] & 0xFF) << 16)
| ((bytes[3] & 0xFF) << 24);
return Float.intBitsToFloat(asInt);
}
public static float average_list (List<Float> list, int n_elements) {
if (list == null) {
return 100/n_elements;
} else {
float value = 0;
for(int j = 0; j < list.size(); j++) {
value = value + list.get(j);
}
return value/n_elements;
}
}
public static float average_listInt (List<Integer> list, int n_elements) {
if (list == null) {
return 100/n_elements;
}
else {
float value = 0;
for(int j = 0; j < list.size(); j++) {
value += list.get(j);
}
return value/n_elements;
}
}
class Thread1 implements Runnable {
#Override
public void run() {
// Socket socket;
try {
serverSocket = new ServerSocket(SERVER_PORT);
runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
try {
socket = serverSocket.accept();
client_connected++ ;
output = new PrintWriter(socket.getOutputStream());
inputStream = new DataInputStream(socket.getInputStream());
runOnUiThread(new Runnable() {
#Override
public void run() {
tvMessages.append("Client 1 Connected\n");
btn_client_1.setEnabled(true);
if(client_connected == 3) {
// new Thread(new MainActivity.Thread2()).start();
tvMessages.append("You can start your recording...\n");
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Thread11 implements Runnable {
#Override
public void run() {
try {
serverSocket_2 = new ServerSocket(SERVER_PORT_2);
runOnUiThread(new Runnable() {
#Override
public void run(){
}
});
try {
socket_2 = serverSocket_2.accept();
client_connected++ ;
output_2 = new PrintWriter(socket_2.getOutputStream());
inputStream_2 = new DataInputStream(socket_2.getInputStream());
runOnUiThread(new Runnable() {
#Override
public void run() {
tvMessages.append("Client 2 Connected\n");
btn_client_2.setEnabled(true);
if(client_connected == 3) {
tvMessages.append("You can start your recording...\n");
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Thread111 implements Runnable {
#Override
public void run() {
try {
serverSocket_3 = new ServerSocket(SERVER_PORT_3);
runOnUiThread(new Runnable() {
#Override
public void run(){
}
});
try {
socket_3 = serverSocket_3.accept();
client_connected++ ;
output_3 = new PrintWriter(socket_3.getOutputStream());
inputStream_3 = new DataInputStream(socket_3.getInputStream());
runOnUiThread(new Runnable() {
#Override
public void run() {
tvMessages.append("Client 3 Connected\n");
btn_client_3.setEnabled(true);
if(client_connected == 3) {
tvMessages.append("You can start your recording...\n");
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Thread_BioFeedback implements Runnable {
private int case_audio;
private int ID;
Thread_BioFeedback(int case_audio, int ID) {
this.case_audio = case_audio;
this.ID = ID;
}
#Override
#RequiresApi(api = Build.VERSION_CODES.O)
public void run() {
int time_vibration = 2000;
run_feedback(case_audio,time_vibration, ID);
}
}
public class TimeStamp {
int prevSample1;
int prevSample2;
int prevSample3;
int currSample1;
int currSample2;
int currSample3;
}
public void checkSampleTime(TimeStamp timeStamp) {
if (btn_client_1.isEnabled()) {
int diff_1 = timeStamp.currSample1 - timeStamp.prevSample1;
if (diff_1 != 10) {
tvMessages.append("sampleTime1 Failure\n");
new Thread(new MainActivity.Thread_BioFeedback(5,3)).start();
}
}
if (btn_client_2.isEnabled()) {
int diff_2 = timeStamp.currSample2 - timeStamp.prevSample2;
if (diff_2 != 10) {
tvMessages.append("sampleTime2 Failure\n");
new Thread(new MainActivity.Thread_BioFeedback(6,3)).start();
}
}
if (btn_client_3.isEnabled()) {
int diff_3 = timeStamp.currSample3 - timeStamp.prevSample3;
if (diff_3 != 10) {
tvMessages.append("sampleTime3 Failure\n");
new Thread(new MainActivity.Thread_BioFeedback(7,3)).start();
}
}
}
private class Thread2 implements Runnable {
#Override
public void run() {
TimeStamp timeStamp = new TimeStamp();
while (true) {
try {
byte[] buffX = new byte[BUFFER_LENGTH*2-8];
byte[] buffX_2 = new byte[BUFFER_LENGTH*2-8];
byte[] buffX_3 = new byte[BUFFER_LENGTH*2-8];
if (btn_client_1.isEnabled()) {
int k = inputStream.read(buffX);
byte[] c = new byte[buffX.length + client1.length];
System.arraycopy(buffX, 0, c, 0, buffX.length);
System.arraycopy(client1, 0, c, buffX.length, client1.length);
fou.write(c);
float pitch_1 = from_bytes_to_float(buffX,18);
pitch_buff_1.add(pitch_1);
int [] data = unpack(buffX);
lc_buff_1.add(data[13]);
if (flag_Acq_1 == 1){
// timeStamp.currSample1 = (data[16]<<16) | (data[15] & 0xFFFF);
timeStamp.currSample1 = (data[15]<<16) | (data[14] & 0xFFFF);
flag_Acq_1 = 0;
} else {
timeStamp.prevSample1 = timeStamp.currSample1;
timeStamp.currSample1 = (data[15]<<16) | (data[14] & 0xFFFF);
}
}
if (btn_client_2.isEnabled()) {
int k_2 = inputStream_2.read(buffX_2);
byte[] c_2 = new byte[buffX_2.length + client2.length];
System.arraycopy(buffX_2, 0, c_2, 0, buffX_2.length);
System.arraycopy(client2, 0, c_2, buffX_2.length, client2.length);
fou.write(c_2);
float pitch_2 = from_bytes_to_float(buffX_2,18);
pitch_buff_2.add(pitch_2);
int [] data_2 = unpack(buffX_2);
lc_buff_2.add(data_2[13]);
if (flag_Acq_2 == 1){
timeStamp.currSample2 = (data_2[15]<<16) | (data_2[14] & 0xFFFF);
flag_Acq_2 = 0;
} else {
timeStamp.prevSample2 = timeStamp.currSample2;
timeStamp.currSample2 = (data_2[15]<<16) | (data_2[14] & 0xFFFF);
}
}
if (btn_client_3.isEnabled()) {
int k_3 = inputStream_3.read(buffX_3);
byte[] c_3 = new byte[buffX_3.length + client3.length];
System.arraycopy(buffX_3, 0, c_3, 0, buffX_3.length);
System.arraycopy(client3, 0, c_3, buffX_3.length, client3.length);
fou.write(c_3);
float pitch_3 = from_bytes_to_float(buffX_3,18);
pitch_buff_3.add(pitch_3);
int [] data_3 = unpack(buffX_3);
lc_buff_3.add(data_3[13]);
if (flag_Acq_3 == 1){
timeStamp.currSample3 = (data_3[15]<<16) | (data_3[14] & 0xFFFF);
flag_Acq_3 = 0;
} else {
timeStamp.prevSample3 = timeStamp.currSample3;
timeStamp.currSample3 = (data_3[15]<<16) | (data_3[14] & 0xFFFF);
}
}
if (flag_Acq == 1) {
flag_Acq = 0;
} else {
checkSampleTime(timeStamp);
}
if (message != null) {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (x%plot_freq==0) {
float value = average_list(pitch_buff_1, plot_freq);
float value_2 = average_list(pitch_buff_2, plot_freq);
float value_3 = average_list(pitch_buff_3, plot_freq);
float lc_avg = average_listInt(lc_buff_1, plot_freq);
float lc_avg_2 = average_listInt(lc_buff_2, plot_freq);
float lc_avg_3 = average_listInt(lc_buff_3, plot_freq);
if (y>=4000) {
series.resetData(new DataPoint[] {new DataPoint(x, value)});
series_2.resetData(new DataPoint[] {new DataPoint(x, value_2)});
series_3.resetData(new DataPoint[] {new DataPoint(x, value_3)});
lc.resetData(new DataPoint[] {new DataPoint(x, lc_avg)});
lc2.resetData(new DataPoint[] {new DataPoint(x, lc_avg_2)});
lc3.resetData(new DataPoint[] {new DataPoint(x, lc_avg_3)});
y = 0;
} else {
series.appendData(new DataPoint(x, value),true,500);
series_2.appendData(new DataPoint(x, value_2),true,500);
series_3.appendData(new DataPoint(x, value_3),true,500);
lc.appendData(new DataPoint(x, lc_avg),true,500);
lc2.appendData(new DataPoint(x, lc_avg_2),true,500);
lc3.appendData(new DataPoint(x, lc_avg_3),true,500);
}
pitch_buff_1.clear();
pitch_buff_2.clear();
pitch_buff_3.clear();
lc_buff_1.clear();
lc_buff_2.clear();
lc_buff_3.clear();
Log.v("Plot Update","OK");
}
x += 1;
y += 1;
Log.v("Plot Update",String.valueOf(x));
}
});
} else {
Thread1 = new Thread(new MainActivity.Thread1());
Thread1.start();
return;
}
Thread.sleep(1);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Thread3 implements Runnable {
private String message;
Thread3(String message) {
this.message = message;
}
#Override
public void run() {
if (btn_client_1.isEnabled()) {
output.write(message);
output.flush();
}
if (btn_client_2.isEnabled()) {
output_2.write(message);
output_2.flush();
}
if (btn_client_3.isEnabled()) {
output_3.write(message);
output_3.flush();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
tvMessages.append("server: " + message + "\n");
// etMessage.setText("");
}
});
}
}
}
I'm not sure why the albums aren't being serialized when the users are.
In the admin class, when I login, the userlist is populated in the JCombobox<String> userlist everytime I restart the program.
But the JComboBox<Album> comboBoxAlbumSelect isn't populated every time I restart the program.
Not sure why. Thanks.
Relevant code:
public class Admin extends JFrame implements ActionListener {
Backend backend = new Backend();
GuiCtrl ctrl = new GuiCtrl(backend);
private JComboBox<String> userlist = new JComboBox<String>();
public Admin() {
//same as login
userlist = new JComboBox<String>(getUserList());
}
public String[] getUserList() {
String[] ret = new String[backend.getUserList().size()];
int i = 0;
for (String s : backend.getUserList()) {
System.out.println(s);
ret[i++] = s;
}
return ret;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == logout) {
this.dispose();
new Login();
}
else if (e.getSource() == add) {
try {
if (ctrl.adduser(idNumberTF.getText(), fullNameTF.getText())) {
userlist.addItem(idNumberTF.getText());
backend.storeData();
} catch (IOException|ClassNotFoundException i) {}
}
}
}
public class MainAlbumPanelv2 extends JFrame implements ActionListener {
JButton btnCreateAlbum = new JButton("Create");
JComboBox<Album> comboBoxAlbumSelect = new JComboBox<Album>();
Backend backend = new Backend();
GuiCtrl ctrl = new GuiCtrl(backend);
User loggedInUser;
public MainAlbumPanelv2(User id) {
loggedInUser = id;
comboBoxAlbumSelect = new JComboBox<Album>(getAlbumList());
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btnCreateAlbum) {
if (ctrl.createAlbum(loggedInUser, textFieldCreateAlbum.getText())) {
Album newAlbum = new Album(textFieldCreateAlbum.getText());
comboBoxAlbumSelect.addItem(newAlbum);
}
try {
backend.storeData();
} catch (IOException i) {}
}
}
public Album[] getAlbumList() {
Album[] ret = new Album[loggedInUser.getAlbums().size()];
int i = 0;
for (Album a : loggedInUser.getAlbums()) {
System.out.println(a);
ret[i++] = a;
}
return ret;
}
}
-
public class GuiCtrl {
User loggedInUser;
Backend backend;
public GuiCtrl(Backend backend) {
this.backend = backend;
}
public boolean adduser(String user_id, String user_name) throws IOException, ClassNotFoundException {
if (backend.addUser(new User(user_id, user_name))) {
return true;
} else {
return false;
}
}
public boolean createAlbum(User user_id, String name) {
if (user_id.getAlbum(name) != null) {
return false;
} else {
user_id.addAlbum(name);
return true;
}
}
}
-
public class Backend {
private HashMap<String, User> userList = new HashMap<>();
StringTokenizer tokenizer;
public Backend() {
try {
populateList();
} catch (ClassNotFoundException | IOException e) {
throw new RuntimeException("Cannot read file");
}
}
public boolean addUser(User newUser)
{
String userId = newUser.getID();
if (userList.containsKey(userId)) {
return false;
}
userList.put(userId, newUser);
return true;
}
public void storeData() throws IOException
{
try
{
FileOutputStream file = new FileOutputStream("users.ser");
ObjectOutputStream out = new ObjectOutputStream(file);
out.writeObject(userList);
out.close();
file.close();
}
catch (IOException i)
{
i.printStackTrace();
}
}
public void populateList() throws IOException, ClassNotFoundException
{
try
{
FileInputStream file = new FileInputStream ("users.ser");
ObjectInputStream in = new ObjectInputStream(file);
userList = (HashMap<String, User>) in.readObject();
in.close();
file.close();
}
catch (IOException i)
{
i.printStackTrace();
userList = new HashMap();
}
}
}
public class Album implements Serializable{
private String name;
private ArrayList<Photo> photoList;
public Album(String name)
{
this.name = name;
photoList = new ArrayList<Photo>();
}
}
public class User implements Serializable{
private String id;
private String fullName;
private ArrayList<Album> albumList;
public User(String id, String fullName)
{
this.id = id;
this.fullName = fullName;
albumList = new ArrayList<Album>();
}
public int addAlbum(Album newAlbum)
{
Album currAlbum;
if (newAlbum == null)
{
return 0;
}
for (int x = 0; x < albumList.size(); x++)
{
currAlbum = albumList.get(x);
if (currAlbum.getName().equals(newAlbum.getName()))
{
return 0;
}
}
albumList.add(newAlbum);
return 1;
}
public ArrayList<Album> getAlbums()
{
return albumList;
}
}
I am writing an apk analysis program. I cannot go deep into details because it's research material. However, the point is that from time to time when I execute the analysis routine, I get the following message:
Exception: java.lang.NullPointerException thrown from the UncaughtExceptionHandler in thread "main"
This happens if I do not override the UncaughtExceptionHandler and also if I do, as you'll see from the code below. Since there is no stacktrace data I cannot know where that exception is coming from and what its cause really is.
I hope you can help me...
This is only the main code. There are three main operation that I have to execute. In order not to disclose particular information, I renamed them to A, B and C
public class MainScannerSequential {
public static void main(String[] args) throws ParserConfigurationException, IOException, InterruptedException {
final File target = new File(args[1]);
final File result = new File(args[2]);
final Options options = new Options(args);
silentMode = options.contains("-s");
noA = options.contains("-nl");
noC = options.contains("-ne");
aStrategy = Factory.createA();
bScanner = Factory.createB();
cDetector = Factory.createcC();
examinedFiles = new PersistentFileList(Globals.EXAMINED_FILES_LIST_FILE);
if (result.exists())
resultsWriter = new BufferedWriter(new FileWriter(result, true));
else {
resultsWriter = new BufferedWriter(new FileWriter(result));
resultsWriter.write("***");
resultsWriter.newLine();
}
if (Globals.PERFORMANCE_FILE.exists())
performancesWriter = new BufferedWriter(new FileWriter(Globals.PERFORMANCE_FILE, true));
else {
performancesWriter = new BufferedWriter(new FileWriter(Globals.PERFORMANCE_FILE));
performancesWriter.write("***");
performancesWriter.newLine();
}
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
if ((t != null) && (t.getName() != null))
System.out.println("In thread : " + t.getName());
if ((e != null) && (e.getMessage() != null)) {
System.out.println(e.getClass().getName() + ": " + e.getMessage());
if (e.getStackTrace() != null)
for (StackTraceElement ste : e.getStackTrace())
if (ste != null)
System.out.println(ste.getFileName() + " at line " + ste.getLineNumber());
}
}
});
if (target.isDirectory()) {
enumerateDirectory(target);
} else {
String name = target.getName().toLowerCase();
if (name.endsWith(".apklist"))
readFileList(target);
else if (name.endsWith(".apk"))
checkFile(target);
}
closeWriters();
}
private static void println(String message) {
if (!silentMode)
System.out.println(message);
}
private static void print(String message) {
if (!silentMode)
System.out.print(message);
}
private static void enumerateDirectory(File directory) {
for (File file : directory.listFiles()) {
checkFile(file);
if (file.isDirectory())
enumerateDirectory(file);
}
}
private static void readFileList(File file) {
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = null;
while((line = reader.readLine()) != null) {
File readFile = new File(line);
if (readFile.exists())
checkFile(readFile);
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void checkFile(File file) {
if (examinedFiles.contains(file)) {
println("Skipped: " + file.getName());
return;
}
if (!file.getName().toLowerCase().endsWith(".apk")) {
return;
}
final Wrapper<Double> unpackingTime = new Wrapper<Double>(0.0);
final ApplicationData data = unpack(file, unpackingTime);
if (data == null) {
return;
}
scanData(data, unpackingTime.value);
}
private static ApplicationData unpack(final File file, final Wrapper<Double> unpackingTime) {
final Wrapper<ApplicationData> resultWrapper = new Wrapper<ApplicationData>(null);
final Wrapper<Exception> exceptionWrapper = new Wrapper<Exception>(null);
println("Unpacking: " + file.getName());
unpackingTime.value = Stopwatch.time(new Runnable() {
#Override
public void run() {
try {
resultWrapper.value = ApplicationData.open(file);
} catch (Exception e) {
exceptionWrapper.value = e;
}
}
});
if (resultWrapper.value != null)
println("Unpacked: " + file.getName());
else if (exceptionWrapper.value != null)
println("Dropped: " + file.getName() + " : " + exceptionWrapper.value.getMessage());
return resultWrapper.value;
}
private static void scanData(final ApplicationData applicationData, Double unpackingTime) {
String apkName = applicationData.getDecodedPackage().getOriginalApk().getAbsolutePath();
println("Submitted: " + apkName);
examinedFiles.add(applicationData.getDecodedPackage().getOriginalApk());
final Wrapper<Boolean> aDetected = new Wrapper<Boolean>(false);
final Wrapper<Result> bDetected = new Wrapper<Result>(new Result());
final Wrapper<Boolean> cDetected = new Wrapper<Boolean>(false);
final Wrapper<Double> aDetectionTime = new Wrapper<Double>((double)ANALYSIS_TIMEOUT);
final Wrapper<Double> bDetectionTime = new Wrapper<Double>((double)ANALYSIS_TIMEOUT);
final Wrapper<Double> cDetectionTime = new Wrapper<Double>((double)ANALYSIS_TIMEOUT);
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(new Runnable() {
#Override
public void run() {
textDetectionTime.value = Stopwatch.time(new Runnable() {
#Override
public void run() {
bScanner.setUnpackedApkDirectory(applicationData.getDecodedPackage().getDecodedDirectory());
bDetected.value = bScanner.evaluate();
}
});
}
});
if (!noA)
executor.submit(new Runnable() {
#Override
public void run() {
lockDetectionTime.value = Stopwatch.time(new Runnable() {
#Override
public void run() {
aStrategy.setTarget(applicationData.getDecodedPackage());
aDetected.value = aStrategy.detect();
}
});
}
});
if (!noC)
executor.submit(new Runnable() {
#Override
public void run() {
encryptionDetectionTime.value = Stopwatch.time(new Runnable() {
#Override
public void run() {
cDetector.setTarget(applicationData.getDecodedPackage());
cDetected.value = cDetector.detect();
}
});
}
});
boolean timedOut = false;
executor.shutdown();
try {
if (!executor.awaitTermination(ANALYSIS_TIMEOUT, TimeUnit.SECONDS)) {
executor.shutdownNow();
timedOut = true;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
resultsWriter.write(String.format("%s, %b, %b, %f, %b, \"%s\", %b\n",
apkName,
aDetected.value,
bDetected.value.isAccepted(),
bDetected.value.getScore(),
cDetected.value,
bDetected.value.getComment(),
timedOut));
performancesWriter.write(String.format("%s, %f, %f, %f, %f, %d, %dl, %dl\n",
apkName,
aDetectionTime.value,
bDetectionTime.value,
cDetectionTime.value,
unpackingTime,
applicationData.getSmaliLoader().getClassesCount(),
applicationData.getSmaliLoader().getTotalClassesSize(),
applicationData.getDecodedPackage().getOriginalApk().length()));
resultsWriter.flush();
performancesWriter.flush();
} catch (IOException e) { }
// No longer deleting temp files
if (!timedOut)
println("Completed: " + apkName);
else {
print("Timeout");
if (bDetectionTime.value == 0) print(" TextDetection");
if (!noA && (aDetectionTime.value == 0)) print(" LockDetection");
if (!noC && (cDetectionTime.value == 0)) print(" EncryptionDetection");
println(": " + apkName);
}
}
private static void closeWriters() throws IOException {
resultsWriter.close();
performancesWriter.close();
examinedFiles.dispose();
}
private static final int ANALYSIS_TIMEOUT = 40; // seconds
private static Boolean silentMode = false;
private static Boolean noA = false;
private static Boolean noC = false;
private static PersistentFileList examinedFiles;
private static BufferedWriter resultsWriter;
private static BufferedWriter performancesWriter;
private static A aStrategy;
private static B bScanner;
private static C cDetector;
}
I labeled the question as multithread because the same happens in the multithreaded version, which I serialized using this code in order to debug that error. Notice that the NullPointerException is in thread main, not in other Executor-spawned threads.
If you don't have a stack trace, it could mean that there are some crazy exceptions thrown in your code (see Exception without stack trace in Java), but it is more likely that the JVM is re-using exception objects as a performance optimization and the -XX:-OmitStackTraceInFastThrow JVM option would help you.
See this article for details
As with basically every exchanger task, I have a producer filling up an empty buffer2, a consumer clearing a full buffer1 and when each thread is done, they should exchange their respective buffers.
I am really unsure about where and how to apply the exchange. I defined readyconsumer and readyproducer as booleans, so that a third thread can check whether it's time to exchange the buffers once both are true. This should solve the problem I had doing it with two threads, where the program was stuck with both threads at wait() (which it unfortunately still is).
This is what the code looks like at the moment. Can anyone help me in which class I have to exchange and at what point in the code? Thank you very much in advance!
class Buffer {
static boolean readyconsumer, readyproducer = false;
volatile int count; // number of put actions
static int max = 10;
Buffer() {
count = 0;
}
public synchronized void put() {
if (count == max) {
readyproducer = true;
System.out.println(" wait ");
try {
wait();
} catch (InterruptedException e) {
}
}
count++;
System.out.println("put " + count);
notifyAll();
}
public synchronized void get() {
if (count == 0) {
readyconsumer = true;
System.out.println(" wait");
try {
wait();
} catch (InterruptedException e) {
}
}
count--;
System.out.println("get " + count);
notifyAll();
}
}
class CheckandSwitch extends ProdCon {
public void run() {
while (true) {
if (Buffer.readyconsumer && Buffer.readyproducer) {
try {
ProdCon.buffer2 = exchanger.exchange(ProdCon.buffer1);
ProdCon.buffer1 = exchanger.exchange(ProdCon.buffer2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Buffer.readyconsumer = false;
Buffer.readyproducer = false;
buffer1.count = 0;
buffer2.count = 10;
notifyAll();
}
}
}
}
class Consumer extends ProdCon {
static Buffer buffer;
Consumer(Buffer b) {
super();
buffer = b;
b.count = 10;
}
public void run() {
while (true) {
consume();
buffer.get();
}
}
private void consume() {
System.out.println("consume");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
class Producer extends ProdCon {
static Buffer buffer;
Producer(Buffer b) {
super();
buffer = b;
b.count = 0;
}
public void run() {
while (true) {
produce();
buffer.put();
}
}
private void produce() {
System.out.println("produce ");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
}
}
import java.util.concurrent.*;
public class ProdCon extends Thread {
static Exchanger<Buffer> exchanger = new Exchanger<Buffer>();
static Buffer buffer1, buffer2 = null;
public static void main(String[] args) {
buffer1 = new Buffer();
buffer2 = new Buffer();
new Consumer(buffer1).start();
new Producer(buffer2).start();
new CheckandSwitch().start();
}
}
You could use an Exchanger.
Here's the code from the javadoc tweaked into a working example.
class DataBuffer<T> {
T data = null;
public boolean isFull() {
return data != null;
}
public boolean isEmpty() {
return data == null;
}
public T get() {
T d = data;
data = null;
return d;
}
public void put(T data) {
this.data = data;
}
}
class FillAndEmpty {
Exchanger<DataBuffer<Integer>> exchanger = new Exchanger<>();
DataBuffer<Integer> initialEmptyBuffer = new DataBuffer<>();
DataBuffer<Integer> initialFullBuffer = new DataBuffer<>();
int countDown = 10;
class FillingLoop implements Runnable {
#Override
public void run() {
DataBuffer currentBuffer = initialEmptyBuffer;
try {
while (currentBuffer != null && countDown > 0) {
addToBuffer(currentBuffer);
if (currentBuffer.isFull()) {
currentBuffer = exchanger.exchange(currentBuffer);
}
}
} catch (InterruptedException ex) {
}
}
private void addToBuffer(DataBuffer<Integer> currentBuffer) {
currentBuffer.put(countDown--);
}
}
class EmptyingLoop implements Runnable {
#Override
public void run() {
DataBuffer<Integer> currentBuffer = initialFullBuffer;
try {
while (currentBuffer != null) {
takeFromBuffer(currentBuffer);
if (currentBuffer.isEmpty()) {
currentBuffer = exchanger.exchange(currentBuffer);
}
}
} catch (InterruptedException ex) {
}
}
private void takeFromBuffer(DataBuffer<Integer> currentBuffer) {
System.out.println(currentBuffer.get());
}
}
void start() {
new Thread(new FillingLoop()).start();
new Thread(new EmptyingLoop()).start();
}
}
public void test() {
System.out.println("Hello");
new FillAndEmpty().start();
}
i have written a java code to transfer files from one server to another using the concept of socket programming. now in the same code i also want to check for the network connection availability before each file is transferred. i also want that the files transferred should be transferred according to their numerical sequence. And while the files are being transferred the transfer progress of each file i.e the progress percentage bar should also be visible on the screen.
i will really appreciate if someone can help me with the code. i am posting the code i have written for file transfer.
ClientMain.java
import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class ClientMain {
private DirectoryTxr transmitter = null;
Socket clientSocket = null;
private boolean connectedStatus = false;
private String ipAddress;
String srcPath = null;
String dstPath = "";
public ClientMain() {
}
public void setIpAddress(String ip) {
this.ipAddress = ip;
}
public void setSrcPath(String path) {
this.srcPath = path;
}
public void setDstPath(String path) {
this.dstPath = path;
}
private void createConnection() {
Runnable connectRunnable = new Runnable() {
public void run() {
while (!connectedStatus) {
try {
clientSocket = new Socket(ipAddress, 3339);
connectedStatus = true;
transmitter = new DirectoryTxr(clientSocket, srcPath, dstPath);
} catch (IOException io) {
io.printStackTrace();
}
}
}
};
Thread connectionThread = new Thread(connectRunnable);
connectionThread.start();
}
public static void main(String[] args) {
ClientMain main = new ClientMain();
main.setIpAddress("10.6.3.92");
main.setSrcPath("E:/temp/movies/");
main.setDstPath("D:/tcp/movies");
main.createConnection();
}
}
(DirectoryTxr.java)
import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class DirectoryTxr {
Socket clientSocket = null;
String srcDir = null;
String dstDir = null;
byte[] readBuffer = new byte[1024];
private InputStream inStream = null;
private OutputStream outStream = null;
int state = 0;
final int permissionReqState = 1;
final int initialState = 0;
final int dirHeaderSendState = 2;
final int fileHeaderSendState = 3;
final int fileSendState = 4;
final int fileFinishedState = 5;
private boolean isLive = false;
private int numFiles = 0;
private int filePointer = 0;
String request = "May I send?";
String respServer = "Yes,You can";
String dirResponse = "Directory created...Please send files";
String fileHeaderRecvd = "File header received ...Send File";
String fileReceived = "File Received";
String dirFailedResponse = "Failed";
File[] opFileList = null;
public DirectoryTxr(Socket clientSocket, String srcDir, String dstDir) {
try {
this.clientSocket = clientSocket;
inStream = clientSocket.getInputStream();
outStream = clientSocket.getOutputStream();
isLive = true;
this.srcDir = srcDir;
this.dstDir = dstDir;
state = initialState;
readResponse(); //starting read thread
sendMessage(request);
state = permissionReqState;
} catch (IOException io) {
io.printStackTrace();
}
}
private void sendMessage(String message) {
try {
sendBytes(request.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
/**
* Thread to read response from server
*/
private void readResponse() {
Runnable readRunnable = new Runnable() {
public void run() {
while (isLive) {
try {
int num = inStream.read(readBuffer);
if (num > 0) {
byte[] tempArray = new byte[num];
System.arraycopy(readBuffer, 0, tempArray, 0, num);
processBytes(tempArray);
}
} catch (SocketException se) {
System.exit(0);
} catch (IOException io) {
io.printStackTrace();
isLive = false;
}
}
}
};
Thread readThread = new Thread(readRunnable);
readThread.start();
}
private void sendDirectoryHeader() {
File file = new File(srcDir);
if (file.isDirectory()) {
try {
String[] childFiles = file.list();
numFiles = childFiles.length;
String dirHeader = "$" + dstDir + "#" + numFiles + "&";
sendBytes(dirHeader.getBytes("UTF-8"));
} catch (UnsupportedEncodingException en) {
en.printStackTrace();
}
} else {
System.out.println(srcDir + " is not a valid directory");
}
}
private void sendFile(String dirName) {
File file = new File(dirName);
if (!file.isDirectory()) {
try {
int len = (int) file.length();
int buffSize = len / 8;
//to avoid the heap limitation
RandomAccessFile raf = new RandomAccessFile(file, "rw");
FileChannel channel = raf.getChannel();
int numRead = 0;
while (numRead >= 0) {
ByteBuffer buf = ByteBuffer.allocate(1024 * 100000);
numRead = channel.read(buf);
if (numRead > 0) {
byte[] array = new byte[numRead];
System.arraycopy(buf.array(), 0, array, 0, numRead);
sendBytes(array);
}
}
System.out.println("Finished");
} catch (IOException io) {
io.printStackTrace();
}
}
}
private void sendHeader(String fileName) {
try {
File file = new File(fileName);
if (file.isDirectory())
return;//avoiding child directories to avoid confusion
//if want we can sent them recursively
//with proper state transitions
String header = "&" + fileName + "#" + file.length() + "*";
sendHeader(header);
sendBytes(header.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
private void sendBytes(byte[] dataBytes) {
synchronized (clientSocket) {
if (outStream != null) {
try {
outStream.write(dataBytes);
outStream.flush();
} catch (IOException io) {
io.printStackTrace();
}
}
}
}
private void processBytes(byte[] data) {
try {
String parsedMessage = new String(data, "UTF-8");
System.out.println(parsedMessage);
setResponse(parsedMessage);
} catch (UnsupportedEncodingException u) {
u.printStackTrace();
}
}
private void setResponse(String message) {
if (message.trim().equalsIgnoreCase(respServer) && state == permissionReqState) {
state = dirHeaderSendState;
sendDirectoryHeader();
} else if (message.trim().equalsIgnoreCase(dirResponse) && state == dirHeaderSendState) {
state = fileHeaderSendState;
if (LocateDirectory()) {
createAndSendHeader();
} else {
System.out.println("Vacant or invalid directory");
}
} else if (message.trim().equalsIgnoreCase(fileHeaderRecvd) && state == fileHeaderSendState) {
state = fileSendState;
sendFile(opFileList[filePointer].toString());
state = fileFinishedState;
filePointer++;
} else if (message.trim().equalsIgnoreCase(fileReceived) && state == fileFinishedState) {
if (filePointer < numFiles) {
createAndSendHeader();
}
System.out.println("Successfully sent");
} else if (message.trim().equalsIgnoreCase(dirFailedResponse)) {
System.out.println("Going to exit....Error ");
// System.exit(0);
} else if (message.trim().equalsIgnoreCase("Thanks")) {
System.out.println("All files were copied");
}
}
private void closeSocket() {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private boolean LocateDirectory() {
boolean status = false;
File file = new File(srcDir);
if (file.isDirectory()) {
opFileList = file.listFiles();
numFiles = opFileList.length;
if (numFiles <= 0) {
System.out.println("No files found");
} else {
status = true;
}
}
return status;
}
private void createAndSendHeader() {
File opFile = opFileList[filePointer];
String header = "&" + opFile.getName() + "#" + opFile.length() + "*";
try {
state = fileHeaderSendState;
sendBytes(header.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
}
}
private void sendListFiles() {
createAndSendHeader();
}
}
(ServerMain.java)
public class ServerMain {
public ServerMain() {
}
public static void main(String[] args) {
DirectoryRcr dirRcr = new DirectoryRcr();
}
}
(DirectoryRcr.java)
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
public class DirectoryRcr {
String request = "May I send?";
String respServer = "Yes,You can";
String dirResponse = "Directory created...Please send files";
String dirFailedResponse = "Failed";
String fileHeaderRecvd = "File header received ...Send File";
String fileReceived = "File Received";
Socket socket = null;
OutputStream ioStream = null;
InputStream inStream = null;
boolean isLive = false;
int state = 0;
final int initialState = 0;
final int dirHeaderWait = 1;
final int dirWaitState = 2;
final int fileHeaderWaitState = 3;
final int fileContentWaitState = 4;
final int fileReceiveState = 5;
final int fileReceivedState = 6;
final int finalState = 7;
byte[] readBuffer = new byte[1024 * 100000];
long fileSize = 0;
String dir = "";
FileOutputStream foStream = null;
int fileCount = 0;
File dstFile = null;
public DirectoryRcr() {
acceptConnection();
}
private void acceptConnection() {
try {
ServerSocket server = new ServerSocket(3339);
socket = server.accept();
isLive = true;
ioStream = socket.getOutputStream();
inStream = socket.getInputStream();
state = initialState;
startReadThread();
} catch (IOException io) {
io.printStackTrace();
}
}
private void startReadThread() {
Thread readRunnable = new Thread() {
public void run() {
while (isLive) {
try {
int num = inStream.read(readBuffer);
if (num > 0) {
byte[] tempArray = new byte[num];
System.arraycopy(readBuffer, 0, tempArray, 0, num);
processBytes(tempArray);
}
sleep(100);
} catch (SocketException s) {
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException i) {
i.printStackTrace();
}
}
}
};
Thread readThread = new Thread(readRunnable);
readThread.start();
}
private void processBytes(byte[] buff) throws InterruptedException {
if (state == fileReceiveState || state == fileContentWaitState) {
//write to file
if (state == fileContentWaitState)
state = fileReceiveState;
fileSize = fileSize - buff.length;
writeToFile(buff);
if (fileSize == 0) {
state = fileReceivedState;
try {
foStream.close();
} catch (IOException io) {
io.printStackTrace();
}
System.out.println("Received " + dstFile.getName());
sendResponse(fileReceived);
fileCount--;
if (fileCount != 0) {
state = fileHeaderWaitState;
} else {
System.out.println("Finished");
state = finalState;
sendResponse("Thanks");
Thread.sleep(2000);
System.exit(0);
}
System.out.println("Received");
}
} else {
parseToUTF(buff);
}
}
private void parseToUTF(byte[] data) {
try {
String parsedMessage = new String(data, "UTF-8");
System.out.println(parsedMessage);
setResponse(parsedMessage);
} catch (UnsupportedEncodingException u) {
u.printStackTrace();
}
}
private void setResponse(String message) {
if (message.trim().equalsIgnoreCase(request) && state == initialState) {
sendResponse(respServer);
state = dirHeaderWait;
} else if (state == dirHeaderWait) {
if (createDirectory(message)) {
sendResponse(dirResponse);
state = fileHeaderWaitState;
} else {
sendResponse(dirFailedResponse);
System.out.println("Error occurred...Going to exit");
System.exit(0);
}
} else if (state == fileHeaderWaitState) {
createFile(message);
state = fileContentWaitState;
sendResponse(fileHeaderRecvd);
} else if (message.trim().equalsIgnoreCase(dirFailedResponse)) {
System.out.println("Error occurred ....");
System.exit(0);
}
}
private void sendResponse(String resp) {
try {
sendBytes(resp.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
private boolean createDirectory(String dirName) {
boolean status = false;
dir = dirName.substring(dirName.indexOf("$") + 1, dirName.indexOf("#"));
fileCount = Integer.parseInt(dirName.substring(dirName.indexOf("#") + 1, dirName.indexOf("&")));
if (new File(dir).mkdir()) {
status = true;
System.out.println("Successfully created directory " + dirName);
} else if (new File(dir).mkdirs()) {
status = true;
System.out.println("Directories were created " + dirName);
} else if (new File(dir).exists()) {
status = true;
System.out.println("Directory exists" + dirName);
} else {
System.out.println("Could not create directory " + dirName);
status = false;
}
return status;
}
private void createFile(String fileName) {
String file = fileName.substring(fileName.indexOf("&") + 1, fileName.indexOf("#"));
String lengthFile = fileName.substring(fileName.indexOf("#") + 1, fileName.indexOf("*"));
fileSize = Integer.parseInt(lengthFile);
dstFile = new File(dir + "/" + file);
try {
foStream = new FileOutputStream(dstFile);
System.out.println("Starting to receive " + dstFile.getName());
} catch (FileNotFoundException fn) {
fn.printStackTrace();
}
}
private void writeToFile(byte[] buff) {
try {
foStream.write(buff);
} catch (IOException io) {
io.printStackTrace();
}
}
private void sendBytes(byte[] dataBytes) {
synchronized (socket) {
if (ioStream != null) {
try {
ioStream.write(dataBytes);
} catch (IOException io) {
io.printStackTrace();
}
}
}
}
}
ClientMain.java and DirectoryTxr.java are the two classes under client application. ServerMain.java and DirectoryRcr.java are the two classes under Server application.
run the ClientMain.java and ServerMain.java
You can sort an array using Arrays.sort(...)
ie
String[] childFiles = file.list();
Arrays.sort(childFiles);
As I understand it, this will sort the files in natural order, based on the file name.
You can modify this by passing a custom Comparator...
Arrays.sort(childFiles, new Comparator<File>() {...}); // Fill out with your requirements...
Progress monitoring will come down to your requirements. Do you want to see only the overall progress of the number of files, the individual files, a combination of both?
What I've done in the past is pre-iterated the file list, calculated the total number of bytes to be copied and used a ProgressMonitor to display the overall bytes been copied...
Otherwise you will need to supply your own dialog. In either case, you will need use SwingUtilities.invokeLater to update them correctly.
Check out Concurrency in Swing for more details.
Network connectivity is subjective. You could simply send a special "message" to there server and wait for a response, but this only suggests that the message was sent and a recipt was received. It could just as easily fail when you start transfering the file again...