0
votes

I'm trying to work with google cloud endpoint on gae. I'm trying to integrate it maven. I've found this maven plugin to do so : http://code.google.com/p/maven-endpoint-plugin/

I was able to define my api and produce the api. I'am able to call my api when it is deployed on app engine. But when i try to call it localy for debugging, I get the following exception :

javax.servlet.ServletContext log: unavailable
java.lang.IllegalArgumentException: '' not a valid path variable name
    at com.google.api.server.spi.tools.devserver.ParameterizedPath.validateName(ParameterizedPath.java:96)
    at com.google.api.server.spi.tools.devserver.ParameterizedPath.getVariableNames(ParameterizedPath.java:68)
    at com.google.api.server.spi.tools.devserver.ParameterizedPath.<init>(ParameterizedPath.java:53)
    at com.google.api.server.spi.tools.devserver.RestMethodDispatcher.saveRestMethod(RestMethodDispatcher.java:37)
    at com.google.api.server.spi.tools.devserver.RestMethodDispatcher.<init>(RestMethodDispatcher.java:30)
    at com.google.api.server.spi.tools.devserver.RestApiServlet.loadApiConfigs(RestApiServlet.java:120)
    at com.google.api.server.spi.tools.devserver.ApiServlet.init(ApiServlet.java:65)
    at org.mortbay.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:440)
    at org.mortbay.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:339)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
    at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:123)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:61)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.BackendServersFilter.doFilter(BackendServersFilter.java:97)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
    at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:94)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:409)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

mars 07, 2013 2:53:38 PM com.google.apphosting.utils.jetty.JettyLogger warn
Avertissement: /_ah/api/project/v1/addProject
java.lang.IllegalArgumentException: '' not a valid path variable name
    at com.google.api.server.spi.tools.devserver.ParameterizedPath.validateName(ParameterizedPath.java:96)
    at com.google.api.server.spi.tools.devserver.ParameterizedPath.getVariableNames(ParameterizedPath.java:68)
    at com.google.api.server.spi.tools.devserver.ParameterizedPath.<init>(ParameterizedPath.java:53)
    at com.google.api.server.spi.tools.devserver.RestMethodDispatcher.saveRestMethod(RestMethodDispatcher.java:37)
    at com.google.api.server.spi.tools.devserver.RestMethodDispatcher.<init>(RestMethodDispatcher.java:30)
    at com.google.api.server.spi.tools.devserver.RestApiServlet.loadApiConfigs(RestApiServlet.java:120)
    at com.google.api.server.spi.tools.devserver.ApiServlet.init(ApiServlet.java:65)
    at org.mortbay.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:440)
    at org.mortbay.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:339)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
    at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:123)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:61)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.BackendServersFilter.doFilter(BackendServersFilter.java:97)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
    at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:94)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:409)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

And I'm also not able to generate the client libraries (executing mvn compile or with google eclipse plugin)

Has anyone successfully integrated google cloud enpoints with maven : - generating client libraries - testing locally - deploying to app engine and getting it to work (this is the only step, I managed to get working)

here's the pom.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>

    <groupId>com.kubity</groupId>
    <artifactId>Kubity</artifactId>

    <properties>
        <appengine.app.id>!!!!</appengine.app.id>
        <appengine.app.version>!!!!</appengine.app.version>
        <appengine.target.version>1.7.5</appengine.target.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <endpoint.service.classnames>com.kubity.business.project.api.ProjectEndpoint</endpoint.service.classnames>
        <!-- <webappDirectory>${project.build.directory}/${project.build.finalName}</webappDirectory> -->
    </properties>

    <repositories>
        <repository>
            <id>objectify-appengine</id>
            <name>Objectify Maven Repository</name>
            <url>http://objectify-appengine.googlecode.com/svn/maven</url>
        </repository>
        <repository>
            <id>cbreleases</id>
            <url>https://repository-michael.forge.cloudbees.com/release</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>cbreleases</id>
            <url>https://repository-michael.forge.cloudbees.com/release</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

    <dependencies>
        <!-- Compile/runtime dependencies -->
        <dependency>
            <groupId>com.google.appengine</groupId>
            <artifactId>appengine-api-1.0-sdk</artifactId>
            <version>${appengine.target.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <dependency>
            <groupId>com.googlecode.objectify</groupId>
            <artifactId>objectify</artifactId>
            <version>3.1</version>
        </dependency>

        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>persistence-api</artifactId>
            <version>1.0.2</version>
        </dependency>

        <!-- using jersey to test the upload web service, this might change in 
            the future -->
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-server</artifactId>
            <version>1.17</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-json</artifactId>
            <version>1.17</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey.contribs</groupId>
            <artifactId>jersey-multipart</artifactId>
            <version>1.17</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-servlet</artifactId>
            <version>1.17</version>
        </dependency>

        <dependency>
            <groupId>com.google.api</groupId>
            <artifactId>appengine-local-endpoints</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.api</groupId>
            <artifactId>appengine-endpoints</artifactId>
            <version>1.0</version>
        </dependency>

        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.7</version>
        </dependency>

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.2.2</version>
        </dependency>

        <!-- Test Dependencies -->
        <dependency>
            <groupId>com.google.appengine</groupId>
            <artifactId>appengine-testing</artifactId>
            <version>${appengine.target.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.google.appengine</groupId>
            <artifactId>appengine-api-stubs</artifactId>
            <version>${appengine.target.version}</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <version>2.5.1</version>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <archiveClasses>true</archiveClasses>
                    <webResources>
                        <!-- in order to interpolate version from pom into appengine-web.xml -->
                        <resource>
                            <directory>${basedir}/src/main/webapp/WEB-INF</directory>
                            <filtering>true</filtering>
                            <targetPath>WEB-INF</targetPath>
                        </resource>
                    </webResources>
                    <nonFilteredFileExtensions>
                        <nonFilteredFileExtension>p12</nonFilteredFileExtension>
                    </nonFilteredFileExtensions>
                </configuration>
            </plugin>

            <plugin>
                <groupId>com.google.appengine</groupId>
                <artifactId>appengine-maven-plugin</artifactId>
                <version>${appengine.target.version}</version>
                <!--<configuration>
                    <jvmFlags>
                        <jvmFlag>-Xdebug</jvmFlag>
                        <jvmFlag>-Xrunjdwp:transport=dt_socket,address=1044,server=y,suspend=y
                        </jvmFlag>
                    </jvmFlags>
                    <disableUpdateCheck>true</disableUpdateCheck>
                </configuration-->
            </plugin>

            <plugin>
                <groupId>com.mic.endpoint.api</groupId>
                <artifactId>endpoint-maven-plugin</artifactId>
                <version>0.0.2-SNAPSHOT</version>
                <!-- <version>0.0.1</version> -->
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <applicationId>${appengine.app.id}</applicationId>
                    <serviceClassNames>${endpoint.service.classnames}</serviceClassNames>
                    <!-- <apiOutputDirectory>${webappDirectory}/WEB-INF</apiOutputDirectory>
                    <classPath>${webappDirectory}/WEB-INF/classes</classPath> -->
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>javax.persistence</groupId>
                        <artifactId>persistence-api</artifactId>
                        <version>1.0.2</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>

    </build>

</project>
4

4 Answers

1
votes

If you depend on com.google.appengine appengine-endpoints 1.7.7 com.google.appengine appengine-api-1.0-sdk 1.7.7 javax.servlet servlet-api 2.5 provided

and you use the Google App Engine Maven Plugin 1.7.7:

        <plugin>
            <groupId>com.google.appengine</groupId>
            <artifactId>appengine-maven-plugin</artifactId>
            <version>1.7.7</version>
            <executions>
                <execution>
                    <phase>compile</phase>
                    <goals>
                        <goal>endpoints_get_discovery_doc</goal>
                        <!--goal>endpoints_get_client_lib</goal-->
                    </goals>
                </execution>
            </executions>
            <configuration>
                <serviceClassNames>YOURENDPOINTSCLASSES(comma separated)</serviceClassNames>
            </configuration>
        </plugin>

You are good to go with these 2 goals: enpoints_get_discovery_doc and endpoints_get_client_lib

1
votes

I have finally been able to run my endpoints on my local endpoints server. the exception had nothing to do with the maven plugin. I wasn't using enpoint annotation properly and this is why I kept having this exception. I was not able to figure out why it worked on gae production server. here's the mistake : I wrote

public void deleteProject(@Named Long projectId) {
    projectManager.deleteProject(projectId);
}

instead of writing

public void deleteProject(@Named("id") Long projectId) {
    projectManager.deleteProject(projectId);
}

I forgot to define the name parameter for the "@Named" annotation for some of my methods.

0
votes

Can you post your pom.xml.

In advance..you can not create the client libraries with maven plugin. It just create your api file. You have to create them outside using the command tool for endpoints wich comes with the SDK

0
votes

Add this

<dependency>
    <groupId>com.google.appengine</groupId>
    <artifactId>appengine-endpoints</artifactId>
    <version>1.7.6</version>
    <scope>runtime</scope>
</dependency>

to your maven dependency (I am using 1.7.6 version, of course)