Search code examples
javareflectionognlprivate-members

Can you access private variables using OGNL?


Is there anyway using OGNL to access private variables that aren't exposed as a bean property (ie no get/set method pair)? I wanted to use OGNL as a faster, cleaner method of reflection for use in unit tests.

Here is my code:

@Test
public void shouldSetup() throws OgnlException{
    class A{
        private Object b = "foo";
        private Object c = "bar";
        public Object getB(){ return b; }
    }
    A a = new A();

    System.out.println( "This'll work..." );
    Ognl.getValue( "b", a );

    System.out.println( "...and this'll fail..." );
    Ognl.getValue( "c", a );

    System.out.println( "...and we'll never get here." );
}

Solution

  • Actually you can. You need to set MemberAccess in OgnlContext to allow access to non public fields and use getValue(ExpressionAccessor expression, OgnlContext context, Object root) method to retrieve value.

    @Test
    public void shouldSetup() throws OgnlException {
        class A {
            private Object b = "foo";
            private Object c = "bar";
            public Object getB() { return b; }
        }
        A a = new A();
    
        // set DefaultMemberAccess with allowed access into the context
        OgnlContext context = new OgnlContext();
        context.setMemberAccess(new DefaultMemberAccess(true));
    
        System.out.println( "This'll work..." );
        // use context in getValue method
        Ognl.getValue( "b", context, a );
    
        System.out.println( "...and this'll work..." );
        // use context in getValue method
        Ognl.getValue( "c", context, a );
    
        System.out.println( "...and we'll get here." );
    }