Why can't I try-with-resources in MY servlet? - java

I have a JEE 7 servlet that sends a picture from a networked web cam to the user's browser. If the camera is on, all is well and the image is sent. If the camera is off, my own "DeviceUnavailableException" is thrown. The servlet then sends an alternative image indicating that the camera is off-a kind of friendly visual error message. This is the code:-
protected void processRequest(HttpServletRequest request, HttpServletResponse response) {
try {
ServletOutputStream os = response.getOutputStream(); // Cannot use try-with-resources here!
Camera camera = new Camera(ip, username, password);
byte[] vImage = camera.getEntropy();
response.setContentType("image/jpeg");
System.out.println("Sending visualisation...");
os.write(vImage);
os.close();
} catch (DeviceUnavailableException e) {
System.err.println(e);
try (InputStream is = PhotonicSignalVisualisation.class
.getResourceAsStream("unavailable.png");
ServletOutputStream os = response.getOutputStream()) {
byte[] uImage = new byte[623]; // need to know exact file size of wait.png
is.read(uImage);
response.setContentType("image/png");
System.out.println("Sending unavailable image...");
os.write(uImage);
} catch (IOException ex) {
System.err.println("No luck sending device unavailable image");
System.err.println(e);
}
} catch (IOException e) {
System.err.println(e);
}
}
This code works.
Weird thing is that whilst I can have a try-with-resources (TWR) statement in the DeviceUnavailableException catch block, I can't in the try block at the top. NetBeans suggests I convert to TWR, but when I do, no image is returned to the browser. It appears that os.write(uImage) is executed, but sent elsewhere, not to the browser!
I'm probably approaching this all backwards, but I can't understand the TWR issue here. Is there a better way to handle the friendly error situation? I was trying to avoid a simple broken image icon on the browser when the camera is off.

All the classes inside TWR block should implement AutoCloseable interface.
https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
The try-with-resources statement ensures that each resource is closed
at the end of the statement. Any object that implements
java.lang.AutoCloseable, which includes all objects which implement
java.io.Closeable, can be used as a resource.
Solution: Make your Camera Class implement AutoCloseable.

Related

Connecting arduino to an android app which uses libgdx (using Bluetooth)

