Вопрос

У меня есть 2 разных проекта Java, у одного есть 2 класса: dynamicbeans.DynamicBean2 и dynamic.Validator.

В другом проекте я динамически загружаю оба этих класса и сохраняю их в Object

class Form {
    Class beanClass;
    Class validatorClass;
    Validator validator;
}

Затем я создаю объект Validator с помощью validatorClass.newInstance() и сохраняю его в validator, а затем создаю объект bean с помощью beanClass.newInstance() и добавляю его в сеанс.

portletRequest.setAttribute("DynamicBean2", bean);

В течение жизненного цикла проекта Form я вызываю validator.validate(), который загружает ранее созданный объект EJB из сеанса (я использую Websphere Portal Server). Когда я пытаюсь преобразовать этот объект обратно в DynamicBean2, происходит сбой ClassCastException.

Когда я вытаскиваю объект из сеанса с помощью

faces.getApplication().createValueBinding("#{DynamicBean2}").getValue(faces);

и проверьте его класс с помощью .getClass() я получаю <=>. Это класс, к которому я хочу привести его, однако, когда я пытаюсь получить ClassCastException.

По какой причине я это получаю?

Это было полезно?

Решение

Я не совсем слежу за вашим описанием потока программы, но обычно, когда вы получаете ClassCastExceptions, вы не можете объяснить, что вы загрузили класс одним загрузчиком классов, а затем пытаетесь привести его к тому же классу, загруженному другим загрузчиком классов. Это не будет работать - они представлены двумя различными объектами Class внутри JVM, и приведение не будет выполнено.

Существует статья о загрузке классов в WebSphere . Я не могу сказать, как это относится к вашему приложению, но есть ряд возможных решений. Я могу думать по крайней мере:

