is it possible to use Firebase on app engine standard environment? I am aware that the standard environment threading capabilities are very limited and since the Firebase SDK runs a background synchronization thread it might not be compatible. I've gave it a try and I've encountered the following error, which I can't seem to overcome:
java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
Here is the servlet code:
public class GeneratorServlet extends HttpServlet {
FirebaseDatabase database = null;
#Override
public void init(ServletConfig config) {
// ClassLoader classloader = Thread.currentThread().getContextClassLoader();
// InputStream serviceAccount = classloader.getResourceAsStream("serviceAccountKey.json");
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredential(FirebaseCredentials.applicationDefault())
// .setCredential(FirebaseCredentials.fromCertificate(serviceAccount))
.setDatabaseUrl("https://app-name.firebaseio.com/")
.build();
FirebaseApp defaultApp = FirebaseApp.initializeApp(options);
this.database = FirebaseDatabase.getInstance(defaultApp);
}
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
PrintWriter out = resp.getWriter();
out.println(this.database);
this.loadData();
}
private void loadData() {
// The following line throws the error
DatabaseReference ref = this.database.getReference("/publiclyReadable");
}
}
Am I doing it wrong or is it caused by the limitations of the standard environment? I chose the standard environment over flexible because flexible version is not recommended for a production use yet.
Thanks, Jan
Edit:
appengine-web.xml
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>doctor-appointment-system</application>
<version>0</version>
<threadsafe>true</threadsafe>
<instance-class>B1</instance-class>
<manual-scaling>
<instances>1</instances>
</manual-scaling>
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
</system-properties>
</appengine-web-app>
Edit:
web.xml
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>generator</servlet-name>
<servlet-class>com.example.bookingtimes.GeneratorServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>generatorinfo</servlet-name>
<servlet-class>com.example.bookingtimes.GeneratorInfoServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>generator</servlet-name>
<url-pattern>/times/generate</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>generatorinfo</servlet-name>
<url-pattern>/times/change</url-pattern>
</servlet-mapping>
</web-app>
build.gradle:
buildscript { // Configuration for building
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.google.cloud.tools:appengine-gradle-plugin:+'
}
}
repositories { // repositories for Jar's you access in your code
maven {
url 'https://maven-central.storage.googleapis.com'
}
jcenter()
mavenCentral()
}
apply plugin: 'java' // standard Java tasks
apply plugin: 'war' // standard Web Archive plugin
apply plugin: 'com.google.cloud.tools.appengine' // App Engine tasks
dependencies {
providedCompile group: 'javax.servlet', name: 'servlet-api', version: '2.5'
compile 'com.google.appengine:appengine:+'
compile 'com.google.firebase:firebase-admin:4.1.0'
}
appengine { // App Engine tasks configuration
run { // local (dev_appserver) configuration (standard environments only)
port = 8080 // default
}
deploy {
stopPreviousVersion = true // default - stop the current version
promote = true // default - & make this the current version
}
}
group = 'com.example.appengine'
version = '0.1'
sourceCompatibility = 1.7
targetCompatibility = 1.7
The Firebase Database client can be used on App Engine Standard Environment, as long as you put it in manual scaling mode. See the documentation on cloud.google.com.
We recently fixed a problem when using the SDK on App Engine (release notes), so be sure to use the latest version.
I switched to App Engine Flexible (which was straightforward) and everything is working now.
Related
Does useServiceAccountCredential works with P12 file. I am trying to use it in Java and get error com.google.appengine.repackaged.com.google.api.client.http.HttpResponseException‌​: 302 Found
Yes it does. You need to have an AppEngine app serving the remote API. E.g., you would have a python app, with the following lines in app.yaml:
- url: /remoteapi.*
script: google.appengine.ext.remote_api.handler.application
Or java app with the following in web.xml:
<servlet>
<display-name>Remote API Servlet</display-name>
<servlet-name>RemoteApiServlet</servlet-name>
<servlet-class>com.google.apphosting.utils.remoteapi.RemoteApiServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>RemoteApiServlet</servlet-name>
<url-pattern>/remote_api</url-pattern>
</servlet-mapping>
Please note that depending on your client, it might call a bit different url, e.g. /remote_api
Also, if you have deployed the AppEngine app in a module, take that into account in the client code, you would have:
RemoteApiOptions raoptions = new RemoteApiOptions()
.server("my-module-dot-my-project.appspot.com", 443)
.useServiceAccountCredential("my-service-account-id", "my-p12-file.p12");
RemoteApiInstaller installer = new RemoteApiInstaller();
installer.install(raoptions);
Hope that helps!
I am deploying my app using jersey 2.2.0 jars onto google app engine. I have been developing and running locally and it works well during local run/test.
I deployed to the google app engine, and I start getting Error: 404 erros for all resources. Checking google logs, at the first request it spits out the following
org.glassfish.jersey.server.ApplicationHandler initialize: Initiating Jersey application, version Jersey: 2.7 2014-03-12 18:11:31...
The jersey servlet spits out the following
I 09:27:38.889 org.glassfish.jersey.filter.LoggingFilter log: 1 * Server has received a request on thread Request EE25C261
GET http://xxxx.appspot.com/service/users/test
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
Accept-Language: en-US,en;q=0.8
Host: xxxxx.appspot.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36
X-AppEngine-City: bangalore
X-AppEngine-CityLatLong: 12.971599,77.594563
X-AppEngine-Country: IN
X-AppEngine-Region: ka
and then spits out the resource not found
I 09:41:15.094 org.glassfish.jersey.filter.LoggingFilter log: 3 * Server responded with a response on thread Request 9826AB68
< 404
It also adds one more line which suggests
I 09:27:39.180 This request caused a new process to be started for your application, and thus caused your application code to be loaded for the first time. This request may thus take longer and use more CPU than a typical request for your application.
Now, all this works on my local testing but is only an issue when deployed to Google App Engine.
Here's my web.xml
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>
org.glassfish.jersey.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<!-- Enter your Jersey resources to speed up initial Jersey loading
You can separate the java packages using , -->
<param-value>com.poolE.web.rest</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.filter.LoggingFilter</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties" />
</system-properties>
</web-app>
and my jersey class is
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import com.poole.web.jpa.EMFService;
import com.poole.web.jpa.Users;
import com.poole.web.jpa.model.User;
#Path("/users/")
public class UsersResource {
private static final Logger log = Logger.getLogger(UsersResource.class.getName());
#GET
#Produces("application/json")
#Path("test")
public String info() {
log.info("comes into test");
return "Hello Jersey on Google App Engine";
}
}
Any help will be appreciated. I am stuck in this frustrating problem of just plumbing it all together in GAE
I am trying to write a simple Google App Engine application. I am following this tutorial:
https://developers.google.com/appengine/docs/java/gettingstarted/creating, however I cannot make it working.
When testing on the localhost, I receive:
HTTP ERROR 403
Problem accessing /. Reason:
FORBIDDEN
Powered by Jetty://
This is my application code:
package test;
import java.io.IOException;
import javax.servlet.http.*;
public class Test extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.setContentType("text/plain");
resp.getWriter().println("Hello, world");
}
}
My web.xml file:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE web-app PUBLIC
"-//Oracle Corporation//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<servlet>
<servlet-name>test</servlet-name>
<servlet-class>test.Test</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>test</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
My appengine-web.xml file:
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>halocline-test</application>
<version>10</version>
<!--
Allows App Engine to send multiple requests to one instance in parallel:
-->
<threadsafe>true</threadsafe>
<!-- Configure java.util.logging -->
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
</system-properties>
<!--
HTTP Sessions are disabled by default. To enable HTTP sessions specify:
<sessions-enabled>true</sessions-enabled>
It's possible to reduce request latency by configuring your application to
asynchronously write HTTP session data to the datastore:
<async-session-persistence enabled="true" />
With this feature enabled, there is a very small chance your app will see
stale session data. For details, see
http://code.google.com/appengine/docs/java/config/appconfig.html#Enabling_Sessions
-->
</appengine-web-app>
Console output:
Jul 06, 2012 2:42:34 PM com.google.apphosting.utils.jetty.JettyLogger info
INFO: Logging to JettyLogger(null) via com.google.apphosting.utils.jetty.JettyLogger
Jul 06, 2012 2:42:35 PM com.google.apphosting.utils.config.AppEngineWebXmlReader readAppEngineWebXml
INFO: Successfully processed C:\Users\Halocline\workspace\Test\war\WEB-INF/appengine-web.xml
Jul 06, 2012 2:42:35 PM com.google.apphosting.utils.config.AbstractConfigXmlReader readConfigXml
INFO: Successfully processed C:\Users\Halocline\workspace\Test\war\WEB-INF/web.xml
Jul 06, 2012 3:42:36 PM com.google.appengine.tools.development.DevAppServerImpl start
INFO: The server is running at http://localhost:8888/
Jul 06, 2012 3:42:36 PM com.google.appengine.tools.development.DevAppServerImpl start
INFO: The admin console is running at http://localhost:8888/_ah/admin
No errors are shown in the console when I open localhost:8888 in my web browser.
Any idea what I am doing wrong?
You servlet is mapped to http://localhost:8888/test
I believe you might have your index.html file in a wrong directory. Check it did not accidentally slip under WEB-INF. It should be directly under war.
Trying out the hello world tutorial for googleapp engine. But get the 500 server error when I try to go on the deployed app.
http://chemstest.appspot.com/
The index works, but then the servlet gives me the error. Its written in java. I saw some things about case errors in web.xml but the app name and java class are all named in lowercase.
The servlet:
package com.chems.hellogoogleapp;
import java.io.IOException;
import javax.servlet.http.*;
#SuppressWarnings("serial")
public class hellogoogleappServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.setContentType("text/plain");
resp.getWriter().println("Hello, James");
}
}
web.xml:
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<servlet>
<servlet-name>hellogoogleapp</servlet-name>
<servlet-class>com.chems.hellogoogleapp.hellogoogleappServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hellogoogleapp</servlet-name>
<url-pattern>/hellogoogleapp</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
appengine-xml:
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>chemstest</application>
<version>1</version>
<!--
By default, App Engine sends requests serially to a given web server.
To allow App Engine to send multiple requests in parallel specify:
<threadsafe>true</threadsafe>
-->
<!-- Configure java.util.logging -->
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
</system-properties>
</appengine-web-app>
Hopefully an easy one to solve?
I started creating a sample webservice using top-down approach in jboss4.2.2 GA.
From the wsdl, i generated stubs using wsconsume
I created a new java class: SalesTaxImpl implementing the interface in the generated stub. Configured #WebService with endpointInterface, portname, wsdllocation.
My war application has the following:
WEB-INF/classes/
WEB-INF/wsdl/SalesTaxService.wsdl
WEB-INF/web.xml
In web.xml i have,
<web-app>
<servlet>
<servlet-name>SalesTax</servlet-name>
<servlet-class>com.hp.np.ws.SalesTaxImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SalesTax</servlet-name>
<url-pattern>/tax</url-pattern>
</servlet-mapping>
</web-app>
After placing the war in <JBOSS_HOME>/server/default/deploy path, i am getting the following error:
19:25:05,046 INFO [DefaultEndpointRegistry] register: jboss.ws:context=JbossWST
opDown,endpoint=SalesTax
19:25:05,078 INFO [TomcatDeployer] deploy, ctxPath=/JbossWSTopDown, warUrl=.../
tmp/deploy/tmp13893JbossWSTopDown-exp.war/
19:25:05,171 ERROR [MainDeployer] Could not start deployment: file:/C:/jboss-4.2
.2.GA/server/default/deploy/JbossWSTopDown.war
org.jboss.ws.WSException: Cannot build meta data: Cannot get URL for: WEB-INF/ws
dl/SalesTaxService.wsdl
at org.jboss.ws.metadata.builder.jaxws.JAXWSWebServiceMetaDataBuilder.bu
ildWebServiceMetaData(JAXWSWebServiceMetaDataBuilder.java:207)
at org.jboss.ws.metadata.builder.jaxws.JAXWSServerMetaDataBuilder.setupP
roviderOrWebService(JAXWSServerMetaDataBuilder.java:50)
I tried giving different combination, but no luck