Как отключить генерацию трассировки стека в программе Java?

Я хочу отключить трассировку стека, генерируемую при возникновении исключения. Я использовал,

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

но все же я мог видеть след генерируются. Как ты можешь это делать? Также мне нужно определить, отлаживает ли кто-то мой класс.

Я хочу отключить все трассировки исключений. Я не могу использовать обфускацию, так как мой продукт является SDK, который будет использоваться в разработке. Я также предлагаю среду выполнения, которая используется, когда люди хотят развернуть свои приложения, построенные с использованием моего SDK. Мое требование заключается в том, что любой, кто использует мои банки времени выполнения, не должен иметь возможности отлаживать написанный код...или, по крайней мере, я сделаю его трудным для отладки, избегая генерации трассировки стека из моих банок времени выполнения.

один из способов, который я нашел, заключается в том, что все исключения, происходящие из моих банок времени выполнения, я бы просто поймал их и установил пустой массив StackTraceElement на объекте исключения и повторно бросил его...

почему такие требование? Предположим, вы разрабатываете приложение с помощью My SDK.(SDK jars не может быть в комплекте с вашим приложением..я ограничил его, и это окончательно :)!!) Теперь для запуска приложения на компьютере клиента вам (или клиенту) необходимо установить среду выполнения на компьютере клиента и запустить приложение. Теперь, что делать, если ваш клиент начинает разрабатывать свои собственные приложения, используя мои банки времени выполнения!! Это угроза моему бизнесу....Вот почему ужасное требование.

зачем отключать стека Трейс?
Отключив генерацию трассировки стека или генерацию трассировки вызова метода, я хотел сделать разработку кода с помощью моих банок времени выполнения сложной, и поэтому я начал свой вопрос таким образом...предложите другое решение для достижения такого требования...

6 ответов


есть несколько сложных частей JVM (по крайней мере, реализация Sun JVM), которые не работают, если генерация трассировки стека отключена (я видел это в реализации некоторых методов поддержки для отражения). Поэтому я не думаю, что генерация трассировки стека может быть отключена вообще. The Runtime.trace*() методы о чем-то другом (инструмент отладки гораздо более тщательный, чем трассировки стека).

во всей общности любой код Java может быть прозрачно проанализирован, если только через bytecode instrumentation (байт-код, модифицированный дополнительными инструкциями при загрузке). Единственная известная защита от такого анализа (я предполагаю, что вы пытаетесь сохранить конфиденциальность своих внутренних кодов) - это обфускация. См., например,должны быть. Обфускация сделает трассировки стека бесполезными для любого чрезмерно любознательного пользователя (и, к сожалению, это также делает отладку очень сложной по тем же причинам).


мне также интересно, почему вы хотите это сделать, но если у вас действительно есть причины, у вас есть по крайней мере два варианта:

Если вы хотите отключить создание трассировки стека для собственных реализаций исключений, вы можете просто переопределить метод fillInStackTrace:

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

Если вы хотите отключить его для все исключения, вы можете использовать агент инструментирования байтового кода для замены метода fillInStackTrace в классе Throwable. Однако это будет работает только для Java 6, так как вам в Java 5 не разрешено заменять собственный метод (fillInStackTrace) на метод Java с использованием инструментария.


  1. Я не думаю, что код может знать, что он отлаживается, за исключением косвенных (и ненадежных) средств, таких как измерение времени выполнения кодовых последовательностей.

  2. невозможно отключить все stacktraces. Вы can отключить stracktraces для классов исключений, которые вы определяете сами, путем переопределения Throwable.fillInStackTrace() ничего не делать. Но это не будет работать для классов, которые вы не можете изменение.

но если вы думаете сделать эти вещи, чтобы предотвратить обратное проектирование, вы будете тратить свое время, даже если вы могли бы это сделать. Для хакера было бы просто идентифицировать анти-инженерный код вашего приложения и отредактировать соответствующие файлы байт-кода, чтобы отключить его.

редактировать - я пересмотрел свое мнение о том, что вы пытаетесь сделать. Учитывая, что то, что вы делаете, распространяет SDK, который вы ожидаете ваши клиенты для внедрения в свои собственные приложения, отключение stacktraces для всего приложения Java считается враждебное поведение клиентов, ИМО. В качестве побочного эффекта защиты вашего "драгоценного" IP вы затрудняете клиенту / разработчику отладку собственного кода. Даже код, который не имеет ваших драгоценных методов в стеке вызовов!

Если бы я был клиентом, я, вероятно, предпочел бы, чтобы вы отправили запутанный код, чем сделать это. Но, скорее всего, я бы очень постарался Трудно найти альтернативного поставщика программного обеспечения, который не относились к своим платежеспособным клиентам как к ворам.


вы хотите отключить его для всех исключений?

Не зная, чего вы пытаетесь достичь, я бы сказал, что это неправильный путь. Если вы ожидаете, что будет выдано исключение, которое вы с радостью проигнорируете, вы должны явно поймать его и обработать (где обработка может просто означать игнорирование его или протоколирование короткого сообщения без полной трассировки стека).


Throwable.setStackTrace (StackTraceElement[] stackTrace) блокирует любые дополнения к stackTrace после его вызова:

Throwable t = new Throwable();
StackTraceElement[] myStackTrace = new StackTraceElement[] {
 new StackTraceElement("MySDKClass","MySDKMethod","MySDKFile",0)
};
t.setStackTrace(trace);

вы можете перенаправить все исключения в другое место, например:

Thread.setDefaultUncaughtExceptionHandler(
                (t, e) -> System.err.println("There's nothing to see here"));

или просто:

Thread.setDefaultUncaughtExceptionHandler(null);

Примечание: никогда не используйте код выше в производстве, если вы не хотите дать своим коллегам трудное время