Error in creating Cache in Google Apps Engine. net.sf.jsr107cache.CacheException - google-app-engine

I just started to play with MemCache in Google Apps Engine and every time I create CacheFactory I get this error :
net.sf.jsr107cache.CacheException:
Could not find class: 'com.google.appengine.api.memcache.jsr107cache.GCacheFactory'
at net.sf.jsr107cache.CacheManager.getCacheFactory(CacheManager.java:46)
I'm using Apps Engine SDK "1.5.0.1 - 2011-05-16" ( which is the latest ). I tested this in my local.
Anybody know how to fix this issue?
Here is my snippet of my code.
#SuppressWarnings("rawtypes")
Map props = new HashMap();
//props.put(GCacheFactory.EXPIRATION_DELTA, 3600);
try {
CacheFactory cacheFactory = CacheManager.getInstance().getCacheFactory();
cache = cacheFactory.createCache(props);
if(cache.containsKey("userAgent"))
{
userAgent = (String)cache.get("userAgent");
}else
{
cache.put("userAgent", userAgent+" from MEMCache");
}
} catch (CacheException e) {
e.printStackTrace();
}

This should be fixed in App Engine SDK 1.5.0.1.
Make sure you are importing:
import net.sf.jsr107cache.CacheException;
import net.sf.jsr107cache.CacheFactory;
import net.sf.jsr107cache.CacheManager;
I don't have any "Could not find class" error with the following sample code
package classnotfoundtest;
import net.sf.jsr107cache.CacheException;
import net.sf.jsr107cache.CacheFactory;
import net.sf.jsr107cache.CacheManager;
import java.io.IOException;
import javax.servlet.http.*;
#SuppressWarnings("serial")
public class ClassnotfoundtestServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
try {
CacheFactory cacheFactory = CacheManager.getInstance().getCacheFactory();
resp.setContentType("text/plain");
resp.getWriter().println("Hello, world");
} catch (CacheException e) {
e.printStackTrace(resp.getWriter());
}
}
}

Eclipse projects created with App Engine plugin 1.5.0 had the broken jsr107cache-1.1.jar added to their war/WEB-INF/lib directory.
Updating the SDK and plugin doesn't alter your projects, you'll need to fix that yourself.

Related

Capacitor Plugin shows as undefined on android build

Here's a capacitor plugin I found https://github.com/JhonArlex/capacitor_qrcode
and I want it to integrate it to my ionic app, on web serve it works as expected, but when I try on livereload on android, the error screen pops out and says the plugin is undefined..
import "capacitor_qrcode";
import { Plugins } from "#capacitor/core";
//..
await Plugins.QRCodePlugin.getCodeQR();
// QRCodePlugin is undefined?
I'm using Ionic React Capacitor... also would appreciate if you can suggest any other way I could integrate QR code scanning feature on my app thanks!
When using your own plugins you need to register/add it into your android MainActivity.
https://capacitor.ionicframework.com/docs/plugins/android#export-to-capacitor
Like this:
import com.jhon.capacitor_qrcode.QRCodePlugin;
public class MainActivity extends BridgeActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initializes the Bridge
this.init(savedInstanceState, new ArrayList<Class<? extends Plugin>>() {{
// Additional plugins you've installed go here
// Ex: add(TotallyAwesomePlugin.class);
add(QRCodePlugin.class);
}});
}
}

jhipster react remove # to URL

