Java/Android - Getting socket output stream breaks execution with no exception launched - java

I'm debugging the thread which manages a socket and I noticed that when I call getOutputStream() the debug breaks with no exception thrown. I've even added breakpoints to the very Socket.getOutputStream() but there is no way to get what's wrong.
The Java server correctly accepts the connection and waits for input (by checking inputStream.available()).
Both Socket and ServerSocket come from SSLSocketFactory and SSLServerSocketFactory.
I'm using Android Studio.
What am I doing wrong?
edit: I've even tried to change structure from Thread to AsyncTask but the result is the same. This is frustrating.

Debugging network connections is a bit tricky as time-outs may occur.
I am also unsure if breakpoints on non-app-code (like Socket.getOutputStream()) will really work. The SDK code in AndroidStudio may be different to the one used by your devices which mean that breakpoints (which are set to a specific line) may end up in a totally different method (if they work at all).
Therefore I would suggest to change your code and add log statements and if necessary sleep commands to slow-down the important parts.
For SSL traffic I strongly suggest to look also at the transferred data. There are apps capturing the traffic on-device that run without root permissions. Later you can then debug the traffic on the PC using Wireshark and see if the problem was caused by a communication problem between your client and the server.

Related

Detect when computer goes into sleep mode [duplicate]

Is there a way for a Java program to detect when the operating system is about to go to sleep, or failing that, at least detecting a wake up?
The actual problem is that in a particular application a number of MySQL database operations are run in the background. In testing on a Windows machine these database transactions are interrupted after a sleep/wake-up cycle causing a ton of error conditions in the program. These errors typically look something like this:
java.net.SocketException
MESSAGE: Software caused connection abort: recv failed
If we could react to a 'will sleep soon' event we could attempt to pause background operations preempting the problem. Less ideally if we could react to a 'just woke up' event we could at least suppress the error messages.
You could detect the wakeup by periodically comparing the current system time to the previous system time.
Edit: here's an example that looks like it would help you detect when the machine is going to sleep:
http://www.codeguru.com/cpp/w-p/system/messagehandling/article.php/c6907
I know it's not exactly what you're looking for, but maybe the right answer is to try to write the code with the assumption that your sockets won't necessarily stay up. There are lots of reasons why the connection could crash, for example because the DB is taken down for maintenance, or because someone tripped over your Ethernet cable. I think you'd have similar problems with errors if someone pulled out the network cable while your app was running, and these are not unheard-of conditions, so maybe it's a better approach to try and handle those conditions gracefully.
You could just JNI or JNA to trap the sleep/wakeup events from the OS.
From Windows Power Events (MSDN), you would have to create a Window handler and a null window to receive the WM_POWERBROADCAST events. This window procedure could then call an event function in your Java code to bubble the message up.

Crystal Report java library, logon hangs forever

Our project uses Business Objects for reports. Our java webapps that launch reports go thruogh a web service we set up to handle the business rules of how we want to launch them. Works great...with one wrinkle.
BO appears to be massively unreliable. The thing frequently goes down or fails to come up after a nightly timed restart. Our Ops team has sort of gotten used to this as a fact of life.
But the part of that which impacts me, on the java team, is our webservice tries to log on to BO, and instead of timing our or erroring like it should, the BO java library hangs forever. Evidently it is connecting to a half-started BO, and never gives up.
Looking around the internet, it appears that others have experienced this, but none of the things I see suggests how to set a timeout on the logon process so that if it fails, the web service doesn't lock up forever (which in turn can cause our app server to become unstable).
The connection is pretty simple:
session = CrystalEnterprise.getSessionMgr().logon(boUserName, boPassword, boServerName, boSecurityType);
All I am looking for is some way to make sure that if BO is dead, my webservice doesn't die with it. A timeout...a way to reliably detect if BO is not started and healthy before trying to logon....something. Our BO "experts" don't seem to think there is anything they can do about BO's instability and they know even less about the java library.
Ideas?
The Java SDK does not detail how to define a timeout when calling logon. I can only assume that this means it falls back on a default network connection timeout.
However, if a connection is made but the SDK doesn't receive the required information (and keeps waiting for an answer), a network timeout will never be reached as this is an application issue, not a network issue.
Therefore, the only thorough solution would be to deal with the instabilities in your BusinessObjects platform (for which you should create a separate question and describe the issue in more detail).
If this is not an option, an alternative could be to launch the connection attempt in a separate thread and implement a timeout yourself, killing the thread when the predefined timeout is reached and optionally retrying the connection attempt several times.
Keep in mind though that while the initial logon might be successful, the instabilities described in your question could cause other issues (e.g. a different SDK call could remain hanging forever due to the same issue that caused your logon call to hang).
Again, the only good solution is to look at the root cause of your platform instabilities.

Java Sockets - Detect network disconnect without inputstream

I've recently been writing java code to send notifications to the Apple Push Notification server. The problem I'm running into is if I create the socket and then disconnect from the network. I've bounced around articles on-line and most suggest relying on the methods:
socket.setKeepAlive(false);
socket.setSoTimeout(1000);
Specifically the "setSoTimeout" method. But the javadoc states that setSoTimeout will only throw an exception when reading from the InputStream. But the Apple Push Notification server never puts any data on the InputStream so I can never read anything from it. Does anyone have any suggestions of how to determine a network disconnect without using the socket InputStream?
You can only reliably detect a Socket has been disconnect when you attempt to write or read from a Socket. Reading is better because writing often takes a while to detect a failure.
The server doesn't need to write anything for you to attempt to read it. If you have a server which never writes you will either read nothing or detect a failure.
A quick precision: APNS will return data on your InputStream if you are using the enhanced notification format and that some error occurs. You should therefore make sure you do not ignore your InputStream...
Unless you are doing this as a personal learning project, you might want to take a look at existing APNS-specific Java libraries that deal with all the communication details for you. Communicating reliably with APNS is much more difficult than it looks at first, especially when you get to the error management part which involves various vague or undocumented details.

