1

なぜ私がこの例外を抱えているのか助けてくれませんか?

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)

以下は私のファクトリーインターフェースです。ご覧のとおり、モバイルデバイスで実行されるjarへのGuiceインジェクションを使用して、すべてのカスタムロケーターをコンパイルしたくなかったため、Serviceアノテーションをに置き換える必要がありました。ServiceName

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注釈ツールは次の警告を出しました:

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.

したがって、サーバーのデバッガーで例外がスローされると、のインスタンスに 、RequestFactoryアノテーションツールによって生成されたクラスによって初期化されcom.google.web.bindery.requestfactory.vm.impl.Deobfuscatorている空のoperationDataフィールドがあることがわかります。DeobfuscatorBuilder

だから...私はそのクラスを逆コンパイルし、これを見つけました:

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アノテーションツールがファクトリ(操作)のトークンを生成しないのはなぜですか?
  • どうすれば修正できますか?
4

2 に答える 2

1

まあ、それはかなりトリッキーでした...しかし、RF注釈ツールでのデバッグは役に立ちました:)

RF Annotation Processor のクラスパスで参照するドメイン クラスが必要であることが判明しまし@ServiceNameそれはニワトリが先か卵が先かの問題を引き起こします。メインモジュールをコンパイルするにはSharedClassesモジュールをコンパイルする必要がありますが、メインモジュールからモジュールをコンパイルするにはドメインクラスをコンパイルする必要がありSharedClassesます。

これが私がしたことです:

  • SharedClasses モジュールの RF 注釈処理を無効にしました。
  • メイン モジュールのRF 注釈プロセッサで、パラメータを使用して処理する必要がある RF ファクトリを明示的に指定しましたrootOverride = com.blah.shared.factories.AdminRequestFactory

ただし、プロジェクト設定で完全修飾クラス名をハードコーディングしたのは残念です。

もっとエレガントな方法を知っている方は教えてください。

于 2012-04-17T09:11:55.763 に答える
0

私も同じ問題にぶつかりました。基本的に、私は 3 つの GWT モジュールを持っています。あなたのソリューションが私が導入する必要があるものであると確信しています。ただし、maven ビルド フェーズで rootOverride を指定する方法がわかりません。pom.xml の構造内のポインターは非常に役立ちます。

于 2013-10-08T21:36:02.830 に答える