#java #reflection
#java #отражение
Вопрос:
Я участвую в конкурсе на самую большую ошибку всех времен. Мне нужно использовать Spring JDBC, даже не делая ссылки на него. Пользовательский загрузчик классов предоставляет контекст, и мне нужно использовать отражение для вызова методов. Одним из таких методов является SimpleJdbcCall.declareParameters(SqlParameter …)
Моя проблема заключается в создании и настройке переменных SqlParameter
(эти экземпляры также должны быть отражены). Мне нужно вставить один параметр в массив, чтобы удовлетворить сигнатуре varargs.
Далее загрузка класса опущена для краткости. Но предположим Class<?> simpleJdbcCallClass = SimpleJdbcCall.class
и т.д.
Constructor sqlOutParameterConstructor =
sqlOutParameterClass.getConstructor(String.class, int.class);
Object sqlOutParameter = sqlOutParameterConstructor.newInstance(param, type);
Object paramArray = Array.newInstance(sqlParameterArrayClass, 1);
Array.set(paramArray, 0, sqlParameterClass.cast(sqlOutParameter));
// IllegalArgumentException thrown above.
// It is thrown without the call to .cast too.
Method declareParametersMethod =
simpleJdbcCallClass.getMethod("declareParameters", sqlParameterArrayClass);
declareParametersMethod.invoke(procedure, paramArray);
Генерируемое исключение является:
java.lang.IllegalArgumentException: array element type mismatch
at java.lang.reflect.Array.set(Native Method)
Метод принимает, SqlParameter ...
и у меня есть экземпляр подкласса SqlOutParameter
. Следовательно, я пытаюсь выполнить приведение с помощью sqlParameterClass.cast(sqlOutParameter)
. Исключение генерируется с этим приведением или без него.
При отладке я могу подтвердить, что paramArray
это SqlParameter[]
и sqlParameterClass.cast(sqlOutParameter)
является SqlOutParamter
(не SqlParameter
как приведенное). Я подозреваю, что это может быть проблемой.
Комментарии:
1. Просто любопытно, но я хотел бы узнать историю, стоящую за этим
2. Несколько месяцев назад я провел крупный рефакторинг, преобразовав использование SQLExecutor в Spring 3 JDBC (чтобы обойти критические условия гонки). Наше приложение находится в среде поставщика, которая объединяет Spring 1. Некоторые подписи в Spring JDBC изменились по сравнению с этими версиями. Это привело к MethodNotFoundExceptions или аналогичному во время выполнения. Пока мы ждем обновления поставщика до Spring 3, я взламываю динамическую загрузку Spring 3 JDBC только для наших DAO. Счастливый, счастливый, радость, радость.
Ответ №1:
Я думаю, что проблема в этой строке:
Object paramArray = Array.newInstance(sqlParameterArrayClass, 1);
В частности, вы не говорите нам, что sqlParameterArrayClass
такое, но, основываясь на имени, я предполагаю, что это класс типа array. На самом деле, это должен быть класс элемента массива; newInstance(...)
методы см. в javadoc.
Комментарии:
1. Также вызов
Class.cast()
, вероятно, не нужен, вам не кажется?2. Да, это была проблема. И приведение было ненужным (это было частью моего устранения неполадок, как описано в вопросе).