Can a Java application detect that a debugger is attached? - java

I know about the (jvm) startup options to have the jvm wait until a debugger is attached - this is not what I mean here.
Is it possible from within Java code to also detect attachment of a debugger, so that I could e.g. write a "script" that is doing some stuff and then at a certain point make my app wait for the debugger?

No. The options are JVM options, and no Javacode is executed before the debugger connects. You can however let the app start, and spinloop on a getter for a variable, which you set from the debugger to let your app continue.

Depending on what you'd like to do, it might be worthwhile investigating the onthrow JDWP sub-option. I haven't actually tried this ;-) but it seems like you could create a special exception type that you throw and catch to trigger JVM suspension. As shown in the linked examples, combining with launch can provide for some interesting alternatives. Of course, the logic/workflow is different from what you've expressed, but it's something to think about...

see Determine if a java application is in debug mode in Eclipse for detecting debugger
You could user TimerTask to poll for attachment

The consensus is: no. Java does not have the equivalent of:
IsDebuggerPresent (native Windows)
Debugger.IsAttached (.NET)
DebugHook (Delphi)
But the consensus:
How to programmatically detect whether current JVM is connected by a remote debugger?
Can a Java application detect that a debugger is attached?
Determine if a java application is in debug mode in Eclipse
Check whether we are in Intellij IDEA Debugger
How to find out if "debug mode" is enabled
agrees that the best (non-minified) hack is:
public static boolean isDebuggerPresent() {
// Get ahold of the Java Runtime Environment (JRE) management interface
RuntimeMXBean runtime = java.lang.management.ManagementFactory.getRuntimeMXBean();
// Get the command line arguments that we were originally passed in
List<String> args = runtime.getInputArguments();
// Check if the Java Debug Wire Protocol (JDWP) agent is used.
// One of the items might contain something like "-agentlib:jdwp=transport=dt_socket,address=9009,server=y,suspend=n"
// We're looking for the string "jdwp".
boolean jdwpPresent = args.toString().contains("jdwp");
return jdwpPresent;
}
Which will have to suffice until Java officially adds one.

Related

From Ruby to Java - Equivalent to 'Pry'?

I'm just transitioning from Ruby to Java and debugging in Ruby was made much easier via the 'Pry' gem. You could place binding.pry anywhere in the code and upon running the app, the code would stop or 'freeze' at the binding.pry and allow you to manipulate variables, create new objects, return values, etc - essentially it dropped you into a playground environment at that given point in time.
Anything similar in Java?
Debugging is the way to go, if you are used to run IRB/pry/rails console in production then you need to get in the habit of changing your connection settings to production which is very dangerous but an option for a language that does not offer a REPL (read eval print loop) console.
Setup a Java class just to be the entry point of the code you want to debug then add the breakpoints and run it in Debug mode. Every time you need to debug something else, change that entry point class to do something else.
You may as well just use breakpoints in your routes/endpoints, you add a breakpoint to a route and you trigger an API call either with curl, postman or any HTTP client that triggers that route.

How to listen to Process Up or down events in Java?

I have a process running using Systemctl, configured it with Restart=always
so that even if process crashes then it will restart by itself without manual intervention. When that process restarts I want to take some action in my java code. I don't want poll the process. is there anyway to achieve this?
Thanks in advance.
systemd has a D-Bus API that you can use to receive event notifications when a unit changes state, including changes to its ActiveState property that tells you whether it's currently running. See this answer on Unix & Linux StackExchange for more information.
To use this API from a Java program, you'll need a D-Bus library for Java. It looks like there's a DBus-Java library, though it hasn't been updated in a long time. Alternatively, you might be able to have your Java program invoke the command-line dbus-send and/or dbus-monitor programs and read their output.

Debugging in NetBeans without changing focus

I have a program which uses the Robot class in Java to automate a bunch of keypresses and clicks. The problem I am encountering is not being able to set breakpoints on certain methods to debug because the focus would change when I skip to the next expression.
Is there a way I can bypass this by changing the default continue hotkey (F8) in NetBeans to a low-level keyboard hook that will check system wide?
The reason for this is because the macro I am designing runs too fast for me to see each action occurring. If I set breakpoints along the program, I must alt-tab to the IDE and continue to the next breakpoint, which, unfortunately, interferes with the macro.
If you need to interact with the system in a way that interferes with your program, you must separate your debugger from your program.
In other words, run the two on separate machines and do a remote debug from one machine to another.
The easiest way to do so if you don't have or want to use two machines, is to run your program in a virtual machine. A cheap solution is to use vmware player along with a Linux distribution supported by Netbeans.

