Java.lang.IllegalAccessException: связано с атрибутом public/private для классов?

В моем коде Java я получаю следующую ошибку:

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

Возможно, это потому, что класс Response не является публичным классом? Если да, как я могу сделать его доступным и сохранить класс Response в том же файле с основным классом?

спасибо

Обновление, код: http://www.smipple.net/snippet/aneuryzma/on:%20is%20related%20to%20public%20/%20private%20attribute%20for%20classes%20%3F

Ответ 1

Насколько я помню, ваш ответ класса должен следовать за соглашением bean: должен быть общедоступным, должен иметь открытый конструктор по умолчанию и должен иметь сеттеры и геттеры для всех полей, которые вы ссылаетесь на свой XML файл.

Ответ 2

Да, это как Документация IllegalAccessException.

Вы можете обойти модификаторы доступа с отражением. Например, чтобы получить доступ к закрытым полям, используйте Class.getDeclaredField(String), чтобы получить конкретный Field (работает также для частных полей - с помощью plain getField могут появляться только открытые элементы), а затем установите Field.setAccessible(true). Теперь поле можно использовать, как если бы оно было общедоступным.

Вы также можете обойти модификатор доступа с помощью JNI. Он вообще не интересуется модификаторами доступа. Еще один способ - создать пользовательский байт-код с помощью инструмента, такого как ASM.

Ответ 3

не может получить доступ к члену класса Response с помощью модификаторов ""

A member - это переменная экземпляра, модификаторы public, protected, static,...

Итак, мне кажется, что класс Response имеет поле, которое невозможно получить или создать через apache-commons-digesters ObjectCreationRule.

Либо у вас есть класс Response, который несовместим с digester, либо ошибка находится в XML файле, который определяет класс Response.


Глядя на ваш код - единственными "элементами" Java без модификаторов доступа являются классы Response и Request. Возможно, ошибка говорит нам, что эти классы должны быть общедоступными.

Ответ 4

Попытки ObjectCreateRule используют запрос Load через его имя класса, а затем вызывает Class.newInstance(). Для этого для запроса Request and Response требуются публичные и стандартные конструкторы по умолчанию.

У вас есть два варианта:  1. Разместить запрос и ответ в своих исходных файлах и сделать их общедоступными  2. Запросить и отклик гнезда внутри вашего класса верхнего уровня и сделать их public static.

Если вы воспользовались вторым вариантом, ваш код будет выглядеть так:   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;
        }

    }
}

Как говорили другие люди, если вы сами использовали рефлексию, вы, вероятно, могли бы обойти модификаторы доступа, но это не вариант в вашем примере.