Backend Development 13 min read

Analysis of MyBatis OGNL Concurrency Bug and Workarounds

This article investigates a concurrency bug in MyBatis caused by OGNL expression evaluation using reflection, explains the root cause through stack trace and source code analysis, and proposes solutions such as upgrading MyBatis or avoiding private inner‑class methods like Arrays.asList.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Analysis of MyBatis OGNL Concurrency Bug and Workarounds
To save time, here is the conclusion: there is indeed a problem (see the issue link: https://github.com/mybatis/mybatis-3/pull/384). Below is the source‑code analysis and handling process for those interested.

Bug fixes are mandatory; without fixing them, daily work can be severely disrupted.

Log

After deploying to the server, MyBatis threw an exception on a frequently used interface, threatening performance metrics.

2023-08-08 09:52:05,386|aaaaaaaaa|XXXXXXXXXXXXXX|unknown exception occurred
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Error evaluating expression 'projects != null and projects.size() > 0 '. Cause: org.apache.ibatis.ognl.MethodFailedException: Method "size" failed for object [aaa,bbb,ccc] [java.lang.IllegalAccessException: Class org.apache.ibatis.ognl.OgnlRuntime can not access a member of class java.util.Arrays$ArrayList with modifiers "public"]
    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:75) ~[mybatis-spring-1.2.2.jar:1.2.2]
    ... (stack trace truncated for brevity) ...
Caused by: org.apache.ibatis.builder.BuilderException: Error evaluating expression 'projects != null and projects.size() > 0 '. Cause: org.apache.ibatis.ognl.MethodFailedException: Method "size" failed for object [aaa,bbb,ccc]
    at org.apache.ibatis.scripting.xmltags.OgnlCache.getValue(OgnlCache.java:45) ~[mybatis-3.2.8.jar:3.2.8]
    ... (more frames omitted) ...

The error occurs intermittently; most calls work fine, but occasional failures require deeper investigation.

Source Code Analysis

Investigation shows that OGNL expressions obtain methods via reflection and cache them in a static variable, which can cause concurrency issues when multiple threads access the cache.

Below is the caching logic (see the method org.apache.ibatis.ognl.OgnlRuntime#getMethods(java.lang.Class, boolean) for details).

The bug manifests when one thread sets a flag to true while another thread resets it to false before the method is invoked, leading to a failure.

The MyBatis issue tracker confirms this problem: https://github.com/mybatis/mybatis-3/pull/384.

The suggested fix is to upgrade MyBatis, but upgrading may not be feasible in a stable production codebase.

As a workaround, avoid using Arrays.asList (which returns a private inner class) in OGNL expressions. Instead, use Lists.newArrayList or other public‑method alternatives.

Summary

Problem: Non‑public methods or classes used in OGNL expressions can cause concurrency issues.

Solution 1: Upgrade MyBatis to a version where the bug is fixed.

Solution 2: Replace Arrays.asList with Lists.newArrayList or other public‑method collections to avoid the private inner‑class pitfall.

JavaconcurrencyreflectionMyBatisbugOGNL
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.