Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/403.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在java程序中禁用堆栈跟踪生成?_Java_Debugging_Stack Trace - Fatal编程技术网

如何在java程序中禁用堆栈跟踪生成?

如何在java程序中禁用堆栈跟踪生成?,java,debugging,stack-trace,Java,Debugging,Stack Trace,我想禁用抛出异常时生成的堆栈跟踪。 我用过, Runtime.getRuntime().traceInstructions(false); Runtime.getRuntime().traceMethodCalls(false); 但我仍然可以看到生成的跟踪。你怎么能做到?我还需要检测是否有人在调试我的类 我想禁用所有异常跟踪。我不能使用模糊处理,因为我的产品是一个将在开发中使用的SDK。我提供了一个运行时,当人们想要部署使用我的SDK构建的应用程序时,也可以使用它。我的要求是,任何使用我的运

我想禁用抛出异常时生成的堆栈跟踪。 我用过,

Runtime.getRuntime().traceInstructions(false);
Runtime.getRuntime().traceMethodCalls(false);
但我仍然可以看到生成的跟踪。你怎么能做到?我还需要检测是否有人在调试我的类


我想禁用所有异常跟踪。我不能使用模糊处理,因为我的产品是一个将在开发中使用的SDK。我提供了一个运行时,当人们想要部署使用我的SDK构建的应用程序时,也可以使用它。我的要求是,任何使用我的运行时JAR的人都不能调试所编写的代码……或者,至少我会通过避免从我的运行时JAR生成堆栈跟踪而使调试变得困难


我发现的一种方法是,所有源自运行时JAR的异常,我只需捕获它们,并在异常对象上设置一个空的StackTraceeElement数组,然后重新抛出它

为什么会有这样的要求? 假设您使用我的SDK开发了一个应用程序。(SDK JAR不能与您的应用程序捆绑在一起..我已经对其进行了限制,这是最终决定:)现在,要在客户机上运行应用程序,您(或客户机)需要在客户机上安装运行时并运行应用程序。现在,如果您的客户开始使用my Runtime JAR开发自己的应用程序,该怎么办!!这对我的生意是一个威胁……这就是为什么这个可怕的要求

为什么要禁用堆栈跟踪?

通过禁用堆栈跟踪生成或方法调用跟踪生成,我想让使用运行时JAR开发代码变得困难,这就是为什么我以这种方式开始我的问题…是否建议其他解决方案来实现这样的要求…

是否要对所有异常禁用它


在不知道你想要实现什么的情况下,我会说这是一条错误的道路。如果您希望抛出一个您乐于忽略的异常,那么您应该显式地捕获它并处理它(处理它可能只是意味着忽略它,或者在没有完整堆栈跟踪的情况下记录一条短消息)。

JVM有一些复杂的部分(至少是Sun的JVM实现)如果禁用堆栈跟踪生成,这将不起作用(我在一些反射支持方法的实现中看到了这一点)。因此,我认为根本不能禁用堆栈跟踪生成。
Runtime.trace*()
方法与其他方法有关(一种比堆栈跟踪更彻底的调试工具)

一般来说,任何Java代码都可以被透明地分析,只要是通过字节码插装(字节码在加载时用额外的指令修改)。针对这种分析的唯一已知防御措施(我假设您试图对代码内部保密)是模糊处理。例如,见。模糊处理将使堆栈跟踪对任何过分好奇的用户都毫无用处(而且,不幸的是,出于同样的原因,它还使调试变得非常困难)

  • 我认为代码不可能知道它正在被调试,除非通过间接(而且不可靠)的方法,比如测量执行代码序列所需的时间

  • 不可能禁用所有堆栈跟踪。您可以为自己定义的异常类禁用stracktraces,方法是重写
    Throwable.fillInStackTrace()
    ,不执行任何操作。 但这对你不能改变的课程是不起作用的

  • 但是,如果你想做这些事情来防止逆向工程,即使你能做,你也会浪费时间。黑客识别应用程序的反逆向工程代码并编辑相关字节码文件以禁用它将非常简单

    编辑-我已经修改了我对您试图做什么的看法。鉴于您所做的是分发一个SDK,您希望您的客户将其嵌入到他们自己的应用程序中,因此禁用整个Java应用程序的StackTrace将被视为客户恶意行为,IMO。作为保护“宝贵”IP的副作用,您使客户/开发人员很难调试自己的代码。即使是调用堆栈中没有宝贵方法的代码


    如果我是一位客户,我可能更希望您提供模糊代码,而不是这样做。但最有可能的是,我会努力寻找一个替代软件供应商,它不会将付费客户视为小偷。

    我也很好奇你为什么要这样做,但如果你真的有你的理由,你至少有两个选择:

    如果要为自己的异常实现禁用堆栈跟踪生成,只需重写fillInStackTrace方法:

    public static class MyException extends Exception {
        @Override
        public Throwable fillInStackTrace() {
            return this;
        }       
    }
    
    如果要对所有异常禁用它,可以使用字节码检测代理替换Throwable类中的fillInStackTrace方法。但是,这只适用于Java 6,因为Java 5中不允许使用检测将本机方法(fillInStackTrace)替换为Java方法。

    Throwable.setStackTrace(StackTraceeElement[]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);
    

    注意:永远不要在生产中使用上面的代码,除非你想让你的同事难堪

    我想这里有两个不同的问题。您应该单独处理它们。请添加更多详细信息,例如,为什么要禁用堆栈跟踪?你说的“禁用stacktrace”到底是什么意思(因为它只是一系列例外情况)我认为你在这里给你的用户提供的服务很差。SDK没有给出有用的例外情况?“我的要求是任何使用我的运行时JAR的人都不能调试编写的代码”-这是一个可怕的要求,也是试图满足这个“要求”的可怕方法。@user279436:这是用于移动应用程序开发的吗?无论如何