前言
这是一篇笔记向的记录文章,希望能对读者也有所帮助。现在经验正热乎,所以快速记录下来。我在构建 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 解决。
呼~~~~,终于解决了,希望我的经验也能给你带来帮助。