New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow accessing private, package private and protected members on OGNL expression #1258

Closed
jrumbinas opened this Issue Apr 18, 2018 · 12 comments

Comments

Projects
None yet
3 participants
@jrumbinas
Copy link

jrumbinas commented Apr 18, 2018

MyBatis internal reflection is not consistent with OGNL. MyBatis is capable of using private methods and constructors for result maps. However, when it comes to queries using OGNL getters and fields are forced to be public.

Here's an example where pojo.getAuthors() has to be public. Otherwise ReflectiveOperationException is thrown.

<insert id="insertAuthor" useGeneratedKeys="true" keyProperty="id">
  insert into Author (username, password, email, bio) values
  <foreach item="item" collection="pojo.getAuthors()" separator=",">
    (#{item.username}, #{item.password}, #{item.email}, #{item.bio})
  </foreach>
</insert>
@harawata

This comment has been minimized.

Copy link
Member

harawata commented Apr 19, 2018

Hi @jrumbinas ,

Assuming it was OGNL throwing the exception, you should submit this request to OGNL tracker.
https://github.com/jkuhnert/ognl
MyBatis just includes OGNL classes using maven-shade-plugin.

@harawata harawata closed this Apr 19, 2018

@jrumbinas

This comment has been minimized.

Copy link
Author

jrumbinas commented Apr 19, 2018

@harawata

This comment has been minimized.

Copy link
Member

harawata commented Apr 19, 2018

I didn't know that, sorry.
Could you provide an executable unit test or example project that reproduce the ReflectiveOperationException ?

@kazuki43zoo

This comment has been minimized.

Copy link
Member

kazuki43zoo commented Apr 19, 2018

Hi @harawata, I've added the OgnlMemberAccess in 3.5.0 because the DefaultMemberAccess removed at ognl 3.2.2
The OgnlMemberAccess allow only public.(This behavior same as the default behavior of DefaultMemberAccess)

It can be changed in the following method.

@Override
public boolean isAccessible(Map context, Object target, Member member, String propertyName) {
return Modifier.isPublic(member.getModifiers());
}

@jrumbinas

This comment has been minimized.

Copy link
Author

jrumbinas commented Apr 19, 2018

Test case:

public class Point {

    private int x;
    private int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }
}

public class Line {

    private List<Point> points;

    public Line(Point... points) {
        this.points = Arrays.asList(points);
    }

    private List<Point> getPoints() {
        return points;
    }

    private void setPoints(List<Point> points) {
        this.points = points;
    }
}
    <insert id="saveLine">
        insert into `lines` (`lid`, `c_lid`) values (#{line.lid}, #{line.compactId});
        insert into `points` (`lid`, `x`, `y`) values
        <foreach item="point" collection="line.getPoints()" separator=",">
            (#{line.lid}, #{point.x}, #{point.y})
        </foreach>
        ;
    </insert>

Result:

Caused by: org.apache.ibatis.builder.BuilderException: Error evaluating expression 'line.getPoints()'. Cause: org.apache.ibatis.ognl.MethodFailedException: Method "getPoints" failed for object com.r9.moonshine.db.mapper.Line@2860f493 [java.lang.NoSuchMethodException: com.r9.moonshine.db.mapper.Line.getPoints()]
	at org.apache.ibatis.scripting.xmltags.OgnlCache.getValue(OgnlCache.java:46)
	at org.apache.ibatis.scripting.xmltags.ExpressionEvaluator.evaluateIterable(ExpressionEvaluator.java:43)
	at org.apache.ibatis.scripting.xmltags.ForEachSqlNode.apply(ForEachSqlNode.java:55)
	at org.apache.ibatis.scripting.xmltags.MixedSqlNode.apply(MixedSqlNode.java:33)
	at org.apache.ibatis.scripting.xmltags.DynamicSqlSource.getBoundSql(DynamicSqlSource.java:41)
	at org.apache.ibatis.mapping.MappedStatement.getBoundSql(MappedStatement.java:292)
	at org.apache.ibatis.executor.statement.BaseStatementHandler.<init>(BaseStatementHandler.java:64)
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.<init>(PreparedStatementHandler.java:40)
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.<init>(RoutingStatementHandler.java:46)
	at org.apache.ibatis.session.Configuration.newStatementHandler(Configuration.java:545)
	at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:48)
	at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.ibatis.plugin.Invocation.proceed(Invocation.java:49)
Caused by: org.apache.ibatis.ognl.MethodFailedException: Method "getPoints" failed for object com.r9.moonshine.db.mapper.Line@2860f493 [java.lang.NoSuchMethodException: com.r9.moonshine.db.mapper.Line.getPoints()]
	at org.apache.ibatis.ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1551)
	at org.apache.ibatis.ognl.ObjectMethodAccessor.callMethod(ObjectMethodAccessor.java:68)
	at org.apache.ibatis.ognl.OgnlRuntime.callMethod(OgnlRuntime.java:1615)
	at org.apache.ibatis.ognl.ASTMethod.getValueBody(ASTMethod.java:91)
	at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
	at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
	at org.apache.ibatis.ognl.ASTChain.getValueBody(ASTChain.java:141)
	at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
	at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
	at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:467)
	at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:431)
	at org.apache.ibatis.scripting.xmltags.OgnlCache.getValue(OgnlCache.java:44)