<Ол>
  • Измените загрузчик класса контекста вручную. Требует, чтобы вы действительно могли получить ссылку на соответствующий загрузчик классов, что может быть невозможно в вашем случае.

    Thread.currentThread().setContextClassLoader(...);
    
  • Убедитесь, что класс загружен загрузчиком классов выше в иерархии.

  • Сериализация и десериализация объекта. (Тьфу!)

  • Хотя, вероятно, есть более подходящий способ для вашей конкретной ситуации.

    Другие советы

    Объекты класса были загружены в разные загрузчики классов, поэтому экземпляры, созданные в каждом из классов, рассматриваются как «несовместимые». Это распространенная проблема в среде, где используется много разных загрузчиков классов и объекты передаются. Эти проблемы могут легко возникнуть в среде Java EE и портала.

    Для преобразования экземпляра класса необходимо, чтобы класс, связанный с объектом, который был преобразован, был таким же, как класс, загруженный текущим загрузчиком классов контекста потока.

    У меня возникла проблема A2AClassCastException при попытке создать список объектов из XML с помощью Apache Commons Digester.

    List<MyTemplate> templates = new ArrayList<MyTemplate>();
    Digester digester = new Digester();
    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
    }
    

    Как указывалось выше, причина в том, что метантенка не использует тот же ClassLoader, что и остальная часть программы. Я запустил это в JBoss, и оказалось, что commons-digester.jar находится не в каталоге lib JBoss, а в каталоге lib веб-приложения. Копирование jar в mywebapp / WEB-INF / lib также решило проблему. Другое решение состояло в том, чтобы заблокировать digester.setClassLoader (MyTemplate.class.getClassLoader ()), но в этом контексте это выглядит довольно уродливым решением.

    У меня была такая же проблема при использовании нескольких экземпляров JBoss на разных машинах. К сожалению, я не наткнулся на этот пост ранее.
    Были артефакты, развернутые на разных машинах, два из них объявили загрузчики классов с одинаковыми именами. Я изменил одно из имен загрузчиков классов, и все работало нормально = & Gt; Остерегайтесь копирования & И вставки!

    Почему в исключении ClassCastException не упоминаются загрузчики классов? - Думаю, это была бы очень полезная информация.
    Кто-нибудь знает, будет ли что-то подобное в будущем? Потребность в проверке класса грузчиков из 20-30 артефактов не так уж и приятна. Или я что-то пропустил в тексте исключения?

    РЕДАКТИРОВАТЬ : я отредактировал файл META-INF / jboss-app.xml и изменил имя загрузчика. Идея состоит в том, чтобы иметь уникальное имя. На работе мы используем идентификатор артефакта (уникальный) в сочетании с версией, вставленной maven ({$ version}) во время сборки.
    Использование динамических полей является необязательным, но помогает, если вы хотите развернуть разные версии одного и того же приложения.

    <jboss-app>
       <loader-repository> 
       com.example:archive=unique-archive-name-{$version}
       </loader-repository> 
    </jboss-app>
    

    Вы можете найти некоторую информацию здесь: https://community.jboss.org/wiki/ClassLoadingConfiguration

    У меня была та же проблема, и я наконец нашел обходной путь на java.net:

    Скопируйте все org.eclipse.persistence jar файлы из glassfish4/glassfish/modules в WEB-INF/lib. Затем войдите в свой glassfish-web.xml и установите class-delegate на false.

    Работал на меня!

    У меня возникла та же проблема с EJB-пакетом Wildfly, EJB возвращал список объектов и имел удаленный и локальный интерфейс. Я по ошибке использовал локальный интерфейс, который работал нормально до того момента, пока вы не попытаетесь привести объекты в список.

    Локальный / удаленный интерфейс:

    public interface DocumentStoreService {
    
        @javax.ejb.Remote
        interface Remote extends DocumentStoreService {
        }
    
        @javax.ejb.Local
        interface Local extends DocumentStoreService {
        }
    

    EJB-компонент:

    @Stateless
    public class DocumentStoreServiceImpl implements DocumentStoreService.Local, DocumentStoreService.Remote {
    

    Правильная пружинная обертка вокруг EJB:

    <bean id="documentStoreService" class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
        <property name="jndiName" value="java:global/dpc/dpc-ejb/DocumentStoreServiceImpl!santam.apps.dpc.service.DocumentStoreService$Remote"/>
        <property name="businessInterface" value="santam.apps.dpc.service.DocumentStoreService$Remote"/>
        <property name="resourceRef" value="true" />
    </bean>
    

    Обратите внимание на $ Remote. Вы можете изменить это значение на $ Local, и он с легкостью найдет интерфейс Local, а также без проблем выполнять методы (из отдельного приложения в том же контейнере), но объекты модели не являются маршалированные и из другого загрузчика классов, если вы используете локальный интерфейс по ошибке.

    Другой вариант:

    Произошло со мной в weblogic, но я полагаю, что это может произойти и на других серверах - если вы делаете (просто) " Publish " и поэтому некоторые из ваших классов перезагружаются. Вместо этого выполните & Quot; Очистить & Quot; поэтому все классы будут перезагружены вместе.

    У меня была такая же проблема с поиском EJB из другого EJB. Я решил добавить @Remote (MyInterface.class) в конфигурацию класса EJB

    То же самое было my.package.MyClass cannot be cast to my.package.MyClass в WildFly 10.1, и, насколько я понимаю, я сделал то, что описал @Emil Lundberg в своем ответе.

    Я добавил модуль (который содержит my.package.MyClass) в my.war/WEB-INF/jboss-deployment-structure.xml как зависимость

    <dependencies>
        ...
        <module name="my.package"/>
    </dependencies>
    

    и удалил соответствующий jar из my.war/WEB-INF/lib, повторно развернул WAR, а затем код заработал, как и ожидалось.

    Таким образом, мы убедились, что это решает проблему. Теперь нам нужно убедиться, что проблема не вернется, например, когда будет собрана и развернута обновленная версия WAR .

    Для этого в источниках этих WAR необходимо добавить <scope>provided</scope> для этих банок в pom.xml, чтобы когда my.war было повторно собранный в следующий раз с введенным кодом исправления / расширения, он не будет связывать этот jar в <=>.

    Я получил эту проблему после добавления зависимости к spring-boot-devtools в моем проекте Springboot. Я удалил зависимость, и проблема ушла. На данный момент я лучше всего предполагаю, что <=> вводит новый загрузчик классов, и это вызывает проблему проблем приведения классов между различными загрузчиками классов в определенных случаях, когда новый загрузчик классов не используется некоторыми потоками.

    Ссылка: Исключение карты бульдозера, связанное с загрузкой devtools в Spring.

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top