Debug 的一点思路

前言

这是一篇笔记向的记录文章,希望能对读者也有所帮助。现在经验正热乎,所以快速记录下来。我在构建 HTTP 报文时,使用了成熟的第三方库 OKHTTP。由于这是从同事接手过来的项目,我不甚了解;而且是个老项目,未使用项目化工具,例如 Maven 进行构建。而且极其吊诡的是这个 bug 居然无迹可寻,代码运行至此,既未有异常抛出(有做异常控制),也未继续运行下一行。我在这个 bug 上用了我无数的思路,侥幸解决了。

分析

OkHttpClient client = new OkHttpClient(); 
StringBuffer messageStringBuffer = new StringBuffer("");
String messageUpload = messageStringBuffer.toString();
MediaType mediaType = MediaType.parse("text/xml");
RequestBody body = RequestBody.create(mediaType, messageUpload);
Request request = new Request.Builder()
  .url("")
  .post(body)
  .addHeader("Content-Type", "text/xml")
  .addHeader("cache-control", "no-cache")
  .build();

详细的报文没必要放上去,问题肯定不会出现在字符串上。

然后如上所示,代码在编译过程中顺利通过。但是实际运行时,既未有异常抛出(最外部有做异常控制),也未继续运行下一行。

然后打了几个断点定位了一下大概位置,我进行了异常捕获。这是一般的处理方法。

try {
	OkHttpClient client = new OkHttpClient();
	StringBuffer messageStringBuffer = new StringBuffer("");
	String messageUpload = messageStringBuffer.toString();
	MediaType mediaType = MediaType.parse("text/xml");
	RequestBody body = RequestBody.create(mediaType, messageUpload);
	Request request = new Request.Builder()
  		.url("")
 		.post(body)
  		.addHeader("Content-Type", "text/xml")
  		.addHeader("cache-control", "no-cache")
  		.build();
} catch (Exception e) {
  e.printStackTrace();
}

代码在编译过程中顺利通过。但是实际运行时,仍然没有异常抛出,也未继续运行下一行。

然后我逐行打断点,结果 bug 就在第一行。

try {
	OkHttpClient client = new OkHttpClient();		// bug
	StringBuffer messageStringBuffer = new StringBuffer("");
	String messageUpload = messageStringBuffer.toString();
	MediaType mediaType = MediaType.parse("text/xml");
	RequestBody body = RequestBody.create(mediaType, messageUpload);
	Request request = new Request.Builder()
  		.url("")
 		.post(body)
  		.addHeader("Content-Type", "text/xml")
  		.addHeader("cache-control", "no-cache")
  		.build();
} catch (Exception e) {
  e.printStackTrace();
}

我在这行代码之前打了断点,然后在 Debug 模式下的 Expressions 窗口里,直接运行了这行代码,这下稍微抓到了一点影子。在 Expressions 窗口中显示

java.lang.NoSuchMethodError: okio.BufferedSource

那很自然,虽然我纳闷儿为什么编译时没有报异常,但是这个很明显:第三方库没有这个方法。可能引入的库版本不对,这个方法没有,需要更新到适当的版本。

我又更新了第三方库,还是没有解决,这个 bug 依然存在,仍然没有异常抛出,也未继续运行下一行。

继续吧。。。

我在 Expressions 窗口中尝试运行了后面几行代码,例如

MediaType mediaType = MediaType.parse("text/xml");
Request request = new Request.Builder()
  		.url("")
 		.post(body)
  		.addHeader("Content-Type", "text/xml")
  		.addHeader("cache-control", "no-cache")
  		.build();

都是可以的,那么,说明第三方库没有问题,运行时也成功加载。

最后,我想了半天。突然闪过了一个念头,因为编译时编译器没有报异常,说明代码是没错的。但是,总是在这个 OkHttpClient 对象创建时出错,那我可以尝试将其变为类的一个属性,直接创建类的时候将 OkHttpClient 创建出来,如果可以,那就懒得理会这个 bug,我确实没辙了。但如果是由于编译时编译器只是检查,而不会去创建这个对象,若我将其变为类的一个属性,编译器需要去初始化属性,那么必然能捕获到异常。

因此我将代码改为:

public class Anything {
      private final OkHttpClient client = new OkHttpClient();
      try {
        OkHttpClient client = new OkHttpClient();		// bug
        StringBuffer messageStringBuffer = new StringBuffer("");
        String messageUpload = messageStringBuffer.toString();
        MediaType mediaType = MediaType.parse("text/xml");
        RequestBody body = RequestBody.create(mediaType, messageUpload);
        Request request = new Request.Builder()
          .url("")
          .post(body)
          .addHeader("Content-Type", "text/xml")
          .addHeader("cache-control", "no-cache")
          .build();
      } catch (Exception e) {
        e.printStackTrace();
      }
}

终于 Console 窗口里终于有异常信息了,这次连编译都未通过。我只贴出最关键的这一行。

java.lang.NoClassDefFoundError: kotlin/TypeCastException

然后一搜,原来还有一个三方库需要添加… …可我在 OKHTTP 的官网上下载时未曾有提到。好像是 OKHTTP 的 new OkHttpClient() 过程中某个特定函数需要调用这个三方库。

将三方库添加后,bug 解决。

呼~~~~,终于解决了,希望我的经验也能给你带来帮助。

原文地址:https://www.cnblogs.com/Sherlock-J/p/12925944.html