Сбой RequestFactory с "UnexpectedException: нет RequestContext для операции LPZEK7DlYkoG1$NQ5MjHlmuRChk="
Не могли бы вы, ребята, помочь мне, почему у меня это исключение?
Я извлек прокси-запросы RequestFactory и контекстные интерфейсы в отдельный jar, чтобы я мог использовать его как в GWT-клиенте, так и в Android-клиенте (подробности здесь)
К сожалению, RF вызывает исключение на сервере при самом первом вызове. Исключение составляет:
com.google.web.bindery.requestfactory.server.UnexpectedException: No RequestContext for operation LPZEK7DlYkoG1$NQ5MjHlmuRChk=
at com.google.web.bindery.requestfactory.server.ServiceLayerDecorator.die(ServiceLayerDecorator.java:216)
at com.google.web.bindery.requestfactory.server.ResolverServiceLayer.resolveRequestContext(ResolverServiceLayer.java:154)
Ниже мой заводской интерфейс. Как видите, мне пришлось заменить Service
аннотации с ServiceName
потому что я не хотел компилировать все пользовательские локаторы с инъекциями Guice для jar, которые будут использоваться на мобильных устройствах.
public interface AdminRequestFactory extends RequestFactory
{
// @Service(value = UserServiceDao.class, locator = InjectingServiceLocator.class)
@ServiceName(value = "com.blah.courierApp.server.dao.UserServiceDao", locator = "com.blah.courierApp.server.inject.InjectingServiceLocator")
public interface GaeUserServiceContext extends RequestContext
{
public Request<String> createLogoutURL(String destinationURL);
public Request<GaeUser> getCurrentUser();
}
// @Service(value = OrderDao.class, locator = InjectingServiceLocator.class)
@ServiceName(value = "com.blah.courierApp.server.dao.OrderDao", locator = "com.blah.courierApp.server.inject.InjectingServiceLocator")
public interface OrderRequestContext extends RequestContext
{
Request<List<OrderProxy>> listAll();
Request<Void> delete(Long id);
Request<Void> createOrder(OrderProxy order);
Request<OrderProxy> findOrderById(long id);
Request<Void> updateOrderState(long id, StateType newStateType);
}
GaeUserServiceContext contextUserService();
OrderRequestContext contextOrder();
}
Когда я его скомпилировал, RF Annotation Tool выдал следующее предупреждение:
Cannot fully validate context since domain type com.blah.courierApp.server.dao.UserServiceDao is not available.
You must run the ValidationTool as part of your server build process.
Add @SuppressWarnings("requestfactory") to dismiss.
Поэтому, когда исключение выдается под отладчиком на сервере, я вижу этот экземпляр com.google.web.bindery.requestfactory.vm.impl.Deobfuscator
имеет пустой operationData
поле, которое инициализируется DeobfuscatorBuilder
класс, сгенерированный инструментом аннотации RequestFactory.
Итак... Я декомпилировал этот класс и нашел это:
public final class AdminRequestFactoryDeobfuscatorBuilder extends Deobfuscator.Builder
{
public AdminRequestFactoryDeobfuscatorBuilder()
{
withRawTypeToken("w1Qg$YHpDaNcHrR5HZ$23y518nA=", "com.google.web.bindery.requestfactory.shared.EntityProxy");
withRawTypeToken("8KVVbwaaAtl6KgQNlOTsLCp9TIU=", "com.google.web.bindery.requestfactory.shared.ValueProxy");
withRawTypeToken("FXHD5YU0TiUl3uBaepdkYaowx9k=", "com.google.web.bindery.requestfactory.shared.BaseProxy");
withRawTypeToken("5vjE9LUy$l0uvi4kMYpS3JA1WEE=", "com.blah.shared.model.GaeUser");
withRawTypeToken("8KVVbwaaAtl6KgQNlOTsLCp9TIU=", "com.google.web.bindery.requestfactory.shared.ValueProxy");
withRawTypeToken("5a7OV4PSV$1xemsooKLfEQ4g5yY=", "com.blah.shared.proxies.OrderProxy");
withRawTypeToken("neR_xIhE5oZsc0HbnkAMa8A88yw=", "com.blah.shared.proxies.OrderStateProxy");
withRawTypeToken("t6gMQWDROJnYvqYhNURV8pd$sn4=", "com.blah.shared.proxies.OrganizationProxy");
withRawTypeToken("1o45xgS$5bIkBKF4wlR8oMw_FSo=", "com.blah.shared.proxies.PersonProxy");
withRawTypeToken("FXHD5YU0TiUl3uBaepdkYaowx9k=", "com.google.web.bindery.requestfactory.shared.BaseProxy");
}
}
Он не генерировал токены для фабрики. Поэтому нет звонков Deobfuscator.Builder.withOperation
из-за чего мой сервер не может найти контекст, когда звонки приходят от клиента.
Вопросы:
- Почему RequestFactory Annotation Tool не генерирует токены для фабрики (операций)?
- Как я могу это исправить?
2 ответа
Ну, это было довольно сложно... Но отладка в RF Annotation Tool помогла:)
Оказывается, у вас должны быть доменные классы, на которые вы ссылаетесь в @ServiceName
в classpath обработчика аннотаций RF. Это создает проблему курицы и яйца. Вы должны скомпилировать SharedClasses
модуль для компиляции основного модуля, но вы должны компилировать доменные классы из основного модуля для компиляции SharedClasses
модуль.
Вот что я сделал:
- Отключена обработка аннотаций RF для модуля SharedClasses.
- В обработчике RF-аннотаций основного модуля я явно указал RF-фабрику, которая должна обрабатываться с использованием параметра
rootOverride = com.blah.shared.factories.AdminRequestFactory
Это отстой, что я жестко закодировал полное имя класса в настройках проекта.
Если вы, ребята, знаете более элегантный метод, пожалуйста, дайте мне знать.
Я тоже столкнулся с той же проблемой. В основном у меня есть 3 модуля GWT 1. Основной модуль, а во втором модуле у меня есть requestFactory, классы домена сервера и значения прокси на стороне клиента. Я почти уверен, что ваше решение - это то, что мне нужно применить. Однако я запутался, как указать rootOverride на этапе сборки maven. Любые указатели в структуре pom.xml были бы чрезвычайно полезны.