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
Related
I've found tons of documentation on how to enable javax.net.debug for SSL, TLS and similar, but even in the reference documentation I've not found how to totally disable it overriding programmatically a previous setting.
My exact problem is that in a Tomcat instance another application performs the following instruction:
System.setProperty("javax.net.debug","all");
and this causes the catalina.out file to rise his dimension quickly and unwanted.
I've already tried to overwrite it from my Java code with the same instruciton, with "none", "off" and "false" values but with no result, still logging a plenty of TLS stuff.
For example in my application I've added this instruction:
System.setProperty("javax.net.debug","none");
but still I'm getting full log.
The problem is that the tomcat application is overwriting whatever value you give from command line, and if there is no way to control what this code is doing, you can't really overwrite it from commandline arguments. While a security manager would be able to prevent setting a property, it can only do so by throwing an exception, which is probably going to cause more issues than it solves.
In this case, your only option is to set the value yourself from code, after the other code sets it.
In case of the javax.net.debug, the option needs to be set to it's final value before the static static initializer of sun.* Debug class runs, which is before the first message would appear. This can be disabled by any value that isn't used as some option (empty string, or none should disable it). If it's set later, it will have no effect with no way to turn it off after the fact (with the exception of doing some bad reflection hacks to access internals of that class anyway, that are only possible with java 8 and earlier)
If there are some VM argument that enable SSL logging try to remove them, in addition you can check eclipse.ini file to see if those arguments are declared there or not.
You can disable it by removing the following from the run configuration in your IDE:
-Djavax.net.debug=all
To anyone who may need this, I set the value to an empty string: System.setProperty("javax.net.debug","");
It worked for me.
In my java project I use a third party library (jar) and call a function of that library at start.
public static void main(String args[]) {
long handle = Library.method(params);
if (0 == handle) {
// error
}
}
Use eclipse for the development. The question is, when I run the project (call the main) in RUN mode, I get the handle. But when I call with DEBUG mode (without any breakpoints attached), I do not get the handle. (The run/debug settings are the same, no additional VM or program parameters)
Question:
How can the library detect that it is called in the debug mode and
prevent returning the handle?
How can I debug this project (I need
some debug)
How can the library detect that it is called in the debug mode and prevent returning the handle?
There are ways, for instance:
How to find out if "debug mode" is enabled
But it is surely not possible to assemble the complete list of possibilities.
How can I debug this project (I need some debug)
You'll either need to find a debuggable version (maybe available from the developer of the library for additional fees?) or overcome the protection.
One-guy-I-know-who-isn't-me would for instance first try to disassemble the library to find out how is it actually protected. If disassembly succeeds then it might be even possible to remove the protection.
I have some Pax Exam tests. To execute the test normally, I just run the JUnit class in Eclipse. If I want to step through the code in the Eclipse debugger, I have to make it set the debug options, including the flag to make it wait for the debugger connection, which is a separate process I have to run. I'm presently having this code check for a "debug" system property to enable this, but that's sort of annoying.
It would be really nice if the #Configuration method can look at a system property or some other condition that will always be true if the code is executing in the debugger, so I could use that as a trigger to enable those flags, instead of a manually set "debug" system property.
I've already tried setting a breakpoint at the top of this method and inspecting all the system properties for something that might be set while in the debugger, but I didn't see anything.
Update:
Just to be clear, I need to point out some details about how Pax Exam tests work, to better explain why I'm looking for a way to improve this process. When the test runs, it forks a Karaf container to run the test in. In order to run a test in the debugger, you have to force the code that runs in the container to set the "suspend=y" flag, which will wait for a debugger connection. You definitely don't want to do that if you're not debugging.
After starting the pax exam test running, you then have to run another debug configuration, to make a remote connection to the karaf container. Technically, the run configuration for the unit test itself doesn't need to be a debug configuration.
So, the easiest way to make this happen is to have the the code that initiates the container check for a "debug" system property (or whatever you want to call it), and when that is set, to set the debugger port and the "suspend=y" flag. If the property is not set, it doesn't do that.
So, if you're running the test without debug, you have to make sure that system property is not set. If you're debugging, you have to make sure it's set. It's an annoyance to have to edit the run configuration each time you need to go back and forth.
So, what I was intending was to start the unit test run configuration as a debug configuration (even though it doesn't need to be), and for the code that starts the karaf container to detect that it's being run as a debug configuration, and set the "suspend=y" flag in that case.
I've concluded that there is no way for the code itself to detect this, but I'll detail in my own answer how I get the debugger to help me a bit.
I'm going to self-answer to address my original problem, although it isn't quite the answer to my original question, which the first answer does attempt to address. That answer doesn't help me, however.
My real need was to able to run my Pax Exam test so that when I first run the unit test, which is running the "server" portion of the Pax Exam test, it will know to provide the correct "-Xdebug" parameters to the server if I'm going to be using the debugger, and NOT to if I'm not using the debugger. I have code that checks for the "debug" system property and uses that to set the correct "-Xdebug" parameters, but I don't want to have to manually add or remove that parameter from the run configuration if I need to change how I'm running the test (going between debugging and not debugging).
So, as far as I can see, the best I can do is make it so that when I run the "server" portion of the unit test in the debugger (which otherwise doesn't actually have to be in the debugger, as it's only the client side that needs it), this will cause the system property I'm checking for to be set, so it will set the correct flags.
I'm not aware of any feature in Eclipse that lets me run particular predefined snippets of code when I start any debugging session (I mean "any", not a "particular" debugging session), but there is something that comes close, even though it's a bit of a hack.
What I did was set a breakpoint at the top of the method that sets the karaf configuration to be started, and I made the breakpoint conditional, with the following expression:
(System.setProperty("debug", "true") != null) && false
This will set the system property I need, but then not stop, as the final expression will be false.
Technically, it doesn't even need to be in this method, it just has to be hit before the karaf options are set.
This stays as a workspace setting, so I don't need to re-add this every time I start Eclipse.
Update:
With the upgrade to Oxygen, this can be slightly simpler, with the new "tracepoints" feature (https://www.eclipse.org/eclipse/news/4.7/jdt.php#toggle-trace-point). Just "toggle tracepoint" and set the expression to 'System.setProperty("debug", "true")'
If you are debugging eclipse application there is a way, you can use Platform.isDebug() to check whether your application is using debug or run lanuch configuration.
In your case i.e checking in Junit test run, I am not aware of how to detect whether we are using run/debug launch config. But strongly believe that there must a way to find it out with code like what you suggested using System Class.
Why can't you pass your own argument/environment variable in Junit debug launch config(With -D= in Arguments tab or in Environment tab? and use it in the test code to detect?
I have some Java code which depends on a system property super.secret.password. I need to set that property when i run my app. The app will be started by a shell script, and the password will be kept in a file with minimal read permissions.
I really don't want to write:
java -Dsuper.secret.password=letmein gov.fortknox.MyApp
Because then anyone who can get on to the machine and run ps or top can see what the password is.
So, is there a good way to set system properties without exposing them on the command line?
The only generic solution we've come up with is to write a small C program which reads system properties from a file, then starts the JVM using the JNI invocation API. Needless to say, we are not keen to do this.
If there isn't a way to set them without using the command line, is there a way to hide the command line from prying eyes? We're using Red Hat Enterprise Linux Server 5.5.
For what it's worth, the app in question is actually JBoss EAP 4.3.0, and we're using the system properties to fill in substitution constructs (${like.this}) in its XML configuration files. There are JBoss-specific solutions - either use the SystemPropertiesService (by default, configured through the properties-service.xml file in the deploy directory) or pass the -P option to run.sh. However, i am interested in the more general case, where this could be any Java program.
You could just read the file somewhere near startup and call System.setProperty(). For a web application use a ServletContextListener so it happens early, see this answer for a quick example.
Update: this is perhaps not early enough for your use case with JBoss loading its configuration files.
If your concern is exposing the value for super.secret.password in clear text but you are not worried about someone invoking your program with the correct value for the password because of you've covered that issue using permissions or some other means, then I think you could simply encrypt the password in your start-up script and have a wrapper class decrypt it.
java -Dsuper.secret.password=BbWvOuliHZVHVwsXudsj14d1iXzo655R gov.fortknox.DecryptWrapper
If the credentials are for a data source, I should also point out other solutions specific to JBoss: SecureIdentityLoginModule which essentially does the above, and PBEUtils which offers a keystore solution when used with SecureIdentityLoginModule. See EncryptingDataSourcePasswords.
And finally, the suggestion by Peter Lawery to use a file is valid too.
'cryptomainia' was written to solve this exact issue. It decrypts main() arguments. https://github.com/birchb1024/cryptomainia
You can read it from some file in a static initializer of your class that contains the main method:
static {
try {
FileReader fr = new FileReader(FILE_NAME);
// read the property
System.setProperty(property.getName(), property.getValue());
} catch (final FileNotFoundException ex) {
logger.log(Level.SEVERE, ex.getMessage(), ex);
} catch (final IOException ex) {
logger.log(Level.SEVERE, ex.getMessage(), ex);
}
}
...
public static void main(...){
...
}
You can use JAVA_TOOL_OPTIONS environment variable and set the property there. But it will be visible still in your script file.
if an attacker has physical access to your machine, then there is no real reason why they can't own the machine - a simple rot13 to avert the casual eye is plenty.
If an attacker has some privileges (such as running top for example), but not physical access, then you can execute the program under a specialized user account (e.g., web-server-user), which has very little privilege, but has exclusive read access to a file containing the password. you then start up the app using that user account, and pass in the file path.
Doing so relies on the access privilege restrictions in the OS, which is likely to be implemented much better than what you can roll yourself.
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.