英文:
java.lang.IllegalArgumentException: Log tag "okhttp3.mockwebserver.MockWebServer" exceeds limit of 23 characters
问题
- 这是由于长日志标签名称引起的“运行时崩溃”,即
okhttp3.mockwebserver.MockWebServer,这不是IDE的Lint错误。 - 这个崩溃是由第三方依赖项引起的,即MockWebServer。感谢Yuri Schimke提出了一个bug 修复与MockWebServer一起使用的Android日志。
- 我在我的回答中提供了解决方案 https://stackoverflow.com/a/63388805/8034839。
英文:
Some points to clarify that this is not a duplicate question as someone suggested:
- This is a "runtime crash" caused by long log tag name. i.e.
okhttp3.mockwebserver.MockWebServer, this is not an IDE lint error. - This crash is caused by a third party dependency, i.e. MockWebServer. And thanks to Yuri Schimke for raising a bug
Fix android logging with MockWebServer. - I have provided my fix in my answer https://stackoverflow.com/a/63388805/8034839.
Original question:
I am working on Android web service tests using Expresso and MockWebServer, however I encounter below exception that tells me the log tag issue:
>"okhttp3.mockwebserver.MockWebServer" exceeds limit of 23 characters.
Detailed stack trace is as following:
2020-08-13 11:31:13.277 16901-17085/com.xxx.app I/okhttp.OkHttpClient: <-- HTTP FAILED: java.net.SocketTimeoutException: timeout
2020-08-13 11:31:13.280 16901-17346/com.xxx.app E/AndroidRuntime: FATAL EXCEPTION: MockWebServer TaskRunner
Process: com.xxx.app, PID: 16901
java.lang.IllegalArgumentException: Log tag "okhttp3.mockwebserver.MockWebServer" exceeds limit of 23 characters
at android.util.Log.isLoggable(Native Method)
at okhttp3.internal.platform.android.AndroidLog.androidLog$okhttp(AndroidLog.kt:66)
at okhttp3.internal.platform.android.AndroidLogHandler.publish(AndroidLog.kt:39)
at java.util.logging.Logger.log(Logger.java:615)
at java.util.logging.Logger.doLog(Logger.java:636)
at java.util.logging.Logger.log(Logger.java:725)
at okhttp3.mockwebserver.MockWebServer$serveConnection$$inlined$execute$1.runOnce(TaskQueue.kt:224)
at okhttp3.internal.concurrent.TaskRunner.runTask(TaskRunner.kt:116)
at okhttp3.internal.concurrent.TaskRunner.access$runTask(TaskRunner.kt:42)
at okhttp3.internal.concurrent.TaskRunner$runnable$1.run(TaskRunner.kt:65)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:762)
2020-08-13 11:31:13.293 16901-17346/com.xxx.app I/Process: Sending signal. PID: 16901 SIG: 9
答案1
得分: 1
我已经找到了解决这个问题的方法,经过对MockWebServer.kt源代码的深入研究。在这个文件中,有一个属性如下:
private val logger = Logger.getLogger(MockWebServer::class.java.name)
MockWebServer::class.java.name将返回一个完整的类名okhttp3.mockwebserver.MockWebServer,显然,这个名称作为Android日志标签已经超过了23个字符。解决方法是使用Kotlin反射来替换logger属性。反射代码如下:
fun <T : Any> T.setPrivateProperty(variableName: String, data: Any): Any? {
return javaClass.getDeclaredField(variableName).let { field ->
field.isAccessible = true
field.set(this, data)
return@let field.get(this)
}
}
在@before方法中,使用simpleName来设置日志标签:
val mockWebServer = MockWebServer() // this is declared inside test class.
@Before
fun setup() {
mockWebServer.setAndReturnPrivateProperty("logger",
Logger.getLogger(MockWebServer::class.java.simpleName))
mockWebServer.start(8080)
}
MockWebServer::class.java.simpleName将返回一个更短的类名,从而解决了这个问题。
英文:
I have figured out the workaround for this issue after digging into the source code of MockWebServer.kt. Inside this file, there is a property like below:
private val logger = Logger.getLogger(MockWebServer::class.java.name)
The MockWebServer::class.java.name will return a full class name okhttp3.mockwebserver.MockWebServer, obviously, this name as an Android log tag is already longer than 23 chars. The fix is using Kotlin reflection to replace the logger property. Reflection code is as below:
fun <T : Any> T.setPrivateProperty(variableName: String, data: Any): Any? {
return javaClass.getDeclaredField(variableName).let { field ->
field.isAccessible = true
field.set(this, data)
return@let field.get(this)
}
}
Inside the @before method, set the logger tag with simpleName
val mockWebServer = MockWebServer() // this is declared inside test class.
@Before
fun setup() {
mockWebServer.setAndReturnPrivateProperty("logger",
Logger.getLogger(MockWebServer::class.java.simpleName))
mockWebServer.start(8080)
}
MockWebServer::class.java.simpleName will return a shorter class name and fix the issue.
答案2
得分: 0
"It's due to Log API doesn't allow tag that exceeds 23 characters.
You can disable the lint checking by following Terence's answer, but you've been warned.
For better understanding, visit:
The logging tag can be at most 23 characters"
英文:
it's due to Log API doesn't allow tag that exceeds 23 characters.
You can disable the lint checking by following [Terence's answer](https://stackoverflow.com/a/28738249/12676247 "You can disable it if you so choose"), but you've been warned.
for better understanding visit :
[The logging tag can be at most 23 characters](https://stackoverflow.com/questions/28168622/the-logging-tag-can-be-at-most-23-characters#:~:text=From%20Android%20Studio's%20Recent%20Changes,tag%20that%20exceeds%2023%20characters. "The logging tag can be at most 23 characters")
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论