0

I have a Google Cloud Endpoints application successfully working with Guice.

I wish to inject a Singleton into an Api Transformer.

Let's say I wish to transform Something into SomethingElse, where Something declares it's transformer to be:

import com.google.api.server.spi.config.Transformer;
import com.google.inject.Inject;
import com.google.inject.Singleton;

@Singleton
public class MyApiTransformer
    implements Transformer<Something, SomethingElse> {

private MySingleton singleton;

@Inject
public MyApiTransformer(MySingleton singleton) {
    this.singleton = singleton;
}
@Override
public Something transformFrom(SomethingElse somethingElse) {
    return singleton.something(somethingElse);
}

@Override
public SomethingElse transformTo(Something something) {
    return singleton.somethingElse(something);
}

}

Notice that I wish to delegate transformation to my Guice singleton. When I try the above transformer I get the following error:

java.io.IOException: com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException: Failed to instantiate custom serializer MyApiTransformer, constructors not found: [(interface java.lang.reflect.Type), (class java.lang.Class), ()]

It seems that Guice is not providing the ApiTransformers so Jackson does not know how to instantiate the class without a default constructor.

How can Guice inject the Singleton into the ApiTransformer?

Community
  • 1
  • 1
Aaron Roller
  • 1,074
  • 1
  • 14
  • 19

1 Answers1

0

Give your Transformer a default constructor and do static Injection:

import com.google.api.server.spi.config.Transformer;
import com.google.inject.Inject;

public class MyApiTransformer
    implements Transformer<Something, SomethingElse> {

@Inject
private static MySingleton singleton;

public MyApiTransformer() {

}
@Override
public Something transformFrom(SomethingElse somethingElse) {
    return singleton.something(somethingElse);
}

@Override
public SomethingElse transformTo(Something something) {
    return singleton.somethingElse(something);
}

}

in your Module:

public class MyModule
    extends AbstractModule {

@Override
protected void configure() {

    requestStaticInjection(MyApiTransformer.class);
}

}
Aaron Roller
  • 1,074
  • 1
  • 14
  • 19
  • Why would you choose static injection? – Jan Galinski Jun 16 '15 at 07:06
  • @JanGalinski I didn't choose it, but it does work. I'm hoping there is a better solution. – Aaron Roller Jun 17 '15 at 10:10
  • Making the field non-static and using "injector.injectMembers()" on the transformer instance should give you the same result, but without opening the "static" context, which might interfere in unexpected ways with guice's singleton. – Jan Galinski Jun 17 '15 at 10:49
  • Where do you propose putting the injectMembers statement? It would need to be part of the Cloud Endpoints framework. Jersey allows us to create custom instances of Adapters so I'm looking for the same feature in Cloud Endpoints. – Aaron Roller Jun 19 '15 at 05:04