Как отключить генерацию трассировки стека в Java-программе? - PullRequest
7 голосов
/ 23 февраля 2010

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

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

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

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

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

Почему такое требование? Предположим, вы разрабатываете приложение с использованием моего SDK (файлы jar SDK не могут поставляться в комплекте с вашим приложением. Я ограничил его, и это окончательно :) !!) Теперь для запуска приложения на компьютере вашего клиента вам (или клиенту) необходимо установить Запустите на компьютере клиента и запустите ваше приложение. А что если ваш клиент начнет разрабатывать свои собственные приложения, используя мои jar-файлы Runtime !! Это угроза для моего бизнеса .... Вот почему ужасное требование.

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

Ответы [ 6 ]

11 голосов
/ 23 февраля 2010

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

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

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

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

5 голосов
/ 23 февраля 2010
  1. Я не думаю, что для кода возможно знать, что он отлаживается, кроме как косвенными (и ненадежными) средствами, такими как измерение, сколько времени требуется для выполнения последовательностей кода.

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

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

РЕДАКТИРОВАТЬ - Я пересмотрел свое мнение о том, что вы пытаетесь сделать. Учитывая то, что вы делаете, распространяете SDK, который, как вы ожидаете, ваши клиенты будут встраивать в свои собственные приложения, отключение трассировки стека для всего приложения Java считается враждебным поведением клиента , IMO. Как побочный эффект защиты вашего «драгоценного» IP, вы затрудняете отладку клиентом / разработчиком своего собственного кода. Даже код, который не имеет ваших драгоценных методов в стеке вызовов!

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

2 голосов
/ 23 февраля 2010

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

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

1 голос
/ 29 мая 2018

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

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

Или просто:

Thread.setDefaultUncaughtExceptionHandler(null);

ПРИМЕЧАНИЕ. Никогда не используйте приведенный выше код в Production, если вы не хотите дать своим коллегам трудное время

1 голос
/ 23 февраля 2010

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

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

0 голосов
/ 21 апреля 2013

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

Throwable t = new Throwable();
StackTraceElement[] myStackTrace = new StackTraceElement[] {
 new StackTraceElement("MySDKClass","MySDKMethod","MySDKFile",0)
};
t.setStackTrace(trace);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...