so i'm trying to do something a little unusual, it's just for fun. I have a game i created using libgdx, it consists of a ship that can shoot. What i want to do is to use some external push buttons to move it. The push buttons send signals to arduino, which in turn sends them to an HC-05 bluetooth module. however i'm very doubtful about the android side of things. What i did basically was the following:
Because i'm working on libgdx i created an interface called BluetoothDude, with three methods setBluetooth() (which will set the bluetooth for the particular platform),String whatIsTheMessage() (which will tell you what's been sent to the phone), and boolean isActive(), to know if the bluetooth is active of course.
The MainGame will receive a BluetoothDude so that particular classes like Ship have access to the Message and are able to react to it.
Then i did the particular implementation of Bluetooth for android, in the setBluetooth() i followed this guide very closely: https://developer.android.com/guide/topics/connectivity/bluetooth.html
i'm sure it is connecting properly, because when it creates the socket it can print "connection success with HC-05" (it will only print that if the method which creates the sockets, which i called BTConnect() returns true).
The problem seems to be in reading the data, the code i'm using is
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private Handler handler;
public ConnectedThread(BluetoothSocket socket,Handler mHandler) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
handler = mHandler;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024];
int bytes;
while (true) {
try {
bytes = mmInStream.read(buffer);
handler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
break;
}
}
}
i made an object of this class in setBluetooth like this
if (device != null) {
if (BTconnect()) {
isActive = true;
connectedThread = new ConnectedThread(socket,handler);
System.out.println("connection success with" + device.getName() + " message: " + message );
}
i have a lot of doubts
first what is the target here, the mHandler was created in BluetoothDude, so is that the target?, second i'm quite sure the thread isn't even running because if i put a line like System.out.println("run") inside run() it doesn't show me the line like a trillion times in the logcat when the app is executed. What is wrong with it, i hope you can help me, i'm not very experienced at all of this, and it's driving me crazy.
I cannot see if this is the case from your code but if you are calling platform specific methods, that should be done in the platform specific project subproject.
For more information on how to do that you can check out this page :
https://github.com/libgdx/libgdx/wiki/Interfacing-with-platform-specific-code
So if your LibGDX game has a function say, "setBluetooth" each platform will have its own implementation of said method. That will differ when you compile for Android or iOS.
If you try to call platform specific code in your core game probably won't work.
Hope it helps, maybe you have already done that in which case you can ignore my comment.

Writing a String to a webpage in Android

I'm trying to write a String to my webpage using Java in Android Studio by reusing some piece of codes of one Java Eclipse project which works well on my PC.
However, the String just cannot be written to the web page using my Android phone.
public void upload(String FTPaddress, String message){
try {
URL url = new URL(FTPaddress); // my server address
URLConnection urlc = url.openConnection();
OutputStream os = (OutputStream) urlc.getOutputStream(); // To upload
OutputStream buffer = new BufferedOutputStream(os);
buffer.write(message.getBytes());
buffer.close();
os.close();
} catch (FileNotFoundException e) {
// print in log
} catch (IOException e) {
// print in log
}
}
Please note that the function is executed, the mobile phone is connected to the internet, thus I am running it on another thread using asyncTask, and there is no exceptions
So can anyone tell me why it worked on my laptop but not for my mobile phone?

Want to Log any exception, Instead showing in the UI as Unexpected Exception

I am using this code:
Logger.getLogger( SampleAction.class.getName() ).log( Level.SEVERE, null, ex );
for logging the exceptions in the Logger.
Along with logging the exception, it is displaying the Exception in the UI.
How to avoid showing this exception?
How about create another class like this.
public class Log{
FileConnection fc;
OutputStream outStream;
InputStream inStream;
Log(String exceptionClass, String errorMessage){
try{
fc = (FileConnection)Connector.open("[path]");
if(!fc.exists()) fc.create();
inStream = fc.openInputStream();
outStream = fc.openOutputStream();
if(inStream!=null)
outStream.write(IOUtilities.streamToBytes(instream)); //use this so overwriting is enabled
outStream.write((exceptionClass+"\n").getBytes());
outStream.write((errorMessage+"\n").getBytes());
}
catch(IOException e){}
finally{
try{
inStream.close();
outStream.close();
fc.close();
}catch(Exception e){}
}
}
}
Then just call your Log class at every catch of your try block:
e.g.
try{
//your process
}catch(Exception e){
//call log
new Log(e.getClassName(), e.getMessage());
}
you can modify it, better if you write date and time for each log.
There are two things happening:
The logger is logging an exception
The exception is not being caught, or is being propogated, until another piece of code displays it in a dialog box. If you don't want the dialog box shown you will need to handle the Exception before it gets displayed.
Please paste the whole of the method that contains the logging.

Google Drive SDk Connection reset by peer

I am using following code to load public shared images from google drive to android app, but sometimes I got:
javax.net.ssl.SSLException: Read error: ssl=0x1d9ed0: I/O error during system call, Connection reset by peer
Why google drive is closing connection before I download image? This is happening randomly, but quite often. Does someone collide with such problem?
public static InputStream getStream(String url)
{
InputStream is = null;
try
{
is = new URL(url).openConnection().getInputStream();
} catch (MalformedURLException e)
{
L.e(e.toString());
} catch (IOException e)
{
L.e(e.toString());
}
return is;
}
For bitmap loading I use simple code:
BitmapFactory.decodeStream(stream, null, null);
It could be that you are affected by the following: The URL that you get from the file's metadata is short lived. If you are saving that URL to use later it won't work because it could be that the URL gets invalidated.
To do this you have to fetch the image metadata every time to get the new downloadURL.
We are working on providing non expirable URLs in the future.

Android TCP - program crashes

I cant seem to get a simple TCP connection going between a java server application and Android (I have tried both the emulator and the Android Dev Phone 2). I am getting this error on the Emulator "The application Data Receive (process com.mdog.datareceive) has stopped unexpectedly. Please try again."
Forgive me but I am very new to android. So I don't know how to debug it... but I am not trying anything too complex. Eventually I want to try and "consume" the bytes I am receiving in the application. and have the TCP run in the background... but for now simply getting the phone and computer to communicate would be great.
If you can help me that would be awesome.
Code for Android side:
public class Receive extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView tv = new TextView(this);
Socket connectionSocket = null;
byte[] inputHolderByteArray = new byte[5*1024];
/* Connect to Server */
try {
connectionSocket = new Socket("192.168.0.104", 11313);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
/* Send an s to server to start transmission */
try {
PrintWriter out = new PrintWriter(connectionSocket.getOutputStream(), true);
out.print('s');
out.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
/* read server transmission */
try {
connectionSocket.getInputStream().read(inputHolderByteArray);
} catch (IOException e) {
e.printStackTrace();
}
tv.setText("done");
setContentView(tv);
}
}
Each instance of the emulator runs behind a virtual router/firewall service that isolates it from your development machine's network interfaces and settings and from the internet.
The virtual router for each instance manages the 10.0.2/24 network address space — all addresses managed by the router are in the form of 10.0.2., where is a number. Addresses within this space are pre-allocated by the emulator/router.
You have to refer to the development machine with address as: 10.0.2.2 instead of 192.168.0.104 in your case. If you want to refer to another machine in your LAN, then you can Use Network Redirections
http://developer.android.com/guide/developing/tools/emulator.html#emulatornetworking
While superfell is correct that the full stack trace would help diagnose this, based on your code the/a likely problem is that you are breaking up every statement into it separate try/catch blocks. This probably isn't your core issue(my guess is you have a networking issue), but it is what is causing the system to crash.
Typically in Java, statements that are reliant on each other which can throw Exceptions are put in the same try/catch statement. What is most likely happening for you is that the code enters your first try catch block where you try to define a new socket. This fails throwing an exception like 'UnknownHostException'. connectionSocket remains null but the code enters the catch for UnknownHostException. You print the stack trace, but the program doesn't exit. Your code continues on to the following try/catch block where you call
PrintWriter out = new PrintWriter(connectionSocket.getOutputStream(), true);
This causes a NullPointerException. This is a RuntimeException which is not checked and, because it is unchecked, you are not forced to catch it in a catch statement. The exception now causes your VM to crash and causes the error screen you have reported.
So, even though getting the logcat stacktrace will tell us more about your issue, the code you have constructed should be condensed into a single try/catch statement since all code is dependent on the first try/catch completing without error.
Edit:
Try constructing your application like this
public class Receive extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView tv = new TextView(this);
Socket connectionSocket = null;
byte[] inputHolderByteArray = new byte[5*1024];
/* Connect to Server */
try {
connectionSocket = new Socket("192.168.0.104", 11313);
PrintWriter out = new PrintWriter(connectionSocket.getOutputStream(), true);
out.print('s');
out.flush();
connectionSocket.getInputStream().read(inputHolderByteArray);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
tv.setText("done");
setContentView(tv);
}
}
When we say 'get the stacktrace', this means you need to connect to the emulator or device using the android debug bridge (adb) and a program called logcat. If you only have the emulator and no phone connected to your pc, try running the following:
adb logcat *:D
This will output the log information to the terminal. Leave this window open and run your application. You should see a stack trace get printed. Please take the time to get to know logcat and adb.

Categories

Resources