Determine if a java application is in debug mode in Eclipse

I want to change the logging level depending if I'm debbugging or not, but I can't find a code snippet to check if the application is running in debug mode.
I'm using eclipse to debug the application, so if the solution only works within Eclipse it will be fine.
Found the answer on how-to-find-out-if-debug-mode-is-enabled
boolean isDebug = java.lang.management.ManagementFactory.getRuntimeMXBean().
getInputArguments().toString().contains("-agentlib:jdwp");
This will check if the Java Debug Wire Protocol agent is used.
You could modify the Debug Configuration. For example add a special VM argument only in the Debug Configuration. You can use System.getProperties() to read the supplied arguments.
Even better, modify the configurations (Run and Debug) to load a different logging configuration file. It isn't good if you need to write code to determine the logging level. This should only be a matter of configuration.
There is not an officially sanctioned way to reliably determine if any given JVM is in debug mode from inside the JVM itself, and relying on artifacts will just break your code some time in the future.
You will therefore need to introduce a methology yourself. Suggestions:
A system property.
An environment variable (shell variable like $HOME or %HOME%)
Ask the JVM about the physical location of a given resource - http://www.exampledepot.com/egs/java.lang/ClassOrigin.html - and based on it, make your decision (does the path contain the word "debug"? is it inside a jar or an unpacked class file? etc).
JNDI
The existance or content of a particular resource.
Have you tried add a vm argument in the eclipse run config?
Pass this as a VM Argument
-Ddebug=true
then you can do Boolean.getBoolean("debug") to check this.
If you are setting the debug level from your own program, may be a line like:
public static final boolean DEBUG_MODE = System.getProperty("java.vm.info", "").contains("sharing");
would do the trick.
Just tested it in eclipse3.5:
package test;
public class Test
{
/**
* #param args
*/
public static void main(String[] args)
{
System.out.println(System.getProperty("java.vm.info", ""));
}
}
will display:
mixed mode, sharing
if launched without debug
mixed mode
if executed with debug launcher
Joachim Sauer comments:
This is highly system depending.
I assume the "sharing" indicates that cross-VM class-sharing is active.
This is a very new feature and is only available on some platforms.
Furthermore there can be many possible reasons to en- or disable it, so I wouldn't use this for debug-mode detection.
(Note: I tested it with the latest jdk1.6b14. I leave this as a CW answer.)
Have a look here:
http://wiki.eclipse.org/FAQ_How_do_I_use_the_platform_debug_tracing_facility%3F
Moreover, I think you can't know if your app is run in debug mode. The only thing you can do is to pass an argument to your JVM when you debug.
Manu
If using socket (e.g. 9999) you can call netstat to check if connection was established:
Process p = new ProcessBuilder("netstat", "-n").start();
String stdout = IOUtils.toString(p.getInputStream(), Charset.defaultCharset());
Then scan in stdout for 127.0.0.1:9999.*ESTABLISHED

Fake X11 display?

I have a Java program using AWT which I would like to run on a headless system. The display for the program does nothing other than display stats. When the program finishes, it exits. There is no user interaction on the display. The program creates an output file which I use in my build system.
Is there a way to get the Java program to run without an X11 display configured? Can I force Java to run the program without trying to display anything? I do not have access to the source code (it is just .jar file), so I can't make modifications to the source.
Any thoughts on how I could get this to work?
The underlying question here is how to run Java applications without an X server; providing a "fake" X server is only one option. In Java 1.4 and up, you can do the following:
java -Djava.awt.headless=true
This allows applications which use AWT to run on headless systems even without an X server.
Xvfb can do what you ask for. I've not used it myself, but here is a link to wikipedia: http://en.wikipedia.org/wiki/Xvfb
You can use a vncserver.
vncserver :1001
export DISPLAY=localhost:1001
java..
The added advantages is that you can actually view the gui
using vncserver 'just in case'
Could also run Xvnc in a low resolution and color depth.
As mentioned by Charles Duffy the traditional method is to tell Java to go headless.
Note that you can always mount the jar in Eclipse and use jad+jadclipse to see what it actually does, and perhaps even override a class if you need to by putting another class-file in "front" of it in the classpath.
A facility that might be relevant if the program uses Java2D is that newer Java versions use optimizations in the X11 server to render faster. This alone might be a reason to devote an X11 server attached to a high performance graphics card to your graphics processing.
I've used with great success in the past the PJA libraries, they don't seem to be maintained anymore, but then again, just just want to run...
I was able to get headless mode in OpenJFX with the command line arguments
-Dglass.platform=Monocle -Dmonocle.platform=Headless -Dprism.order=sw

Categories