Skip to content
This repository has been archived by the owner on Sep 17, 2022. It is now read-only.

Error Code: 503 [java.lang.IllegalStateException: You have not started an Objectify context. You are probably missing the ObjectifyFilter. If you are not running in the context of an http request, see the ObjectifyService.run() method.] #73

Open
hardyt opened this issue Apr 19, 2016 · 10 comments

Comments

@hardyt
Copy link

hardyt commented Apr 19, 2016

After copying all the file contents into my existing backend I receive this error when trying to send a message:

Error Code: 503 [java.lang.IllegalStateException: You have not started an Objectify context. You are probably missing the ObjectifyFilter. If you are not running in the context of an http request, see the ObjectifyService.run() method.]

I have the following in my web.xml:

<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
    <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>
    <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.atrware.gcphealthcare.backend.RegistrationEndpoint, com.atrware.gcphealthcare.backend.MessagingEndpoint</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>SystemServiceServlet</servlet-name>
        <url-pattern>/_ah/spi/*</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>MyServlet</servlet-name>
        <servlet-class>com.atrware.gcphealthcare.backend.MyServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>


    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
</web-app>

What could be the issue?

@patflynn
Copy link
Contributor

Hey there,

are you using Android Studio to generate this backend? What does your
backend build.gradle look like?

On Tue, Apr 19, 2016 at 5:22 PM, Tom notifications@github.com wrote:

After copying all the file contents into my existing backend I receive
this error when trying to send a message:

Error Code: 503 [java.lang.IllegalStateException: You have not started an
Objectify context. You are probably missing the ObjectifyFilter. If you are
not running in the context of an http request, see the
ObjectifyService.run() method.]

I have the following in my web.xml:

ObjectifyFilter com.googlecode.objectify.ObjectifyFilter ObjectifyFilter /_ SystemServiceServlet com.google.api.server.spi.SystemServiceServlet services com.atrware.gcphealthcare.backend.RegistrationEndpoint, com.atrware.gcphealthcare.backend.MessagingEndpoint SystemServiceServlet /_ah/spi/_ MyServlet com.atrware.gcphealthcare.backend.MyServlet MyServlet /hello
<welcome-file-list>
    <welcome-file>index.html</welcome-file>
</welcome-file-list>

What could be the issue?


You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
#73

@hardyt
Copy link
Author

hardyt commented Apr 19, 2016

Wow, thanks for the super quick response! Yes, I used Android Studio 2.0 to generate the backend using a slightly different GCM tutorial. I can't find the link at the moment, but it implemented GcmSender.java.

backend build.gradle:

// If you would like more information on the gradle-appengine-plugin please refer to the github page
// https://github.com/GoogleCloudPlatform/gradle-appengine-plugin

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.google.appengine:gradle-appengine-plugin:1.9.28'
    }
}

repositories {
    jcenter();
}

apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'appengine'
apply plugin: 'application'

mainClassName = "com.atrware.gcphealthcare.backend.GcmSender"

sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7

//sourceCompatibility = JavaVersion.VERSION_1_8
//targetCompatibility = JavaVersion.VERSION_1_8

run {
    def params = []
    if (project.hasProperty('msg')) {
        params.add(project.msg)
        if (project.hasProperty('to')) {
            params.add(project.to)
        }
    }
    args params
}

dependencies {
    appengineSdk 'com.google.appengine:appengine-java-sdk:1.9.28'
    compile 'javax.servlet:servlet-api:2.5'
    compile 'com.firebase:firebase-client-jvm:2.5.2'
    compile 'org.apache.httpcomponents:httpclient:4.5.2'
    compile 'com.google.appengine:appengine-api-1.0-sdk:1.9.34'
    compile 'com.google.appengine:appengine-endpoints:1.9.34'
    compile 'com.google.appengine:appengine-endpoints-deps:1.9.34'
    compile 'org.apache.commons:commons-io:1.3.2'
    compile 'com.googlecode.objectify:objectify:5.1.12'
    compile 'com.ganyo:gcm-server:1.0.2'
    compile 'org.json:json:20140107'
}

appengine {
  downloadSdk = true
  appcfg {
    oauth2 = true
  }
    endpoints {
        getClientLibsOnBuild = true
        getDiscoveryDocsOnBuild = true
    }
}

@patflynn
Copy link
Contributor

Hi Tom,

I think there's a chance you're making an Objectify call outside of the
scope of a servlet request.

Without the full code it's hard for me to say. I'd need a link to the
tutorial you followed to say for sure.

On Tue, Apr 19, 2016 at 5:34 PM, Tom notifications@github.com wrote:

Wow, thanks for the super quick response! Yes, I used Android Studio 2.0
to generate the backend using a slightly different GCM tutorial. I can't
find the link at the moment, but it implemented GcmSender.java.

backend build.gradle:

// If you would like more information on the gradle-appengine-plugin please refer to the github page
// https://github.com/GoogleCloudPlatform/gradle-appengine-plugin

buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.google.appengine:gradle-appengine-plugin:1.9.28'
}
}

repositories {
jcenter();
}

apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'appengine'
apply plugin: 'application'

mainClassName = "com.atrware.gcphealthcare.backend.GcmSender"

sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7

//sourceCompatibility = JavaVersion.VERSION_1_8
//targetCompatibility = JavaVersion.VERSION_1_8

run {
def params = []
if (project.hasProperty('msg')) {
params.add(project.msg)
if (project.hasProperty('to')) {
params.add(project.to)
}
}
args params
}

dependencies {
appengineSdk 'com.google.appengine:appengine-java-sdk:1.9.28'
compile 'javax.servlet:servlet-api:2.5'
compile 'com.firebase:firebase-client-jvm:2.5.2'
compile 'org.apache.httpcomponents:httpclient:4.5.2'
compile 'com.google.appengine:appengine-api-1.0-sdk:1.9.34'
compile 'com.google.appengine:appengine-endpoints:1.9.34'
compile 'com.google.appengine:appengine-endpoints-deps:1.9.34'
compile 'org.apache.commons:commons-io:1.3.2'
compile 'com.googlecode.objectify:objectify:5.1.12'
compile 'com.ganyo:gcm-server:1.0.2'
compile 'org.json:json:20140107'
}

appengine {
downloadSdk = true
appcfg {
oauth2 = true
}
endpoints {
getClientLibsOnBuild = true
getDiscoveryDocsOnBuild = true
}
}


You are receiving this because you commented.
Reply to this email directly or view it on GitHub
#73 (comment)

@hardyt
Copy link
Author

hardyt commented Apr 20, 2016

I found the code that breaks it. It's inside appengine-web.xml. The Google/Android/Appengine/Firebase tutorial specifies manual scaling. This breaks this tutorial. Any idea on how to work around this?

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    <application>atrware</application>
    <version>1</version>
    <threadsafe>true</threadsafe>
    <manual-scaling> <------------------- This element breaks this GCM tutorial/template
        <instances>1</instances>
    </manual-scaling>
    <system-properties>
        <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
        <property name="gcm.api.key" value="AIzaSyD6rHzF0MvHWiU47RLLbupQDEal4y3mUbM"/>
    </system-properties>
</appengine-web-app>

"To use Firebase with App Engine, you must use manual scaling. This is because Firebase uses background threads to listen for changes and App Engine only allows long-lived background threads on manually scaled backend instances."

So this means I can only use Firebase or GCM? Not both?

The full code is here, but all the pertinent files are the same as this tutorial with the exception of adding my app's information (name/api key).

@hardyt
Copy link
Author

hardyt commented Apr 20, 2016

Another note: When that element is removed, I get a success message on the local instance and am able to receive a push notification on the Android emulator client. When the app is deployed, I don't see any result - no success and no error- if that element is included or removed. No notification is sent to the client. The client does say it has sent the token to the server.

I see this in Chrome's console:

cb=gapi.loaded_0:160 GET https://www.atrware.com/_ah/api/static/proxy.html?jsh=m%3B%2F_%2Fscs%2Fapps…res__%2Fam%3DAQ%2Frt%3Dj%2Fd%3D1%2Frs%3DAGLTcCMCp0KeucYH1ftSCLjBQaTZ3eOfcA net::ERR_CONNECTION_CLOSED

The Appengine log only shows a successful GET:

23:11:01.730 GET 200 0 B 2 ms Chrome 49 /?
 ipaddress - - [19/Apr/2016:23:11:01 -0600] "GET /? HTTP/1.1" 200 - http://www.atrware.com/? "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "www.atrware.com" ms=2 cpu_ms=0 cpm_usd=0 instance=- app_engine_release=1.9.36 trace_id=284b75fa284b9a9a25c28b1aeccf5b0b

Update: Removing the manual scaling, I can run it fine from http://atrware.appspot.com/, but not from http://www.atrware.com/ (getting that ERR_CONNECTION_CLOSED). What should I change to run it from my domain?

@patflynn
Copy link
Contributor

You should be able to use Firebase and GCM. Your problem is actually
around setting up the Objectify context. The Objectify filter does so
automatically for all servlet request threads, but if you're trying to use
Objectify from a background thread you'll need to set it up manually.

It's not my area of expertise but looking at what the filter actually does:
https://github.com/objectify/objectify/blob/master/src/main/java/com/googlecode/objectify/ObjectifyFilter.java,
it looks like you may be able to simply use a try with resources block
around your objectify operations like this:
try (Closeable closeable = ObjectifyService.begin()) {
// do your objectify read and writes here
}

On Wed, Apr 20, 2016 at 1:13 AM, Tom notifications@github.com wrote:

Another note: When that element is removed, I get a success message on the
local instance. When the app is deployed, I don't see any result - no
success and no error. The Appengine log only shows a successful GET:

23:11:01.730 GET 200 0 B 2 ms Chrome 49 /?
ipaddress - - [19/Apr/2016:23:11:01 -0600] "GET /? HTTP/1.1" 200 - http://www.atrware.com/? "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36" "www.atrware.com" ms=2 cpu_ms=0 cpm_usd=0 instance=- app_engine_release=1.9.36 trace_id=284b75fa284b9a9a25c28b1aeccf5b0b


You are receiving this because you commented.
Reply to this email directly or view it on GitHub
#73 (comment)

@hardyt
Copy link
Author

hardyt commented Apr 20, 2016

Pat, thanks for your quick answers. It's too bad there is no clear resolution to this.

I think there are multiple "gotchas" I'm running into. In addition to the possible ObjectifyFilter modification, at least one other "gotcha" is that Google Cloud Endpoints doesn't work on custom domains. That should be a note/requirement in the README for this tutorial

As for a way forward to close this out, Firebase was important, but not critical to my backend. I'll explore more in a few weeks since there is no clear resolution and I have lots of other work to finish before the end of the semester. I can't spend hours troubleshooting what should be a one line requirement either here, in notes for Objectify, or in notes for GCM.

@patflynn
Copy link
Contributor

Sorry we couldn't more helpful. I am actually not very well versed in
using GCM. This project is owned by the Android Studio cloud plugin team so
our focus is on the IDE integration. You may want to try using the GCM
stackoverflow tag
http://stackoverflow.com/questions/tagged/google-cloud-messaging to ask
your question. You may find someone there who might be able to help you.

On Wed, Apr 20, 2016 at 1:59 PM, Tom notifications@github.com wrote:

Pat, thanks for your quick answers. It's too bad there is no clear
resolution to this.

I think there are multiple "gotchas" I'm running into. In addition to the
possible ObjectifyFilter modification, at least one other "gotcha" is that
GCM doesn't work on custom domains. That should be a note/requirement in
the README for this tutorial

As for a way forward to close this out, Firebase was important, but not
critical to my backend. I'll explore more in a few weeks since there is no
clear resolution and I have lots of other work to finish before the end of
the semester. I can't spend hours troubleshooting what should be a one line
requirement either here, in notes for Objectify, or in notes for GCM.


You are receiving this because you commented.
Reply to this email directly or view it on GitHub
#73 (comment)

@tsanidas
Copy link

Leaving this here for posterity... It seems that only when using basic-scaling or manual-scaling that GAE uses a RequestDispatcher.forward() to route this to your backend module. This means that we can tell the Objectify filter to honor that by making your web.xml entry look like this:

    <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>
        <!-- Next three lines are for request dispatcher actions -->
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

Good luck!

@stsandro
Copy link

stsandro commented Oct 21, 2016

<dispatcher>REQUEST</dispatcher> <dispatcher>INCLUDE</dispatcher> <dispatcher>FORWARD</dispatcher>
Had the same problem. Those three lines somehow magically solved it.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants