Objectify + Eclipse + Generate Cloud Endpoint Client Library

358 views
Skip to first unread message

Vanessa Gomes

unread,
Jul 16, 2014, 5:30:48 AM7/16/14
to objectify...@googlegroups.com
Hey, everyone. 

I am new here. I am sorry if this question was already solved. My problem is:

What I am using: Eclipse, Java, Objectify, App Engine

I was trying for about 3 weeks make my project work. At first, I had an Android Project. Then, with Google Eclipse Plugin, I generated an App Engine Backend (on Eclipse) and started to work with JPA. However, I had too many problems regarding relationships. I just lost time and patience. So, I decided to move to objectify.

I built my classes following all the steps of Objectify's documentation. I defined my Endpoints replacing the previous code (that used JPA) by a new one. objectify and guava jars are both on WEB-INF/lib and inside the buildpath. 

The problem: when I try to generate the Cloud Endpoint Client Libraries, I got this error:

There was a problem generating the API metadata for your Cloud Endpoints classes: com.google.appengine.repackaged.com.google.api.client.http.HttpResponseException: 
400 Bad Request
{"error": {"message": "Bad Request", "code": 400, "errors": [{"message": "api exception", "debug_info": "Variable  does not conform to style guide"}]}}

Error log:
java.lang.reflect.InvocationTargetException
at com.google.gdt.eclipse.appengine.swarm.wizards.GenerateSwarmApiAction$1.run(GenerateSwarmApiAction.java:82)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)
Caused by: com.google.gdt.eclipse.appengine.swarm.wizards.helpers.SwarmGenerationException: com.google.appengine.repackaged.com.google.api.client.http.HttpResponseException: 400 Bad Request
{"error": {"message": "Bad Request", "code": 400, "errors": [{"message": "api exception", "debug_info": "Variable  does not conform to style guide"}]}}
at com.google.gdt.eclipse.appengine.swarm.wizards.helpers.SwarmApiCreator.createClientLibFromApiConfig(SwarmApiCreator.java:144)
at com.google.gdt.eclipse.appengine.swarm.wizards.helpers.SwarmApiCreator.createSwarmApi(SwarmApiCreator.java:258)
at com.google.gdt.eclipse.appengine.swarm.wizards.helpers.SwarmServiceCreator.create(SwarmServiceCreator.java:444)
at com.google.gdt.eclipse.appengine.swarm.wizards.GenerateSwarmApiAction$1.run(GenerateSwarmApiAction.java:80)
... 1 more
Caused by: com.google.appengine.repackaged.com.google.api.client.http.HttpResponseException: 400 Bad Request
{"error": {"message": "Bad Request", "code": 400, "errors": [{"message": "api exception", "debug_info": "Variable  does not conform to style guide"}]}}
at com.google.appengine.repackaged.com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1054)
at com.google.api.server.spi.tools.CloudClientLibGenerator.postRequest(CloudClientLibGenerator.java:53)
at com.google.api.server.spi.tools.CloudClientLibGenerator.generateClientLib(CloudClientLibGenerator.java:44)
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:606)
at com.google.gdt.eclipse.appengine.swarm.wizards.helpers.SwarmApiCreator.createClientLibFromApiConfig(SwarmApiCreator.java:142)
... 4 more
Root exception:
com.google.gdt.eclipse.appengine.swarm.wizards.helpers.SwarmGenerationException: com.google.appengine.repackaged.com.google.api.client.http.HttpResponseException: 400 Bad Request
{"error": {"message": "Bad Request", "code": 400, "errors": [{"message": "api exception", "debug_info": "Variable  does not conform to style guide"}]}}
at com.google.gdt.eclipse.appengine.swarm.wizards.helpers.SwarmApiCreator.createClientLibFromApiConfig(SwarmApiCreator.java:144)
at com.google.gdt.eclipse.appengine.swarm.wizards.helpers.SwarmApiCreator.createSwarmApi(SwarmApiCreator.java:258)
at com.google.gdt.eclipse.appengine.swarm.wizards.helpers.SwarmServiceCreator.create(SwarmServiceCreator.java:444)
at com.google.gdt.eclipse.appengine.swarm.wizards.GenerateSwarmApiAction$1.run(GenerateSwarmApiAction.java:80)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)
Caused by: com.google.appengine.repackaged.com.google.api.client.http.HttpResponseException: 400 Bad Request
{"error": {"message": "Bad Request", "code": 400, "errors": [{"message": "api exception", "debug_info": "Variable  does not conform to style guide"}]}}
at com.google.appengine.repackaged.com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1054)
at com.google.api.server.spi.tools.CloudClientLibGenerator.postRequest(CloudClientLibGenerator.java:53)
at com.google.api.server.spi.tools.CloudClientLibGenerator.generateClientLib(CloudClientLibGenerator.java:44)
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:606)
at com.google.gdt.eclipse.appengine.swarm.wizards.helpers.SwarmApiCreator.createClientLibFromApiConfig(SwarmApiCreator.java:142)
... 4 more


Some examples (including the Entity Registration). I will suppress package, imports and getters/setters. If anyone knows how to help, I would really appreciate. If there is any code I should put here, please let me know.

User.java
@Entity
    public class User {
@Id
private Long id;

private String name;

@Index
private PhoneNumber phoneNumber;

private String friendCode;
@Load
private List<Ref<Group>> groups = new ArrayList<Ref<Group>>(); //groups that a User can be simple member
//...
}

Group.java
@Entity
public class Group {
@Id
private Long id;

@Index(IfNotNull.class)
private String name;

@Load
@Index
private Ref<User> owner; // Owner of the group. The creator.

OfyService.java
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyFactory;
import com.googlecode.objectify.ObjectifyService;

public class OfyService {
    static {
        factory().register(Category.class);
        factory().register(Group.class);
        factory().register(Image.class);
        factory().register(Judgement.class);
        factory().register(User.class);
        
    }

