ClassCastException при приведении к тому же классу
У меня есть 2 разных Java-проекта, в одном есть 2 класса: dynamicbeans.DynamicBean2 и dynamic.Validator.
В другом проекте я динамически загружаю оба этих класса и сохраняю их в Object
classForm { Class beanClass; Class validatorClass; Validator validator; }
Затем я продолжаю и создаю Validator объект с помощью validatorClass.newInstance() и сохраняю его на validator затем я также создаю bean-объект с помощью beanClass.newInstance() и добавляю его в сеанс.
В течение жизненного цикла Form проекта я вызываю validator.validate() который загружает ранее созданный объект bean из сеанса (я использую Websphere Portal Server). Когда я пытаюсь привести этот объект обратно в DynamicBean2 он завершается неудачей с ClassCastException.
Когда я вытаскиваю объект обратно из сеанса с помощью
и проверьте его класс, используя .getClass() я получаю dynamicbeans.DynamicBean2. Это класс, к которому я хочу привести его, однако при попытке я получаю ClassCastException.
Есть какая-нибудь причина, по которой я это получаю?
Переведено автоматически
Ответ 1
Я не совсем понимаю ваше описание потока работы программы, но обычно, когда вы получаете ClassCastExceptions, вы не можете объяснить, что вы загрузили класс с помощью одного classloader, а затем пытаетесь привести его к тому же классу, загруженному другим classloader. Это не сработает - они представлены двумя разными объектами класса внутри JVM, и приведение завершится ошибкой.
Есть статья о загрузке классов в WebSphere. Я не могу сказать, как это применимо к вашему приложению, но есть ряд возможных решений. Я могу придумать по крайней мере:
Измените загрузчик контекстного класса вручную. Требуется, чтобы вы действительно могли получить ссылку на соответствующий загрузчик класса, что может быть невозможно в вашем случае.
Убедитесь, что класс загружен загрузчиком классов выше по иерархии.
Сериализуйте и десериализуйте объект. (Фу!)
Однако, вероятно, есть более подходящий способ для вашей конкретной ситуации.
Ответ 2
Я столкнулся с этой проблемой после добавления зависимости в spring-boot-devtools в моем проекте Springboot. Я удалил зависимость, и проблема исчезла. Мое лучшее предположение на данный момент заключается в том, что spring-boot-devtools вводит новый загрузчик классов, и это вызывает проблемы с приведением классов между разными загрузчиками классов в определенных случаях, когда новый загрузчик классов не используется некоторыми потоками.
Объекты класса были загружены в разные загрузчики классов, поэтому экземпляры, созданные из каждого из классов, рассматриваются как "несовместимые". Это распространенная проблема в среде, где используется много разных загрузчиков классов и объекты передаются по кругу. Эти проблемы могут легко возникнуть в средах Java EE и portal.
Для приведения экземпляра класса требуется, чтобы класс, связанный с приводимым объектом, совпадал с классом, загруженным текущим загрузчиком классов контекста потока.
Ответ 4
У меня возникла проблема с A2AClassCastException при попытке создать список объектов из XML с помощью Apache Commons Digester.
List<MyTemplate> templates = newArrayList<MyTemplate>(); Digesterdigester=newDigester(); digester.addObjectCreate("/path/to/template", MyTemplate.class); digester.addSetNext("/path/to/template", "add"); // Set more rules... digester.parse(f); // f is a pre-defined File
for(MyTemplate t : templates) { // ClassCastException: Cannot cast mypackage.MyTemplate to mypackage.MyTemplate // Do stuff }
Как указано выше, причина в том, что digester не использует тот же ClassLoader, что и остальная часть программы. Я запустил это в JBoss, и оказалось, что это commons-digester.jar было не в каталоге lib JBoss, а скорее в каталоге lib веб-приложения. Копирование jar в mywebapp / WEB-INF / lib также решило проблему. Другим решением было использовать digester.setClassLoader(MyTemplate.class.getClassLoader()), но в данном контексте это кажется довольно уродливым решением.