I'm new to the community. I built an e-commercce application with the Jhipster (Java + React Redux) Monolitica. I have the following problem: The application is configured to display a hashtag (#) in the URL for example ... http://localhost:9000/#/. I removed this parameter in React and everything was right. But when I upload the application with Gradle (./gradew) it works, http://localhost:9000/. But if you type directly into the browser http://localhost:9000/home/ I get ERROR 404, Page not found! -----> my application to check the problem (http://www.severobalanceboard.eco.br - OK), (http://www.severobalanceboard.eco.br/historia - ERROR 404)
_
I think this problme by Spring.
Resolved, for remove Hash tag # To URL, using Jhipster and React [Spring + ReactJs]. I use the link of #Gaël Marziou told me.
follows the modifications:
==React==
1 - com/mycompany/myapp/src/main/webapp/app/app.tsx
import { BrowserRouter as Router } from 'react-router-dom';
// import { HashRouter as Router } from 'react-router-dom';
2 - com/mycompany/myapp/src/main/webapp/index.html
<!-- <base href="./"/> -->
<base href="/"/>
3 - com/mycompany/myapp/webpack/webpack.prod.js
},
devServer: {
historyApiFallback: true, /*insert this line - only use for develop*/
stats: options.stats,
hot: true,
contentBase: './build/www',
proxy: [{
context: [
...
==JAVA==
4 - com/mycompany/myapp/src/main/java/br/com/MyApp/config/WebConfigurer.java
#Bean
public Html5RouteFilter html5RouteFilter() {
return new Html5RouteFilter();
}
5 - com/mycompany/myapp/src/main/java/br/com/MyApp/web/Html5RouteFilter.java
YOU NEED CREATE THIS FILE
package com.mycompany.myapp.web;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.regex.Pattern;
/**
* Filter that distinguishes between client routes and server routes when you don't use '#' in client routes.
*/
public class Html5RouteFilter extends OncePerRequestFilter {
private Logger log = LoggerFactory.getLogger(getClass());
// These are the URIs that should be processed server-side
private static final Pattern PATTERN = Pattern.compile("^/((api|content|i18n|management|swagger-ui|swagger-resources)/|error|h2-console|swagger-resources|favicon\\.ico|v2/api-docs).*");
#Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
if (isServerRoute(request)) {
filterChain.doFilter(request, response);
} else {
RequestDispatcher rd = request.getRequestDispatcher("/");
rd.forward(request, response);
}
}
protected static boolean isServerRoute(HttpServletRequest request) {
if (request.getMethod().equals("GET")) {
String uri = request.getRequestURI();
if (uri.startsWith("/app")) {
return true;
}
return PATTERN.matcher(uri).matches();
}
return true;
}
}
===END==
now be happy

Programmatically accessing a Google App Engine Standard servlet that requires Google login

The following is a simple Google App Engine Standard servlet that displays a user’s Google e-mail address if the user is logged in. How can I invoke this programmatically (e.g. using curl or Java code) while providing Google credentials (e.g. for a user or service account). I think I need to obtain an OAuth2 token, but I could use some help coming up with a step-by-step process.
package com.example.appengine.java8;
import java.io.IOException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
#WebServlet(name = "HelloAppEngine", value = "/hello")
public class HelloAppEngine extends HttpServlet {
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
response.setContentType("text/plain");
PrintWriter out = response.getWriter();
if(user == null) {
out.print("not authenticated");
}
else {
out.print(user.getEmail());
}
}
}
Here is a live version of this servlet:
https://servlet-authentication-test.appspot.com/hello
You can use the following link to login with a Google account and then access the servlet while authenticated:
https://accounts.google.com/signin/v2/identifier?service=ah&passive=true&continue=https%3A%2F%2Fappengine.google.com%2F_ah%2Fconflogin%3Fcontinue%3Dhttps%3A%2F%2Fservlet-authentication-test.appspot.com%2Fhello&flowName=GlifWebSignIn&flowEntry=ServiceLogin
You can use GoogleAuthorizationCodeFlow from Google API Client Library to generate a callback request to Google to handle signing in to a Google account. For a detailed example you can take a look at this documentation or at GitHub for the source code.

Datastore export logic in Java

Thankfully, Google announced the export logic from cloud Datastore. I would like to set up schedule-export in my platform. However, it's not Python, but Java. So I need to use cron.xml and Java logic to design this logic.
Is there any reference to design Datastore export logic (cloud_datastore_admin.py) in Java? Especially, I need to transform this part in Java
app = webapp2.WSGIApplication(
[
('/cloud-datastore-export', Export),
], debug=True)
https://cloud.google.com/datastore/docs/schedule-export
You can create the skeleton for App Egnine by following these instructions.
Once you have the skeleton, add something like this to handle export requests:
CloudDatastoreExport.java
package com.google.example.datastore;
import com.google.appengine.api.appidentity.AppIdentityService;
import com.google.appengine.api.appidentity.AppIdentityServiceFactory;
import com.google.apphosting.api.ApiProxy;
import com.google.common.io.CharStreams;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.Logger;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
#WebServlet(name = "CloudDatastoreExport", value = "/cloud-datastore-export")
public class CloudDatastoreExport extends HttpServlet {
private static final Logger log = Logger.getLogger(CloudDatastoreExport.class.getName());
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
// Verify outputURL parameter
String outputUrlPrefix = request.getParameter("output_url_prefix");
if (outputUrlPrefix == null || !outputUrlPrefix.matches("^gs://.*")) {
response.setStatus(HttpServletResponse.SC_CONFLICT);
response.setContentType("text/plain");
response.getWriter().println("Error: Must provide a valid output_url_prefix.");
} else {
// Get project ID
String projectId = ApiProxy.getCurrentEnvironment().getAppId();
// Remove partition information to get plain app ID
String appId = projectId.replaceFirst("(.*~)", "");
// Get access token
ArrayList<String> scopes = new ArrayList<String>();
scopes.add("https://www.googleapis.com/auth/datastore");
final AppIdentityService appIdentity = AppIdentityServiceFactory.getAppIdentityService();
final AppIdentityService.GetAccessTokenResult accessToken =
appIdentity.getAccessToken(scopes);
// Read export parameters
// If output prefix does not end with slash, add a timestamp
if (!outputUrlPrefix.substring(outputUrlPrefix.length() - 1).contentEquals("/")) {
String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
outputUrlPrefix = outputUrlPrefix + "/" + timeStamp + "/";
}
String[] namespaces = request.getParameterValues("namespace_id");
String[] kinds = request.getParameterValues("kind");
// Build export request
JSONObject exportRequest = new JSONObject();
exportRequest.put("output_url_prefix", outputUrlPrefix);
JSONObject entityFilter = new JSONObject();
if (kinds != null) {
JSONArray kindsJSON = new JSONArray(kinds);
entityFilter.put("kinds", kinds);
}
if (namespaces != null) {
JSONArray namespacesJSON = new JSONArray(namespaces);
entityFilter.put("namespaceIds", namespacesJSON);
}
exportRequest.put("entityFilter", entityFilter);
URL url = new URL("https://datastore.googleapis.com/v1/projects/" + appId + ":export");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.addRequestProperty("Content-Type", "application/json");
connection.addRequestProperty("Authorization", "Bearer " + accessToken.getAccessToken());
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
exportRequest.write(writer);
writer.close();
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
JSONTokener exportResponseTokens = new JSONTokener(connection.getInputStream());
JSONObject exportResponse = new JSONObject(exportResponseTokens);
response.setContentType("text/plain");
response.getWriter().println("Export started:\n" + exportResponse.toString(4));
} else {
InputStream s = connection.getErrorStream();
InputStreamReader r = new InputStreamReader(s, StandardCharsets.UTF_8);
String errorMessage =
String.format(
"got error (%d) response %s from %s",
connection.getResponseCode(), CharStreams.toString(r), connection.toString());
log.warning(errorMessage);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.setContentType("text/plain");
response.getWriter().println("Failed to initiate export.");
}
}
}
}
You can use the same cron.yaml from the docs:
cron:
- description: "Daily Cloud Datastore Export"
url: /cloud-datastore-export?namespace_id=&output_url_prefix=gs://BUCKET_NAME[/NAMESPACE_PATH]
target: cloud-datastore-admin
schedule: every 24 hours
Use gcloud to deploy the cron job:
gcloud app deploy cron.yaml
Make sure you complete this part to give GAE export and bucket permissions or else
you'll get permission denied errors:
https://cloud.google.com/datastore/docs/schedule-export#before_you_begin
The code snippet you showed is just a part of the typical GAE app skeleton specific for 1st generation standard environment python apps. You can easily recognize it in the main.py section of the python quickstart Hello World code review.
The code initializes the app variable (from the main python module, i.e. the main.py file) which is referenced in the app.yaml handler config as script: main.app.
The corresponding java app skeleton is significantly different, see the java quickstart Hello World code review. But no worries, you shouldn't need to specifically transform that code snippet, you just need to build your java app skeleton and focus on what the app handler actually does - making those POST requests to the datastore. Sorry I can't help more, but I'm not a java user.
What I really realized is that app.yaml is like Web.xml in java
and cloud-datastore-export is a servlet that communicates with gae to export data but I can't do more

