views:

287

answers:

4

I want to disable the stack trace getting generated when an exception is thrown. I have used,

Runtime.getRuntime().traceInstructions(false);
Runtime.getRuntime().traceMethodCalls(false);

but still i could see the trace getting generated. How can you do that? Also i need to detect whether some one is debugging my class.

I want to disable all exception traces. I cannot use obfuscation since my product is an SDK which will be used in development. I am offering a Runtime also which is used when people want to deploy their applications built using my SDK. My requirement is that anyone using my Runtime jars should not be able to debug the code that is written...or atleast i will make it tough to debug by avoiding the stack trace generation from my runtime jars.

One way that i have found is that all the exceptions that are originating from my runtime jars, i would just catch them and set an empty StackTraceElement array on the exception object and re-throw it...

Why such requirement? Suppose you a develop an application using my SDK.(SDK jars cannot bundled with your application..i have restricted it and thats final :) !!) Now to run your application on your client's machine you(or client) needs to install the Runtime on client's machine and run your application. Now what if your client starts developing his own applications using my Runtime jars!! Thats a threat to my business....Thats why the horrible requirement.

Why disable stack trace?
By disabling the stack trace generation or method call trace generation i wanted to make developing code with my Runtime jars difficult and thats why i started my question in that way...do suggest some other solution to achieve such a requirement...

+2  A: 

Do you want to disable it for all exceptions?

Without knowing what you are trying to achieve, I would say this is the wrong path to go down. If you expect an exception to be thrown that you are happy to ignore you should explicitly catch it and handle it (where handling it can simply mean ignoring it, or logging a short message without the full stack trace).

Joel
+3  A: 

There are a few intricate parts of the JVM (at least, Sun's implementation of the JVM) which do not work if stack trace generation is disabled (I saw this in the implementation of some support methods for reflection). So I do not think that stack trace generation can be disabled at all. The Runtime.trace*() methods are about something else (a debugging tool much more thorough than stack traces).

In all generality, any Java code can be transparently analyzed, if only through bytecode instrumentation (bytecode modified with extra instructions when it is loaded). The only known defense against such analysis (I am assuming that you are trying to keep your code internals confidential) is obfuscation. See for instance ProGuard. Obfuscation will make stack traces useless to any over-inquisitive user (and, sadly, it also makes debugging very difficult, for the same reasons).

Thomas Pornin
I want to disable all exception traces.I cannot use obfuscation since my product is an SDK which will be used in development. I am offering a Runtime also which is used when people want to deploy their applications built using my SDK. My requirement is that anyone using my Runtime jars should not be able to debug the code that is written...or atleast i will make it tough to debug by avoiding the stack trace generation from my runtime jars.
AD
One way that i have found is that all the exceptions that are originating from my runtime jars, i would just catch them and set an empty StackTraceElement array on the exception object and re-throw it...
AD
+1 for just using ProGuard.
Thorbjørn Ravn Andersen
So why not distribute separate runtime and development jars, where the runtime jars are obfuscated?
Chinmay Kanchi
+1  A: 
  1. I don't think it is possible for code to know that it is being debugged, except by indirect (and unreliable) means like measuring how long it takes to execute code sequences.

  2. It is not possible to disable all stacktraces. You can disable stracktraces for exception classes that you define yourself, by overriding Throwable.fillInStackTrace() to do nothing. But that won't work for classes that you cannot change.

But if you are thinking of doing these things to prevent reverse engineering, you would be wasting your time even if you could do it. It would be simple for a hacker to identify your application's anti-reverse-engineering code and edit the relevant bytecode files to disable it.

EDIT - I've revised my opinion on what you are trying to do. Given that what you are doing is distributing an SDK which you are expecting your customers to embed in their own applications, disabling stacktraces for the entire Java application counts as customer hostile behaviour, IMO. As a side-effect of protecting your "precious" IP, you are making it hard for the customer/developer to debug her own code. Even code that doesn't have your precious methods on the call stack!

If I was a customer, I'd probably prefer that you shipped obfuscated code than do this. But most likely, I'd try VERY HARD to find an alternative software supplier that didn't treat its paying customers as thieves.

Stephen C
A: 

I'm also curious on why you want to do this, but if you really have your reasons, you have at least two options:

If you want to disable stack trace generation for your own Exception implementations, you can simply override the fillInStackTrace method:

public static class MyException extends Exception {
    @Override
    public Throwable fillInStackTrace() {
        return null;
    }       
}

If you want to disable it for all exceptions, you can use a byte code instrumentation agent to replace the fillInStackTrace method in the Throwable class. That will however only work for Java 6, since you in Java 5 are not allowed to replace a native method (fillInStackTrace) with a Java method using instrumentation.

jarnbjo
Replacing `fillInStackTrace` for all exceptions is liable to break things; e.g. Java security.
Stephen C
@Stephen: Do you care to explain why, or should it be obvious?
jarnbjo
IIRC, some security checks involve examining the callstack to see if the caller is "privileged" code. IIRC this relies on fillInStackTrace.
Stephen C
also you want 'return this', not 'return null', otherwise you violate the javadoc of fillInStackTrace()
Matt McHenry
@Matt: You are right. @Stephen: Any examples?
jarnbjo