2010-03-06 5 views
0

Я пытаюсь использовать JPA с GWT.JPA и GWT сбой

Мой serviceImpl называет

UserDAO.exists(user); 

Когда я запускаю тестовый пример, который вызывает тот же метод, с теми же параметрами, он работает нормально. Когда я делаю вызов RPC, если он терпит неудачу (ошибка в конце).

Когда я переименовал persistence.xml в someothername.xml, я получаю ТОЧНУЮ ошибку, поэтому я склонен думать, что GWT (в режиме разработки BTW) НЕ читает мой persistence.xml.

Ошибка:

Starting Jetty on port 8888 
    [WARN] Exception while dispatching incoming RPC call 
com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract hobarrera.client.dto.main.UserRegDTO hobarrera.client.services.AuthService.selfRegisterUser(java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws hobarrera.client.exceptions.MyCustomizedException' threw an unexpected exception: java.lang.ExceptionInInitializerError 
at com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:378) 
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:581) 
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:188) 
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:224) 
at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487) 
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362) 
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) 
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181) 
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729) 
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405) 
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) 
at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49) 
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) 
at org.mortbay.jetty.Server.handle(Server.java:324) 
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505) 
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843) 
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647) 
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211) 
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380) 
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395) 
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488) 
Caused by: java.lang.ExceptionInInitializerError 
at hobarrera.server.DAO.EntityManagerFactory.createEntityManager(EntityManagerFactory.java:13) 
at hobarrera.server.DAO.UsuarioDAO.userNameExists(UsuarioDAO.java:52) 
at hobarrera.server.services.AuthServiceImpl.selfRegisterUser(AuthServiceImpl.java:60) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:616) 
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:562) 
... 22 more 
Caused by: javax.persistence.PersistenceException: No resource files named META-INF/services/javax.persistence.spi.PersistenceProvider were found. Please make sure that the persistence provider jar file is in your classpath. 
at javax.persistence.Persistence.findAllProviders(Persistence.java:167) 
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:103) 
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:83) 
at hobarrera.server.DAO.EntityManagerFactory$RealEntityManagerFactoryContainer.<clinit>(EntityManagerFactory.java:9) 
... 30 more 
[ERROR] 500 - POST /desarrollonew/greet (0:0:0:0:0:0:0:1) 57 bytes 
    Request headers 
     Host: localhost:8888 
     User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.8) Gecko/20100216 Fedora/3.5.8-1.fc12 Firefox/3.5.8 
     Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
     Accept-Language: en-us,en;q=0.5 
     Accept-Encoding: gzip,deflate 
     Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 
     Keep-Alive: 300 
     Connection: keep-alive 
     Referer: http://localhost:8888/desarrollonew/hosted.html?desarrollonew 
     Cache-Control: no-cache 
     X-GWT-Permutation: HostedMode 
     X-GWT-Module-Base: http://localhost:8888/desarrollonew/ 
     Content-Type: text/x-gwt-rpc; charset=utf-8 
     Content-Length: 187 
     Pragma: no-cache 
    Response headers 
     Content-Type: text/plain 

[править]
Кажется GWT имеет собственный файл persistence.xml где-то (для внутреннего использования, я думаю). Вот почему переименование моего persistence.xml на somethingelse.xml все равно дало ту же ошибку: файл persistence.xml, который читался, постоянно был GWT.

Итак, теперь мой вопрос: как мне переопределить его, заставить использовать другое или жить без него?

ответ

2

У вас есть банки DataNucleus в WEB-INF/lib?

+0

Да, как и их зависимости. Кажется, проблема находится в другом месте (отредактировано мое оригинальное сообщение, так что см. Там, plase). – WhyNotHugo

+0

@Hugo Является ли это проектом GAE/J или просто GWT? –

+0

Это просто GWT с DataNucleus как реализация JPA. – WhyNotHugo

0

Вы не добавили реализацию JPA в свой путь к классам. Поместите в свой путь пути банку datanucleus (или добавьте, или что бы вы ни использовали), которые заботятся о создании менеджера сущностей.

+0

Это в пути к классам, обратите внимание, что ошибка была такой же, как и в файле NO persistence.xml, поэтому даже не зная, что поставщик WHICH для поиска ошибки был таким же; следовательно, ошибка заключается не в поиске реализации JPA (DataNucleus BTW). – WhyNotHugo

-1

Поскольку это, как в очередной раз я собираюсь предложить переключение на внешний сервер для GWT, позвольте мне процитировать my previous answer (пожалуйста, прочитайте полный ответ на объяснения более глубокий встроенных вопросы Jetty GWT в):

I'd recommend just switching to an external Java server (like Tomcat, which you seem to have installed and which works with your configuration) - much less problems, easier than trying to work with the crippled Jetty that comes with GWT.

The instructions can be found in the docs. If you stick with GWT's Jetty, you will only run into more issues in the future.