Pattern for working with process that may throw OutOfMemoryError

I have a Java client - server application. The client is designed to run arbitrary user code. If the user code running on the client creates an OutOfMemoryError then the client ends up in an ugly state. Normally the client would be sending messages (via RMI) to the server until the code the client is running terminates and the client gracefully disconnects with the server.
What would people recommend for the OOM situation on the client? Could I catch it and kill the client process? Presumably I would not be able to push any commands out from the server because the client will be unresponsive.
If possible, I would like the client process to be terminated without having to log on to the client machine and kill it "by hand". Clearly it would be best if the user code did not cause this error in the first place, but that is up to the user to debug and my framework to deal with in as friendly way as possible. Thanks for your ideas!
It's a bad idea to catch OutOfMemoryError. If you catch it, you'll probably not have enough memory to kill the process anyway...
One good practice when developing a server side application is to use a socket timeout. If your client doesn't send any command for a given amount of time, the connection is dropped. This makes your server more reliable, more secure, and prevents situations like yours happening.
Another thing you can do is to try to make your client app "OutOfMemoryError proof", not in the way that it can't run out of memory, but in the way that it shouldn't make your application crash.
You could define some 'reserve memory' you could catch the exception and deal with it (at least in most cases). But you need to make sure the chunk is large enough. This works as follows:
static byte[] reserveMemory = new byte[1024 * 1024];
try {
...
} catch (OutOfMemoryError e) {
reserveMemory = null;
cleanUpAndExit();
}
You could do a few things. 1 is spawn the user code into it's own process and watch it. If it failed, you could then notify the back end server of the failure so it could clean up the connection.
You could use a stateless server (which may not be possible) with asynchronous communication protocols (such as HTTPInvoker) instead of RMI. (Again, this may not be possible depending on what you are trying to do).
You could watch the memory usage in the client and kill the thread that is running the client code when the memory hits a certain point, and then have the watcher close out the connection, notifying the server of the problem.
Or, as Vivien Barousse mentioned, you could have a low timeout on the server side to prevent the situation.
Hope these help.
If you're routinely getting out-of-memory errors, I think the real solution is not to find a way to catch them, as all that that accomplishes is allowing you to die a less dramatic death. The real thing to do is rework your application to not keep running out of memory. What are you doing that you're running out of memory? If you're reading a bunch of data off a database and trying to process it all at once, maybe you can read it in smaller chunks, like one record at a time. If you're creating animations, maybe you can do one frame at a time instead of holding it all in memory at once. Etc.
Wrap a Java client program by another program -- maybe written in C++, Java or any other language (it must not work on the same VM as your client) -- that restart or log an error message.
Your client should log its state (create checkpoints*) every x operation/(...)/on application start and close. So you can implement a functionality in the client that clean up mess -- based on checkpoint info -- if a client is restarted with info that it crashed before. So the wrapper does not need to have any complicated functionality.
ps. OutOfMemory exception is a terminal error so there is no sense to catch it. Of course, sometimes there is enough memory to do something but it is not a rule
Checkpoints/Recovery is an architectural pattern used heavily in dependable systems see http://www.google.de/search?q=dependable+sytem+checkpoints+restore to find a number of publication on this topic.

How to detect dataloss with Java sockets?

I have the following situation: using a "classical" Java server (using ServerSocket) I would like to detect (as rapidly as possible) when the connection with the client failed unexpectedly (ie. non-gracefully / without a FIN packet).
The way I'm simulating this is as follows:
I'm running the server on a Linux box
I connect with telnet to the box
After the connection has succeeded I add "DROP" rule in the box's firewall
What happens is that the sending blocks after ~10k of data. I don't know for how long, but I've waited more than 10 minutes on several occasions. What I've researched so far:
Socket.setSoTimeout - however this affects only reads. If there are only writes, it doesn't have an effect
Checking for errors with PrintWriter.checkError(), since PW swallows the exceptions - however it never returns true
How could I detect this error condition, or at least configure the timeout value? (either at the JVM or at the OS level)
Update: after ~20min checkError returned true on the PrintWriter (using the server JVM 1.5 on a CentOS machine). Where is this timeout value configured?
The ~20 min timeout is because of standard TCP settings in Linux. It's really not a good idea to mess with them unless you know what you're doing. I had a similar project at work, where we were testing connection loss by disconnecting the network cable and things would just hang for a long time, exactly like you're seeing. We tried messing with the following TCP settings, which made the timeout quicker, but it caused side effects in other applications where connections would be broken when they shouldn't, due to small network delays when things got busy.
net.ipv4.tcp_retries2
net.ipv4.tcp_syn_retries
If you check the man page for tcp (man tcp) you can read about what these settings mean and maybe find other settings that might apply. You can either set them directly under /proc/sys/net/ipv4 or use sysctl.conf. These two were the ones we found made the send/recv fail quicker. Try setting them both to 1 and you'll see the send call fail a lot faster. Make sure to take not of the current settings before changing them.
I will reiterate that you really shouldn't mess with these settings. They can have side effects on the OS and other applications. The best solution is like Kitson says, use a heartbeat and/or application level timeout.
Also look into how to create a non-blocking socket, so that the send call won't block like that. Although keep in mind that sending with a non-blocking socket is usually successful as long as there's room in the send buffer. That's why it takes around 10k of data before it blocks, even though you broke the connection before that.
The only sure fire way is to generate application level "checks" instead of relying on the transport level. For example, a bi-directional heartbeat message, where if either end does not get the expected message, it closes and resets the connection.

Categories

Resources