Security exception when using non-white listed java class java.nio.channels.spi.SelectorProvider

232 views
Skip to first unread message

Benjamin Glatzeder

unread,
Dec 18, 2015, 3:30:46 PM12/18/15
to Google App Engine
Hi!

Running this line of code
Cluster cluster = CouchbaseCluster.create("MY-IP");
in a bare minimum Java GAE produces a crash.

Couchbase is a NoSQL database.
Gradle import for Couchbase:
compile 'com.couchbase.client:java-client:2.2.2'

Stacktrace:

java.lang.NoClassDefFoundError: Could not initialize class com.google.apphosting.runtime.security.shared.stub.java.nio.channels.spi.SelectorProvider 
at com
.couchbase.client.deps.io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:52)
at com
.couchbase.client.core.env.DefaultCoreEnvironment.<init>(DefaultCoreEnvironment.java:262)
at com
.couchbase.client.java.env.DefaultCouchbaseEnvironment.<init>(DefaultCouchbaseEnvironment.java:124)
at com
.couchbase.client.java.env.DefaultCouchbaseEnvironment.<init>(DefaultCouchbaseEnvironment.java:55)
at com
.couchbase.client.java.env.DefaultCouchbaseEnvironment$Builder.build(DefaultCouchbaseEnvironment.java:472)
at com
.couchbase.client.java.env.DefaultCouchbaseEnvironment.create(DefaultCouchbaseEnvironment.java:158)
at com
.couchbase.client.java.CouchbaseCluster.create(CouchbaseCluster.java:164)
at com
.couchbase.client.java.CouchbaseCluster.create(CouchbaseCluster.java:151)
at ben
.tests.couch8.backend.MyServlet.doPost(MyServlet.java:40)
at javax
.servlet.http.HttpServlet.service(HttpServlet.java:637)
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 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:37)
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:260)
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:78)
at org
.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at com
.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:148)
at com
.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:469)
at com
.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:437)
at com
.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:444)
at com
.google.tracing.CurrentContext.runInContext(CurrentContext.java:256)
at com
.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:308)
at com
.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:300)
at com
.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:441)
at com
.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:235)
at java
.lang.Thread.run(Thread.java:745)

As far as I understand is the class (java.nio.channels.spi.SelectorProvider) not allowed to be executed because of security concerns. All white listed Java classes can be found here: https://cloud.google.com/appengine/docs/java/jrewhitelist Unfortunately this class is used by Couchbase. What would be your suggestion? Shall I host the code at another cloud-service provider?

Kind regards
Benjamin Glatzeder


Adam (Cloud Platform Support)

unread,
Dec 18, 2015, 8:08:44 PM12/18/15
to Google App Engine
Running Couchbase on App Engine would be counterproductive anyway as you have no access to local storage for a backing store. You'd want to host Couchbase on a Google Compute Engine instance where you do have access to local storage and don't have class restrictions, and then access it from App Engine via the Couchbase Java Client library.

Benjamin Glatzeder

unread,
Dec 19, 2015, 3:38:30 AM12/19/15
to Google App Engine
Hi Adam,

we have a small misunderstanding. I'll give a broader picture of what I'll try to accomplish.

User opens (Android) app, then registers/logs in with email-password combination. That's send to an App server (e.g. Google App Engine), that server forwards the request to Couchbase's Sync Gateway. Sync Gateway handles the request and gives an appropriate response. E.g. "User was successfully registered".

The client library you linked is the one I'm using on GAE. Here's the gradle import:
compile 'com.couchbase.client:java-client:2.2.2'

Here is a bit more code:

@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {

   
Cluster cluster = CouchbaseCluster.create("MY-IP");

   
String username = req.getParameter("username");
   
String password = req.getParameter("password");
   
Bucket bucket = cluster.openBucket("MY-BUCKET");
   
ResponseEntity<String> responseEntity = createLogin(bucket, username, password);
   
// TODO: handle result
}

Server falls over at
Cluster cluster = CouchbaseCluster.create("MY-IP");

Stacktrace is in first post.

I use an app server between (Android) app and Couchbase's Sync Gateway because it is explained on the Couchbase Blog. There is a flow diagram below the headline App Server: http://blog.couchbase.com/2015/september/adding-user-sign-up-to-your-android-app-with-node.js-and-couchbase-mobile

I posted my findings first at Couchbase's forum: https://forums.couchbase.com/t/unable-to-access-couchbasecluster-on-google-app-engine/6231

Regards,
Benjamin Glatzeder

Jeff Schnitzer

unread,
Dec 19, 2015, 10:12:41 AM12/19/15
to Google App Engine
NIO is not available on standard Google App Engine. The driver will also have problems creating threads, if it tries to do so (most db drivers seem to, though I haven't looked at Couchdb's). If you really need Couchbase, consider using Managed VMs.

Jeff

--
You received this message because you are subscribed to the Google Groups "Google App Engine" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-appengi...@googlegroups.com.
To post to this group, send email to google-a...@googlegroups.com.
Visit this group at https://groups.google.com/group/google-appengine.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-appengine/e6409e5e-d78e-4d23-8ca6-2a5f6a43ff3f%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Adam (Cloud Platform Support)

unread,
Dec 23, 2015, 8:24:23 PM12/23/15
to Google App Engine
Somehow I completely missed the references to the client library in the stack trace and Gradle import, apologies.


On Friday, December 18, 2015 at 3:30:46 PM UTC-5, Benjamin Glatzeder wrote:
...
Reply all
Reply to author
Forward
0 new messages