Это по-прежнему верно, однако, что Jetty, который поставляется с GWT, как известно, проблематичен. Прочитайте docs для получения инструкций о том, как использовать внешний сервер с GWT (простая процедура, IMHO) - никаких недостатков и проблем со странными ошибками/исключениями.

+0

Я решил проблему; хотя я посмотрю, что я нахожу в этих проблемах, которые вы упомянули. В качестве недостатка на ранних этапах развертывание в tomcat занимает гораздо больше времени. – WhyNotHugo

+0

Я сделаю тот же комментарий, что и для вашего предыдущего ответа: если вам есть что сказать или показать о «известных» проблемах с Jetty, сделайте это. Если нет, то я считаю это FUD. –

+0

Вы правы, я отредактировал свой предыдущий ответ (ссылка в ответе выше), чтобы отразить это, надеюсь, что это меньше FUD и больше до обычного (высокого) стандарта на SO :) –

0

Ссылка: http://code.google.com/webtoolkit/articles/using_gwt_with_hibernate.html

Почему объекты Hibernate нельзя понять, когда они достигают мира браузера?

Так что пошло не так? Если посмотреть на консоль с установленным режимом, вы заметите, что на консоль был зарегистрирован предупреждающий сигнал «Исключение при отправке входящего вызова RPC». Выбрав предупреждающее сообщение, нижняя панель отобразит довольно длинную трассировку стека.

Это часть обратить внимание на:

причиненном: com.google.gwt.user.client.rpc.SerializationException: Тип «org.hibernate.collection.PersistentSet» не был включен в комплект типов, которые могут быть сериализованы этим объектом SerializationPolicy или его классом, не могут быть загружены. В целях безопасности этот тип не будет сериализован. at com.google.gwt.user.server.rpc.impl.StandardSerializationPolicy.validateSerialize (StandardSerializationPolicy.java:83) at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize (ServerSerializationStreamWriter.java: 591)

Ключевым моментом здесь является исключение SerializationException, которое было создано при попытке загрузить и получить учетные записи.

Итак, что именно случилось? Ну, как вы, возможно, читали в документах GWT RPC, исключение SerializationException генерируется всякий раз, когда тип, переданный по RPC, не является «сериализуемым». Определение сериализуемого здесь означает, что механизм RPC GWT знает, как сериализовать и десериализовать тип от байт-кода до JSON и наоборот. Чтобы объявить тип как сериализуемый компилятору GWT, вы можете либо сделать тип, который будет передан через RPC, реализовать интерфейс IsSerializable, специально созданный для этой цели, либо реализовать стандартный интерфейс java.io.Serializable, при условии, что его члены и методы состоят из типов, которые также могут быть сериализованы.

В случае объектов Счета и записи Hibernate мы реализуем интерфейс Serializable, поэтому они должны работать, не так ли ?. Как выясняется, дьявол находится в деталях.

Когда вы берете объект и превращаете его в объект Hibernate, объект теперь расширен, чтобы быть постоянным. Эта настойчивость не приходит без какого-либо инструментария объекта. В случае Hibernate библиотека Javassist фактически заменяет и перезаписывает байт-код для этих объектов постоянными объектами, чтобы заставить работать Hibernate. Для GWT RPC это означает, что к тому моменту, когда объект готов к передаче по проводу, на самом деле это не тот объект, который, по мнению компилятора, переносится, поэтому при попытке десериализации механизм GWT RPC больше не знает, что такое тип, и отказывается от десериализации.

На самом деле, если вы хотите глубже изучить предыдущий вызов loadAccounts() и вступить в метод RPC.invokeAndEncodeResponse(), вы увидите, что объект, который мы пытаемся десериализовать, теперь стал ArrayList типов учетных записей с их java.util.Set записей, замененных типом org.hibernate.collection.PersistentSet.

Аналогичные проблемы возникают с другими структурами сохранения, такими как JDO или JPA, которые используются в Google App Engine.

Потенциальным решением было бы заменить типы еще раз в обратном направлении, прежде чем возвращать вызов RPC на стороне сервера. Это выполнимо, и мы решим проблему, с которой мы столкнулись здесь, но пока что мы не были бы в опасности. Еще одно большое преимущество использования Hibernate - это то, что мы можем лениво загружать связанные объекты, когда это необходимо. Например, на стороне сервера я мог загружать учетную запись, изменять ее и загружать связанные записи, когда был вызван вызов account.getRecords() и некоторые действия по этим записям. Специальная аппаратура Hibernate позаботится о том, чтобы действительно получать записи, когда я делаю вызов, делая их доступными только тогда, когда это действительно необходимо.

Как вы можете себе представить, это приведет к странному поведению в мире GWT RPC, где эти объекты Hibernate перешли с серверной стороны Java на территорию браузера. Если служба RPC GWT пытается получить доступ к ассоциациям лениво, вы можете увидеть что-то вроде брошенного LazyInitializationException.

 Смежные вопросы

  • Нет связанных вопросов^_^