JAXB: исключение приведения класса, но класс имеет то же имя

У меня есть интересная проблема.

Когда я запустил сервер Glassfish, все работает нормально. Но я изменил код и опубликовал сервер, а также запускаю свой клиент (SistemGirisClientKullaniciDogrula). Приложение выдает это исключение:

java.lang.ClassCastException: tr.com.app.Kullanici cannot be cast to tr.com.app.Kullanici.

Интересно, что после перезагрузки сервера Glassfish приложение работает нормально.

Я использую restlet-spring-hibernate. И я также использую JAXB (org.restlet.ext.jaxb.jar) для преобразования XML в объекты Java. Мой сервер приложений — Glassfish v3.0.

подробности для настройки

  • рестлет 2.0.5
  • весна 3.0.5
  • спящий режим 3.3.2
  • стеклянная рыбка v3.0

клиентский класс (только для теста)

import java.io.IOException;

import org.restlet.Client;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.data.MediaType;
import org.restlet.data.Method;
import org.restlet.data.Protocol;
import org.restlet.ext.jaxb.JaxbRepresentation;

public class SistemGirisClientKullaniciDogrula {

    public static void main(String[] Args) throws IOException {

        String url = "http://localhost:8080/Project/sistemgirisws";

        Client client = new Client(Protocol.HTTP);

        Kullanici kullanici = new Kullanici();
        kullanici.setKodu("1");

        JaxbRepresentation<Kullanici> jaxbRepresentationSendingKullanici= new JaxbRepresentation<Kullanici>(MediaType.APPLICATION_XML, kullanici);

        Request request = new Request(Method.GET, url, jaxbRepresentationSendingKullanici);
        Response response = client.handle(request);

        JaxbRepresentation<Kullanici> kullaniciResponse = new JaxbRepresentation<Kullanici>(response.getEntity(), Kullanici.class);
        kullanici = kullaniciResponse.getObject();

        System.out.println("kullanici id : " + kullanici.getId());
    }
}

Веб-служба

public class ProjectWebService {

/**
 * 
 * @param representation
 * @return
 */
@Get
public Representation getKullanici(Representation representation) {

    JaxbRepresentation<Kullanici> jaxbRepresentation = new JaxbRepresentation<Kullanici>(representation, Kullanici.class);

    Kullanici kullanici = new Kullanici();

    try {

        kullanici = jaxbRepresentation.getObject(); //THIS LINE THROW java.lang.classCastException tr.com.app.Kullanici cannot be cast to tr.com.app.Kullanici.

    } catch (IOException e) {
        e.printStackTrace();
    }

    try {

        kullanici = sistemGirisBusinessManager.kullaniciDogrula(kullanici);

        getResponse().setStatus(Status.SUCCESS_OK);
        return new JaxbRepresentation<Kullanici>(MediaType.APPLICATION_XML, kullanici);

    } catch (Exception exception) {

        exception.printStackTrace();
        getResponse().setStatus(Status.CLIENT_ERROR_EXPECTATION_FAILED);
        return new JaxbRepresentation<MesajList>(MediaType.APPLICATION_XML, sistemGirisBusinessManager.getMesajList());

    }
}
}

Кто-нибудь знает, в чем проблема?


person Musa YUVACI    schedule 31.05.2011    source источник


Ответы (2)


Это может быть проблема с загрузкой класса. В Java, если два загрузчика классов загрузили один и тот же класс, он рассматривается как два разных класса. В этом случае ваше приведение не удастся, потому что JVM кажется, что вы приводите один тип к другому, который не находится в дереве наследования.

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

person Yohan Liyanage    schedule 31.05.2011
comment
Привет Йохан, спасибо за ответ. Но у меня есть только одна война. Возможно ли, что одна война может использовать два разных загрузчика классов. - person Musa YUVACI; 31.05.2011
comment
Привет @Musa, да, можно использовать несколько загрузчиков классов в контейнере, даже если у вас есть только один файл WAR. Это означает, что контейнер может использовать отдельный загрузчик классов только для вашего файла WAR. Я предполагаю, что когда вы развертываете приложение, оно использует один загрузчик классов, а для ваших последующих модификаций (режим отладки) замена кода использует другой загрузчик классов. - person Yohan Liyanage; 31.05.2011
comment
@Musa YUVACI - утечки ClassLoader в этой форме часто происходят из-за ссылок, хранящихся в ClassLoader области сервера (либо ошибки на сервере приложений, либо разработчики, добавляющие библиотеки вне WAR / EAR). - person McDowell; 31.05.2011
comment
@McDowel-Спасибо за ответ, теперь все работает. Проблема возникла при добавлении библиотек вне WAR. Итак, после удаления библиотек с сервера Glassfish все работает. - person Musa YUVACI; 31.05.2011

Проблема действительно в разных загрузчиках классов. у меня тоже было это, и добавление implements Serializable и serialVersionUID для этих объектов решило проблему.

person Vidmantas    schedule 07.06.2012
comment
Привет, Видмантас, какие значения serialVesionUID вы добавили? У меня есть все мои классы сущностей, реализующие Serializable и с serialVersionUID внутри (все имеют значение = 1L). У меня все еще есть проблема с кастингом Exception, хотя это происходит очень непредсказуемо. - person greenskin; 23.04.2013