Caused by: java.lang.NoSuchMethodException: c.r.m.d.Line.getPoints()
	at org.apache.ibatis.ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1492)
@harawata

This comment has been minimized.

Copy link
Member

harawata commented Apr 19, 2018

@jrumbinas ,
NoSuchMethodException makes sense. Thanks!

@kazuki43zoo ,
Could you take care of this?
I just took a quick look at how this interface is used in OGNL, but couldn't make much sense out of it...

@kazuki43zoo

This comment has been minimized.

Copy link
Member

kazuki43zoo commented Apr 19, 2018

@harawata , OK! I will take care this. I have one question. Should we allow to access a private method at OGNL expression?

@harawata

This comment has been minimized.

Copy link
Member

harawata commented Apr 19, 2018

Thank you, @kazuki43zoo !

Should we allow to access a private method at OGNL expression?

I couldn't think of any reason not to.
Let's test it in snapshot.

@kazuki43zoo

This comment has been minimized.

Copy link
Member

kazuki43zoo commented Apr 19, 2018

Let's test it in snapshot.

OK!!

@kazuki43zoo kazuki43zoo self-assigned this Apr 21, 2018

kazuki43zoo added a commit to kazuki43zoo/mybatis-3 that referenced this issue Apr 22, 2018

kazuki43zoo added a commit to kazuki43zoo/mybatis-3 that referenced this issue Apr 22, 2018

kazuki43zoo added a commit to kazuki43zoo/mybatis-3 that referenced this issue Apr 22, 2018

kazuki43zoo added a commit to kazuki43zoo/mybatis-3 that referenced this issue Apr 24, 2018

@kazuki43zoo

This comment has been minimized.

Copy link
Member

kazuki43zoo commented Apr 25, 2018

Hi @jrumbinas,

I will change to allow private, package private and protected members using OGNL expression same with parameter mapping and result mapping via #1262. But There are no plans to make it configurable at now.

Is OK?

@jrumbinas

This comment has been minimized.

Copy link
Author

jrumbinas commented Apr 25, 2018

That's perfect! Thank you so much!

kazuki43zoo added a commit to kazuki43zoo/mybatis-3 that referenced this issue Apr 25, 2018

@kazuki43zoo kazuki43zoo changed the title Feature request: configurable member access for Ognl Allow accessing private, package private and protected members on OGNL expression Apr 25, 2018

@kazuki43zoo kazuki43zoo added this to the 3.5.0 milestone Apr 25, 2018

@kazuki43zoo

This comment has been minimized.

Copy link
Member

kazuki43zoo commented Apr 25, 2018

fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment