Some points to clarify that this is not a duplicate question as someone suggested:
okhttp3.mockwebserver.MockWebServer
, this is not an IDE lint error.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
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.