英文:
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")
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论