Visar inlägg med etikett java. Visa alla inlägg
Visar inlägg med etikett java. Visa alla inlägg

2018-01-02

Compiling JavaScript on Serverside With Scala and ScalaJS using Google Standard App Engine

Compiling JavaScript on Serverside With Scala and ScalaJS using Google Standard App Engine 

Since my experience with the JavaScript world and exploration of ScalaJS I felt compelled to move from Node and Grunt and try to fully utilize Scala for both front and back.
I reached a goal with Scala Stack, a concept of creating all web content on serverside using only Scala code. The concept is extended to keep everything in code including configuration to be fully testable.

Obvious Advantages

My main purpose was to skip the JavaScript world but it moved on to something much larger. If all code is shared there are quite a few advantages
  • Single, isomorphic source which ease work and can share logic
  • Share data by keeping it in code. For instance languages could be defined with a Enum type
  • Fully testable code
  • No JavaScript package manager like NPM or WebPack
  • No pre processor like Gulp or Grunt
  • No SBT since the compilation is with a simple Servlet  

Risks

There are some traps though 
  • Security, some code should not be shared between backend and frontend
  • Long term effects, demands an experienced architect 
  • Shared code needs to be ScalaJS compatible and cannot use backend dependencies since it's compiled and used on frontend

Scala Stack

Map of Scala Stack

I've made three implementations using Google Standard Environment with Java 8. Implemented in native JavaScript, jQuery and AngularJS.
Goal is to keep everything in code and to avoid configuration, annotations and settings in Strings.
By only using Scala on serverside, it produce HTML, CSS and JavaScript which is all components for a webpage. 

Scala Stack with Angular

You find links to code and running example below

Servlet Compiler

Scala Stack is using a Servlet compiler with different logging:

2017-12-10

Servlet Using Google Vision API Sample

Servlet Using Google Vision API

A simple servlet with POST getting an image URL and performs a SAFE SEARCH check using Google Vision API.
Note that it doesn't contain authorization. You can do it locally on your machine or run it live at App Engine using it's service account (it does that automatic so you just deploy it).

2016-05-30

Uppdated! "Cannot determine the default location of the Google Cloud SDK" Solved

Error

Got a really annoying error while trying to run my local Flexible Environment with GCloud 
$ mvn -Dgcloud.gcloud_directory="c:\path\to\gcloud-sdk\" gcloud:run
[ERROR] Cannot determine the default location of the Google Cloud SDK.
[ERROR] If you need to install the Google Cloud SDK, follow the instructions located at https://cloud.google.com/appengine/docs/java/managed-vms
[ERROR] You can then set it via <gcloud_directory> </gcloud_directory> in the pom.xml
[ERROR]
org.apache.maven.plugin.MojoExecutionException: Unkown Google Cloud SDK location:C:\...\gcloud_sdk
        at com.google.appengine.gcloudapp.AbstractGcloudMojo.setupInitialCommands(AbstractGcloudMojo.java:170)
        at com.google.appengine.gcloudapp.GCloudAppRun.getCommand(GCloudAppRun.java:306)
        at com.google.appengine.gcloudapp.GCloudAppRun.execute(GCloudAppRun.java:292)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:207)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:863)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:199)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.441 s
[INFO] Finished at: 2016-05-30T20:21:34+02:00
[INFO] Final Memory: 24M/380M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal com.google.appengine:gcloud-maven-plugin:2.0.9.74.v20150814:run (default-cli) on project scala-js-compiler: Execution error: org.apache.maven.plugin.MojoExecutionException: Unkown Google Cloud SDK location:C:...\gcloud_sdk -> [Help 1]

Solution

It was much easier to solve! Just add Python to path (which is bundled in the Gcloud SDK).
But managed to use the locally installed python to run the python script which starts development server:
$ cd project
$ c:\...\gcloud_sdk\google-cloud-sdk\platform\bundledpython\python.exe c:\...\gcloud_sdk\google-cloud-sdk\bin\dev_appserver.py src\main\webapp

2015-11-12

Objectify and Scala

Objectify and Scala

There are some learning steps to combine Objectify with Scala. One interesting piece of code is Objectify's:
ObjectifyService.ofy().loader().type(EntityClass.class);
It's not possible to type "type" or "class" in Scala. The first one needs to be escaped and the other have a predefined function:
ObjectifyService.ofy().loader.`type`(classOf[EntityClass])

Scala Example

You can find a complete example here:


2015-11-09

Google App Engine + Scala + ScalaJS + Objectify

Created a single Maven project combining Google App Engine, Scala, ScalaJS and Objectify.

Description

A Scala implementation of Filter using Objectify, a separate source directory for ScalaJS which is generating JavaScript with SBT.

2015-11-08

Google Endpoints + Objectify

Created a small project combining Google Endpoints with Objectify. Added page with a simple JavaScript introduction.

Fabric

There is a small sample for creating some data and getting it.

Creating

As a sample, it's possible to create three different entities
  • EntityId, with POST, creates a new id
  • EntityData, with POST
  • EntityPrimitives, with POST
When posting an EntityId, the response will be its new id.
When posting an EntityData or EntityPrimitives, use the same id as EntityId.

Fetching

To get each type, there's a GET path like
/entityid/123
/entitydata/123
To get the EntityId and all children with the same id, it's possible to use
/entityid/123/entitydata+entityprimitives/

2015-09-12

App Engine + Scala + Java + SBT + Eclipse

Combining Java App Engine with Scala and SBT, and Import to Eclipse

Forked and added Eclipse plugin, to in a easy way run a App Engine project in Eclipse and with Scala.

2015-02-05

Auth0 + Google App Engine (Java) = "Running on GAE? Fine. No cookie support for you!"

