开发者

java.lang.IllegalAccessException: is related to public / private attribute for classes?

I get the following erro开发者_如何学JAVAr in my Java code:

java.lang.IllegalAccessException: Class org.apache.commons.digester.ObjectCreateRule can not access a member of class Response with modifiers ""

Is it maybe because class Response is not public class ? If so, how can I make it accessible and keep the class Response in the same file with the main class ?

thanks

Update, Code: http://www.smipple.net/snippet/aneuryzma/on:%20is%20related%20to%20public%20/%20private%20attribute%20for%20classes%20%3F


As far as I remember your class Response should follow the bean convention: should be public, should have public default constructor and should have setters and getters for all fields that you refer from your xml.


Yes it is, as IllegalAccessException documentation says.

You can circumvent access modifiers with reflection. For example, to access private fields, use Class.getDeclaredField(String) to get a specific Field (works also for private fields - using plain getField can only get public members), and then set Field.setAccessible(true). Now the field can be used as if it was public.

You can also circumvent access modifier with JNI. It doesn't care about access modifiers at all. Yet one more way is to generate custom bytecode with a tool such as ASM.


can not access a member of class Response with modifiers ""

A member is an instance variable, modifiers are public, protected, static, ...

So it looks to me, that the Response class has a field that can't be accessed or created through the apache-commons-digesters ObjectCreationRule.

Either you have a Response class that is not compatible with digester or the error lies within the xml file that defines the Response class.


Looking at your code - the only Java "items" with no access modifiers are the classes Response and Request. Maybe the error tells us that those classes have to be public.


ObjectCreateRule attempts uses the loads Request via it's class name and then invokes Class.newInstance(). For this to work the Request and Response both need public and have public default constructors.

You have two options for this: 1. Place Request and Response in their own source files and make them public 2. Nest Request and Response inside your public top level class and make them public static.

If you took option two then your code would look like this: import java.io.Reader; import java.io.StringReader;

import org.apache.commons.digester.Digester;

public class DigExample {

    public static void main(String ar[]) {
        try {
            Digester digester = new Digester();
            digester.setValidating( false );

            digester.addObjectCreate( "response", Response.class );

            digester.addObjectCreate( "response/request", Request.class );
            digester.addBeanPropertySetter("response/request/name", "name" );
            digester.addBeanPropertySetter("response/request/value", "value" );
            digester.addSetNext( "response/request", "setRequest" );

            digester.addBeanPropertySetter( "response/matches", "matches" );

            Reader reader = new StringReader(
                            "<?xml version='1.0' encoding='UTF-8'?>" + 
                            "<response>" + 
                            "<request><name>books</name><value>xml</value></request>" +  
                            "<matches>20</matches>" + 
            "</response>");
            Response response = (Response)digester.parse( reader );

            System.out.println( response.toString() );

        } catch( Exception exc ) {
            exc.printStackTrace();
        }

    }
    static  public  class Response {

        public Response(){}

        private int _matches = 0;
        private Request  _request;

        public Request getRequest() {
            return _request;
        }

        public void setRequest(Request request) {
            _request = request;
        }

        public int getMatches() {
            return _matches;
        }

        public void setMatches(int matches) {
            _matches = matches;
        }

    }



    static public class Request {

        public Request() {}

        private String _name = "";
        private String _value = "";

        public String getName() {
            return _name;
        }

        public void setName(String name) {
            _name = name;
        }

        public String getValue() {
            return _value;
        }

        public void setValue(String value) {
            _value = value;
        }

    }
}

As other people have mentioned, if you were using reflection directly yourself you could probably circumvent the access modifiers, but this isn't an option in your example.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