    public static Objectify ofy() {
        return ObjectifyService.ofy();
    }

    public static ObjectifyFactory factory() {
        return ObjectifyService.factory();
    }
}

UserEndpoint.java
import static com.uandq.lychee.OfyService.ofy;
@Api(name = "sampleEndpoint", namespace = @ApiNamespace(ownerDomain = "sample.com", ownerName = "sample.com", packagePath = ""))
public class UserEndpoint {


@ApiMethod(name = "listUser")
public List<User> listUser() {
List<User> result = new ArrayList<User>();
result = ofy().load().type(User.class).list();
return result;
}

@ApiMethod(name = "getUser")
public User getUser(@Named Long id) {
User user = ofy().load().type(User.class).id(id).now();
return user;
}
@ApiMethod(name = "insertUser")
public User insertUser(User user) {
ofy().save().entity(user).now();
return user;
}

@ApiMethod(name = "removeUser")
public void removeUser(@Named Long id) {
ofy().delete().type(User.class).id(id).now();
}

@ApiMethod(name = "findUserByPhoneNumber")
public User findUserByPhoneNumber(PhoneNumber phone) {

User user = ofy().load().type(User.class)
.filter("phoneNumber ==", phone).first().now();

return user;
}
}

GroupEndpoint.java
import static com.uandq.lychee.OfyService.ofy;

@Api(name = "sampleEndpoint", namespace = @ApiNamespace(ownerDomain = "sample.com", ownerName = "sample.com", packagePath = ""))
public class GroupEndpoint {

@ApiMethod(name = "listGroup")
public List<Group> listGroup() {
List<Group> result = new ArrayList<Group>();
result = ofy().load().type(Group.class).list();
return result;
}

@ApiMethod(name = "getGroup")
public Group getGroup(@Named Long id) {
Group group = ofy().load().type(Group.class).id(id).now();
return group;
}

@ApiMethod(name = "insertGroup")
public Group insertGroup(Group group) {
ofy().save().entity(group).now();
return group;
}

@ApiMethod(name = "removeGroup")
public void removeGroup(@Named Long id) {
ofy().delete().type(Group.class).id(id).now();
}

}

web.xml
<?xml version="1.0" encoding="utf-8" standalone="no"?><web-app version="2.5">
<servlet>
<servlet-name>SystemServiceServlet</servlet-name>
<servlet-class>com.google.api.server.spi.SystemServiceServlet
</servlet-class>
<init-param>
<param-name>services</param-name>
<param-value>com.sample.GroupEndpoint, com.sample.UserEndpoint</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SystemServiceServlet</servlet-name>
<url-pattern>/_ah/spi/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>ObjectifyFilter</filter-name>
<filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ObjectifyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>



Vanessa Gomes

unread,
Jul 16, 2014, 8:15:53 AM7/16/14
to objectify...@googlegroups.com
Also, I tried now to generate the Endpoint libs following these steps: 
  1. Generating a client library for Android using endpoints.sh
via Terminal. And it did not work as well. I still get:

Error: 400 Bad Request

{"error": {"message": "Bad Request", "code": 400, "errors": [{"message": "api exception", "debug_info": "Variable  does not conform to style guide"}]}}

Any help is welcome.

Jon Stevens

unread,
Jul 16, 2014, 12:30:23 PM7/16/14
to objectify...@googlegroups.com
I did a quick search in google for: Variable does not conform to style guide

I found this page which seems to have a lot of helpful information: 

I searched for the word 'conform', which had this bit of text...
  • Most parameter types must be serializable because JSON requires that the objects be serializable.
    • You may also use any JavaBean, which includes anything from your model, since your model objects should conform to the JavaBean standard as described above.

I wonder if adding 'implements Serializable' to your objects would help?
It also sounds like you need zero arg constructors.

best,

jon



--
You received this message because you are subscribed to the Google Groups "objectify-appengine" group.
To unsubscribe from this group and stop receiving emails from it, send an email to objectify-appen...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Vanessa Gomes

unread,
Jul 16, 2014, 1:10:25 PM7/16/14
to objectify...@googlegroups.com
Hey, Jon. 

Thanks for the reply. Zero Arg Constructors are automatic (default) in Java, so there is no need to implement then. And also, Objectify mentions that on their documentation: 
  • There must be a no-arg constructor (or no constructors - Java creates a default no-arg constructor). The no-arg constructor can have any protection level (private, public, etc).

Also, I found the problem. Actually I followed everything on this link you sent to me. Then, there is:
    • Most parameter types must be serializable because JSON requires that the objects be serializable.
      • You may also use any JavaBean, which includes anything from your model, since your model objects should conform to the JavaBean standard as described above.
    • A limited set of types need not be serializable, but must be annotated with @Named. These are the types: String, int/Integer, boolean/Boolean, long/Long.
    In my endpoints, some parameters were using the annotation @Named in a wrong way: without the actual name of the parameter. I don't even need to implement Serializable. I just replaced:

    public User getUser(@Named Long id)

    by

    public User getUser(@Named("id") Long id)

    And all the others @Named parameters. Now I am able to generate the Endpoint libs.

    Thank you very much.



    Vanessa Gomes de Lima                    
    Associate Student - 2013/2014 - BSc Computer Science
    Queen Mary University of London


    --
    You received this message because you are subscribed to a topic in the Google Groups "objectify-appengine" group.
    To unsubscribe from this topic, visit https://groups.google.com/d/topic/objectify-appengine/981f4LlXscg/unsubscribe.
    To unsubscribe from this group and all its topics, send an email to objectify-appen...@googlegroups.com.
    Reply all
    Reply to author
    Forward
    0 new messages