Had some troubles implementing Auth0 Java example code to Google App Engine since ...


  1. W2015-02-05 20:25:28.236
    [s~workaround-town/1.382027755131049112].<stderr>: No CookieHandler. Running on GAE? Fine. No cookie support for you!
    
    
  2. W2015-02-05 20:25:28.239
    Error for /auth0-callback/
    java.lang.ExceptionInInitializerError
     at com.auth0.Auth0ServletCallback.createResty(Auth0ServletCallback.java:168)
     at com.auth0.Auth0ServletCallback.fetchTokens(Auth0ServletCallback.java:109)
     at com.auth0.Auth0ServletCallback.doGet(Auth0ServletCallback.java:73)
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
     at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
     at se.ce.workaround.WorkaroundFilter.doHttpFilter(WorkaroundFilter.java:145)
     at se.ce.util.web.singlepage.DefaultFilter.doFilter(DefaultFilter.java:38)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.googlecode.objectify.cache.AsyncCacheFilter.doFilter(AsyncCacheFilter.java:58)
     at com.googlecode.objectify.ObjectifyFilter.doFilter(ObjectifyFilter.java:48)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
     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 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.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:254)
     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.headerComplete(HttpConnection.java:923)
     at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
     at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
     at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:146)
     at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:484)
     at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:438)
     at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:445)
     at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:220)
     at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:309)
     at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:301)
     at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:442)
     at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251)
     at java.lang.Thread.run(Thread.java:724)
    Caused by: java.security.AccessControlException: access denied ("java.net.NetPermission" "setDefaultAuthenticator")
     at java.security.AccessControlContext.checkPermission(AccessControlContext.java:375)
     at java.security.AccessController.checkPermission(AccessController.java:565)
     at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
     at com.google.apphosting.runtime.security.CustomSecurityManager.checkPermission(CustomSecurityManager.java:56)
     at java.net.Authenticator.setDefault(Authenticator.java:127)
     at us.monoid.web.Resty.<clinit>(Resty.java:94)
     ... 43 more
    
  3. W2015-02-05 20:25:28.241
    Nested in java.lang.ExceptionInInitializerError:
    java.security.AccessControlException: access denied ("java.net.NetPermission" "setDefaultAuthenticator")
     at java.security.AccessControlContext.checkPermission(AccessControlContext.java:375)
     at java.security.AccessController.checkPermission(AccessController.java:565)
     at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
     at com.google.apphosting.runtime.security.CustomSecurityManager.checkPermission(CustomSecurityManager.java:56)
     at java.net.Authenticator.setDefault(Authenticator.java:127)
     at us.monoid.web.Resty.<clinit>(Resty.java:94)
     at com.auth0.Auth0ServletCallback.createResty(Auth0ServletCallback.java:168)
     at com.auth0.Auth0ServletCallback.fetchTokens(Auth0ServletCallback.java:109)
     at com.auth0.Auth0ServletCallback.doGet(Auth0ServletCallback.java:73)
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
     at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
     at se.ce.workaround.WorkaroundFilter.doHttpFilter(WorkaroundFilter.java:145)
     at se.ce.util.web.singlepage.DefaultFilter.doFilter(DefaultFilter.java:38)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.googlecode.objectify.cache.AsyncCacheFilter.doFilter(AsyncCacheFilter.java:58)
     at com.googlecode.objectify.ObjectifyFilter.doFilter(ObjectifyFilter.java:48)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
     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 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.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:254)
     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.headerComplete(HttpConnection.java:923)
     at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
     at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
     at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:146)
     at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:484)
     at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:438)
     at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:445)
     at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:220)
     at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:309)
     at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:301)
     at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:442)
     at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251)
     at java.lang.Thread.run(Thread.java:724)
    
  4. C2015-02-05 20:25:28.244
    Uncaught exception from servlet
    java.lang.ExceptionInInitializerError
     at com.auth0.Auth0ServletCallback.createResty(Auth0ServletCallback.java:168)
     at com.auth0.Auth0ServletCallback.fetchTokens(Auth0ServletCallback.java:109)
     at com.auth0.Auth0ServletCallback.doGet(Auth0ServletCallback.java:73)
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
     at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
     at se.ce.workaround.WorkaroundFilter.doHttpFilter(WorkaroundFilter.java:145)
     at se.ce.util.web.singlepage.DefaultFilter.doFilter(DefaultFilter.java:38)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.googlecode.objectify.cache.AsyncCacheFilter.doFilter(AsyncCacheFilter.java:58)
     at com.googlecode.objectify.ObjectifyFilter.doFilter(ObjectifyFilter.java:48)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
     at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
     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 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.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:254)
     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.headerComplete(HttpConnection.java:923)
     at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
     at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
     at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:146)
     at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:484)
     at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:438)
     at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:445)
     at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:220)
     at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:309)
     at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:301)
     at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:442)
     at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251)
     at java.lang.Thread.run(Thread.java:724)
    Caused by: java.security.AccessControlException: access denied ("java.net.NetPermission" "setDefaultAuthenticator")
     at java.security.AccessControlContext.checkPermission(AccessControlContext.java:375)
     at java.security.AccessController.checkPermission(AccessController.java:565)
     at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
     at com.google.apphosting.runtime.security.CustomSecurityManager.checkPermission(CustomSecurityManager.java:56)
     at java.net.Authenticator.setDefault(Authenticator.java:127)
     at us.monoid.web.Resty.<clinit>(Resty.java:94)
     ... 43 more
Will create a Auth0Callback suited for Google App Engine. Take a look at my Github:
https://github.com/AIMMOTH/GAEAuth0Callback