jeudi 27 juillet 2017

Method.invoke not working with package-private class

I have a class TableModelBase that extends AbstractTableModel. In there I override the getValueAt method so that it return the getter result of the row class.

TableModelBase.java

@Log
@AllArgsConstructor
public abstract class TableModelBase<T> extends AbstractTableModel{
    @NonNull private final String[] columns;
    @NonNull protected final transient List<T> rows;

    //...

    /**
     * Default getValue method.<br>
     * The row type fields must be in the same sequence that the columns.<br>
     * Getter methods must follow the getter convention.
     * @param rowIndex The row index.
     * @param columnIndex The column index matches the field index of the row type.
     * @return Object
     */
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        final T row = rows.get(rowIndex);
        if(row.getClass().getDeclaredFields().length != getColumnCount()) {
            for (Field field : row.getClass().getDeclaredFields()) {
                System.out.println(field.getName());
            }
            log.severe("Fields number and table columns number are different in: " + row.getClass().getSimpleName());
            System.exit(1);
        }
        final Field field = row.getClass().getDeclaredFields()[columnIndex];

        String getter;
        if(field.getType().equals(boolean.class)) {
            getter = field.getName();
        }
        else {
            getter = "get" + Character.toUpperCase(field.getName().charAt(0)) + field.getName().substring(1);
        }

        try {
            Method method = row.getClass().getMethod(getter);
            return method.invoke(row);
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            log.severe(e.getMessage());
            System.exit(1);
            return null;
        }
    }
}

I have a test class TableModelTest in the package tablemodel. In this package there is also the classes Data and DataModel.

Data.java

@Value
class Data {
    String text = "text";
    boolean isSuccessful = true;
}

DataModel.java

class DataModel extends TableModelBase<Data> {
    DataModel() {
        super(new String[]{"Text", "Is Successful"}, new ArrayList<>());
        rows.add(new Data());
    }
}

TableModelBaseTest

public class TableModelBaseTest {
        @org.junit.Test
        public void getValueAt() {    
            final DataModel dataModel = new DataModel();
            assertEquals("text",dataModel.getValueAt(0, 0));
            assertEquals(true, dataModel.getValueAt(0, 1));
        }
}

The test give an IllegalAccessException:

Class com.dsidesoftware.tablemodel.TableModelBase can not access a member of class tablemodel.Data with modifiers "public"

The getters are public so why I cannot access them ?
The strange thing is when I make Data public, the exception is gone.

Any idea of what is going on ?

Thanks.





Aucun commentaire:

Enregistrer un commentaire