views:

101

answers:

3

How can a Java program find out if it is running in debug mode?

The application should behave a bit different in regular 'full speed' mode than in 'debug mode' (when a debugger is attached, when running in debug mode). The application communicates over TCP with either another computer, another process, or within itself. My co-worker wants us to use Socket.setSoTimeout(1000) by default, so that reads from the socket can block for at most 1 second. When debugging, this is not enough of course, and the application stops working as it should. So a solution would be to set the SO_TIMEOUT higher, but just in debug mode (for example: unlimited). Now, I don't always set breakpoints or don't want use a debug build where I could set the 'debug' property myself. Sometimes I attach the debugger (remote debugging). I'm mainly using Eclipse so a solution that just works there is OK.

Possible answers include:

A) To find out if run in debug mode, use the following method in java.lang.management.* or javax.management.* ...

B) Your co-worker is wrong for reason X, you shouldn't set SO_TIMEOUT to 1 second by default.

Update

I know about the system property approach, but I leave the question open to solve my original question.

+1  A: 

You're solving the wrong problem. Your program doesn't need to know this unless it's dealing with eclipse or jvm internals.

Solution

Use a system property with a default value:

int timeout = Integer.parseInt( 
    System.getProperty("socket.timeout", "1000"));
socket.setSoTimeout(timeout);

And in the debug launch configuration, just add

-Dsocket.timeout=20000

to the call parameters

(If you don't specify the system property, the default value will be used)

References

seanizer
Same here: I wanted to avoid having to set a system property manually.
Thomas Mueller
+5  A: 

Make the timeout configurable. The simplest way is to just use a system property and read it with Integer.getInteger:

private final static int SOCKET_TIMEOUT =
  Integer.getInteger("com.yourapp.module.socketTimeout", 1000); // default 1 sec

Then, when starting your app for debugging, just set the property from the command line (or an appropriate config file, depending on the environment your app runs in):

java -Dcom.yourapp.module.socketTimeout=1000000 MainClass

This is good because it does not magically alter the behavior when you fire the app up in a debugger, and you can change the timeout when not debugging (for example, if you need to run it somewhere with a slow connection, some day).

(Of course, if your system already uses a config file, it may be appropriate to add this value as an entry there instead.)

As to whether one second is an appropriate timeout... that depends completely on the app. Sometimes it's better to give a correct answer eventually, other times failing quickly is better than waiting for success.

gustafc
`Integer.getInteger(..)`? Darn, I didn't know that one. Cool (+1)
seanizer
This is a valid solution of course, but it requires a manual step: setting the system property at startup. I wanted to avoid that.
Thomas Mueller
+2  A: 

I found it out myself now:

boolean isDebug = java.lang.management.ManagementFactory.getRuntimeMXBean().
    getInputArguments().toString().indexOf("-agentlib:jdwp") > 0;

This will check if the Java Debug Wire Protocol agent is used.

Thomas Mueller
Sure, this works, but that's tight coupling to something that doesn't have anything to do with the program.
seanizer
It is a hack because there is no official API to find out if running in debug mode. A system property would be nice. But in the case described above, the program *should* behave differently in debug mode. It's completely on purpose. I just don't want to set the system property *manually* whenever I debug.
Thomas Mueller