API Call from App Engine flexible to Firebase FCM failed

API Calls,e.g. to Firebase https://fcm.googleapis.com/fcm/send worked before switching from <env>vm</env> appengine-web.xml to
env: flex app.yaml flexible.
When deploying with mvn appengine:deploy everything is fine, but when an API call gets fired, which worked before, i get the exception below:
Exception in thread "Thread-14" com.google.apphosting.api.ApiProxy$CallNotFoundException:
Can't make API call urlfetch.Fetch in a thread that is neither the original request thread nor a thread created by ThreadManager
at com.google.apphosting.api.ApiProxy$CallNotFoundException.foreignThread(ApiProxy.java:800)
at com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:112)
at com.google.appengine.api.urlfetch.URLFetchServiceImpl.fetch(URLFetchServiceImpl.java:40)
at com.google.api.client.extensions.appengine.http.UrlFetchRequest.execute(UrlFetchRequest.java:74)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:981)
at com.qweez.flexenv.service.GameCounterService.run(GameCounterService.java:80)
it crashes when calling request.execute() below:
import com.google.api.client.http.ByteArrayContent;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpResponse;
import java.io.IOException;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;
// stuff
try {
HttpRequest request = HttpRequestUtil.getHttpRequestFactory().buildPostRequest(new GenericUrl(GlobalConfig.MESSAGING_SERVER_URL), ByteArrayContent.fromString("application/json", requestBody));
HttpResponse response = request.execute();
//logger.warning(LOG_TAG+" ++++++ response status=" + response.getContent());
} catch (IOException e) {
logger.warning(LOG_TAG+" sent messge to topic error: " + e.getMessage());
}
the helper class httpRequestUtil looks like this
import com.google.api.client.extensions.appengine.http.UrlFetchTransport;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import java.io.IOException;
public class HttpRequestUtil {
private static HttpTransport httpTransport;
private static HttpRequestFactory requestFactory;
static {
httpTransport = UrlFetchTransport.getDefaultInstance();
requestFactory = httpTransport.createRequestFactory(new HttpRequestInitializer() {
#Override
public void initialize(com.google.api.client.http.HttpRequest httpRequest) throws IOException {
HttpHeaders hh = new HttpHeaders();
hh.setAuthorization(GlobalConfig.SERVER_KEY);
hh.setContentType("application/json");
httpRequest.setHeaders(hh);
}
});
}
public static HttpRequestFactory getHttpRequestFactory(){
return requestFactory;
}
Is there something deprecated now?
Or what's the issue here now?
Any help very appreciated. Thanks!

Resources