zoukankan      html  css  js  c++  java
  • 一次难忘的调试经历

    正在编一个网站,在本地编好之后打包成war远程部署到tomcat。在本地一切正常,但是一传到服务器上去就不行了。
    我这个网站程序会访问一个网页,去那个网页上爬取点东西,要想爬取就必须需要data.txt提供令牌。
    初步锁定bug所在区间,编一个小程序测试一下

        @RequestMapping("haha")
        @ResponseBody
        String debug() {
            try {
                return Util.debug("SY1606604", "xxxxxx", HttpClients.createDefault());
            } catch (IOException e) {
                e.printStackTrace(); 
            }  
            return "error";
        }
    

    出错的那段代码原来是Util.login(username,password,client)
    我把出错的那段代码重写,写成一个函数叫做Util.debug(),让这个函数返回尽量多的信息
    结果

    怎么会这样呢?我写了ResponseBody了呀,返回不得是个字符串吗?不会跳到“error”页面的呀。
    那我就多返回一点数据:

       @RequestMapping("haha")
        @ResponseBody
        String debug() {
            StringBuilder builder = new StringBuilder();
            try {
                builder.append(Util.debug("SY1606604", "xxxxx", HttpClients.createDefault()));
            } catch (IOException e) {
                builder.append(e.getMessage());
                builder.append(e.getCause().toString());
                builder.append(e.toString());
                builder.append("不可能出错呀");
               
            } 
             return "error";
        }
    

    访问haha页面,结果发现还是上面那种情况,一点都没变啊!
    为什么呀?
    原来是错中有错,在catch中再次抛出了异常!我又没写finally,结果这个Servlet就向容器抛出异常,结果就跳转到error页面去了!
    还有,如果是运行时异常,catch IOException好像不会接住吧,所以改成接一切异常!再加上一个finally

            StringBuilder builder = new StringBuilder();
            try {
                builder.append(Util.debug("SY1606604", "xxxxx", HttpClients.createDefault()));
            } catch (Exception e) {
                builder.append(e.getMessage());
                builder.append(e.getCause().toString());
                builder.append(e.toString());
                builder.append("不可能出错呀");
            } finally {
                return builder.toString();
            }
    

    结果页面中一个字都没有,ctrl+u查看网页源代码,也是空空如也。这tm都是咋回事啊?
    要知道上面每一次试错都需要进行

    • maven package打包
    • 打开tomcat manager页面,undeploy旧的war
    • 选择新的war,点击deploy
    • 等待上传结束,刷新haha页面

    每次至少两分钟。
    我怒了,我打印了这么多东西为啥一个字都没有?
    重定向,接受一切打印!!!!!!!!

        @RequestMapping("haha")
        @ResponseBody
        String debug() {
            StringBuilder builder = new StringBuilder();
            builder.append("百思不得其解");
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            PrintStream stream = new PrintStream(out);
            try {
                System.setErr(stream);
                System.setOut(stream);
                builder.append(Util.debug("SY1606604", "xxxxx", HttpClients.createDefault()));
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                builder.append(out.toString());
                return builder.toString();
            }
        }
    

    终于:

    终于看到了日志,梦寐以求的日志,终于知道自己错在哪里?当我看到找不到data.txt文件这句话时,我差点哭出来,好艰难。
    珍惜日志,哪有那么多条件去让你调试、跟踪,根本不可能。连部署都是这么艰难,就像ACM题一样,只告诉你对错bool值,不告诉你错在哪里,这是最令人疯狂的。
    仿佛有一个声音不停地在耳边呼喊:“你不行的”,我一直追问:“为什么不行?我哪里不行?”这个声音仿佛在嘲笑:“你为什么不行,我不说”。这就像是彻底的否定。
    不断地向别人展示别人无法更改的错误,是一种邪恶。它只是为了指出错误而指出错误,只是无理由的告诉你你不行。这让人如堕深渊。
    别人有错误,如果以让其改正为目的,则是善意;如果只是一次简单的评判,则是中意;如果是指出别人错误彰显自己的明智或者羞辱别人,那这就是恶意。

    回到上文,这里的错误是找不到data.txt,代码中是这么写的:

    OutputStream cout = Files.newOutputStream(Paths.get("src/main/resources/checkcode.jpg"));
    

    路径有问题,因为一旦部署到服务器,就没有这种路径了!应该去掉src/main/resources/这个前缀,因为在maven打包时自动把resources目录下的东西打包到classpath路径中了。更好的解决方法是:使用classPath而不要使用操作系统的文件路径

    回头观望,我发现了一种调试程序的手段。
    定义一个拦截器,在进行处理请求之前,重定向输出流、错误流或者日志到一个内存流,在请求处理的最后,如果发现错误,则打印这个流。这样就能清楚知道自己错在哪里了。

  • 相关阅读:
    Cloudera Manager安装之利用parcels方式安装3或4节点集群(包含最新稳定版本或指定版本的安装)(添加服务)(CentOS6.5)(五)
    Cloudera Manager安装之利用parcels方式安装单节点集群(包含最新稳定版本或指定版本的安装)(添加服务)(CentOS6.5)(四)
    Cloudera Manager安装之Cloudera Manager 5.3.X安装(三)(tar方式、rpm方式和yum方式)
    Cloudera Manager安装之时间服务器和时间客户端(二)
    Cloudera Manager安装之Cloudera Manager安装前准备(CentOS6.5)(一)
    Cloudera Manager架构原理
    Cloudera Manager是啥?主要是干啥的?
    HDU-1664-Different Digits(BFS)
    AdapterView<?> arg0, View arg1, int arg2, long arg3參数含义
    c++11 新特性之 autokeyword
  • 原文地址:https://www.cnblogs.com/weiyinfu/p/6336871.html
Copyright © 2011-2022 走看看