[
https://issues.apache.org/jira/browse/JCLOUDS-881?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14492218#comment-14492218
]
Ignasi Barrera commented on JCLOUDS-881:
----------------------------------------
The linked issue is about reflection issues, when using it to make fields
accessible. jclouds mostly uses that to deserialize the json/xml http responses
into the java domain objects. Due to the immutable nature of the jclouds domain
model, this is needed in some cases to get all fields properly populated (and
I'm not sure if the underlying libraries used to serialize/deserialize will
already use that kind of reflection).
This said, we can workaround that by changing all {{setAccessible}} calls to be
a "best effort" and don't fail. That could mean that some object could have
incomplete info, but it's worth trying it. After that PoC, a more complex but
better solution would be to do that only when using the GAE module, but all
that reflection happens in static code that is used to cache the Method and
Constructor objects (to avoid the reflection overhead jclouds caches them), so
that would require some structural changes that are not that trivial.
This is the list of places where we manually call the {{setAccessible}} method,
in case you want to try/catch them to do a proof of concept (you can ignore the
ones in the "test" folders):
{code}
ibarrera@ibarrera:~/src/asf/jclouds (master) $ find . -name *.java -exec grep
-nH 'setAccessible' {} \;
./compute/src/test/java/org/jclouds/compute/domain/TemplateBuilderSpecTest.java:669:
f.setAccessible(true);
./core/src/test/java/org/jclouds/reflect/Reflection2OverriddenMethodTest.java:109:
field.setAccessible(true);
./core/src/test/java/org/jclouds/reflect/Reflection2OverriddenMethodTest.java:122:
field.setAccessible(true);
./core/src/test/java/org/jclouds/proxy/ProxyForURITest.java:81:
useProxyForSockets.setAccessible(true);
./core/src/test/java/org/jclouds/proxy/ProxyForURITest.java:100:
useProxyForSockets.setAccessible(true);
./core/src/main/java/org/jclouds/json/internal/NullHackJsonLiteralAdapter.java:61:
outField.setAccessible(true);
./core/src/main/java/org/jclouds/http/internal/JavaUrlHttpCommandExecutorService.java:240:
delegateField.setAccessible(true);
./core/src/main/java/org/jclouds/http/internal/JavaUrlHttpCommandExecutorService.java:261:
methodField.setAccessible(true);
./core/src/main/java/org/jclouds/reflect/Reflection2.java:156:
ctor.setAccessible(true);
./core/src/main/java/org/jclouds/reflect/Reflection2.java:163:
method.setAccessible(true);
./core/src/main/java/org/jclouds/reflect/Reflection2.java:320:
method.setAccessible(true);
./core/src/main/java/org/jclouds/logging/config/BindLoggersAnnotatedWithResource.java:83:
field.setAccessible(true);
./scriptbuilder/src/test/java/org/jclouds/scriptbuilder/statements/login/AdminAccessBuilderSpecTest.java:184:
f.setAccessible(true);
{code}
Apart from the reflection issues, the stacktrace you provide seems to complain
about proxy objects. Is that correct? jclouds uses proxy objects to generate
the HTTP requests, and that is something we won't be able to change, at least
without refactoring a big part of the jclouds core.
> Can't create ComputeServiceContext for aws-ec2 in Google App Engine
> -------------------------------------------------------------------
>
> Key: JCLOUDS-881
> URL: https://issues.apache.org/jira/browse/JCLOUDS-881
> Project: jclouds
> Issue Type: Bug
> Affects Versions: 1.8.1, 1.9.0
> Environment: Google App Engine SDK 1.9.18; Java 1.8.0_05; Eclipse
> Luna; Windows 8.1 (could not replicate on same codebase running in Debian
> GNU/Linux; GAE 1.9.17; Java 1.7.0_65.)
> Reporter: Christopher Lane Hinson (w/ Web Performance)
>
> Hi, I'm writing on the understanding that you hope JClouds will work in a
> Google App Engine environment, where I'm having the problem described below.
> I'm having a hard time understanding how anyone can use the aws-ec2 provider
> in GAE at all under these conditions. Either I'm failing at something
> elementary, or everyone else lined up for this issue hasn't upgraded to the
> problematic version of something yet.
> Thanks in advance for your assistance.
> (1) Create a new Google App Engine project using the tools in Eclipse.
> (2) Use the following as your servlet:
> package com.webperformance.bugs.jclouds;
> import java.io.IOException;
> import javax.servlet.http.*;
> import org.jclouds.ContextBuilder;
> import org.jclouds.aws.ec2.AWSEC2Api;
> import org.jclouds.compute.ComputeServiceContext;
> @SuppressWarnings("serial")
> public class Jclouds_app_engine_bugServlet extends HttpServlet {
> public void doGet(HttpServletRequest req, HttpServletResponse resp)
> throws IOException {
>
> ComputeServiceContext context =
> ContextBuilder.newBuilder("aws-ec2")
> .credentials("my valid access key", "my valid
> secret key")
> .buildView(ComputeServiceContext.class); //
> <<---- explodes here
> AWSEC2Api ec2Api = context.unwrapApi(AWSEC2Api.class);
> /* //tried this instead, same thing
> AWSEC2Api ec2Api = ContextBuilder.newBuilder("aws-ec2")
> .credentials(data._access_key, data._secret_key)
> .buildApi(AWSEC2Api.class);
> */
>
> resp.setContentType("text/plain");
> resp.getWriter().println("Hello, world");
> }
> }
> Result is:
> Apr 08, 2015 1:51:29 PM com.google.inject.internal.MessageProcessor visit
> INFO: An exception was caught and reported. Message:
> java.security.AccessControlException: access denied
> ("java.lang.reflect.ReflectPermission"
> "newProxyInPackage.org.jclouds.compute.config")
> java.security.AccessControlException: access denied
> ("java.lang.reflect.ReflectPermission"
> "newProxyInPackage.org.jclouds.compute.config")
> at java.security.AccessControlContext.checkPermission(Unknown Source)
> at java.security.AccessController.checkPermission(Unknown Source)
> at java.lang.SecurityManager.checkPermission(Unknown Source)
> at
> com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkPermission(DevAppServerFactory.java:429)
> at java.lang.reflect.Proxy.checkNewProxyPermission(Unknown Source)
> at java.lang.reflect.Proxy.newProxyInstance(Unknown Source)
> at
> com.google.inject.assistedinject.FactoryProvider2.<init>(FactoryProvider2.java:285)
> at
> com.google.inject.assistedinject.FactoryModuleBuilder$1.configure(FactoryModuleBuilder.java:334)
> at com.google.inject.AbstractModule.configure(AbstractModule.java:59)
> at
> com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:223)
> at com.google.inject.AbstractModule.install(AbstractModule.java:118)
> at
> org.jclouds.compute.config.BaseComputeServiceContextModule.configure(BaseComputeServiceContextModule.java:96)
> at
> org.jclouds.aws.ec2.compute.config.AWSEC2ComputeServiceContextModule.configure(AWSEC2ComputeServiceContextModule.java:78)
> at com.google.inject.AbstractModule.configure(AbstractModule.java:59)
> at
> com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:223)
> at com.google.inject.spi.Elements.getElements(Elements.java:101)
> at
> com.google.inject.internal.InjectorShell$Builder.build(InjectorShell.java:133)
> at
> com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:103)
> at com.google.inject.Guice.createInjector(Guice.java:95)
> at org.jclouds.ContextBuilder.buildInjector(ContextBuilder.java:402)
> at org.jclouds.ContextBuilder.buildInjector(ContextBuilder.java:326)
> at org.jclouds.ContextBuilder.buildView(ContextBuilder.java:608)
> at org.jclouds.ContextBuilder.buildView(ContextBuilder.java:588)
> at
> com.webperformance.bugs.jclouds.Jclouds_app_engine_bugServlet.doGet(Jclouds_app_engine_bugServlet.java:18)
> 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
> com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
> at
> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
> at
> com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:127)
> at
> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
> at
> com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
> at
> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
> at
> com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:63)
> 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
> com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125)
> at
> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
> at
> com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectRequest(DevAppServerModulesFilter.java:366)
> at
> com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectModuleRequest(DevAppServerModulesFilter.java:349)
> at
> com.google.appengine.tools.development.DevAppServerModulesFilter.doFilter(DevAppServerModulesFilter.java:116)
> 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.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:98)
> at
> org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
> at
> com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:491)
> 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 org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:547)
> at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
> at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
> at
> org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
> at
> org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
> Apr 08, 2015 1:51:30 PM com.google.apphosting.utils.jetty.JettyLogger warn
> WARNING: /jclouds_app_engine_bug
> com.google.inject.CreationException: Guice creation errors:
> 1) No implementation for
> org.jclouds.compute.config.BaseComputeServiceContextModule$RunScriptOnNodeFactoryImpl$Factory
> was bound.
> while locating
> org.jclouds.compute.config.BaseComputeServiceContextModule$RunScriptOnNodeFactoryImpl$Factory
> for parameter 0 at
> org.jclouds.compute.config.BaseComputeServiceContextModule$RunScriptOnNodeFactoryImpl.<init>(BaseComputeServiceContextModule.java:144)
> while locating org.jclouds.compute.callables.RunScriptOnNode$Factory
> for parameter 19 at
> org.jclouds.aws.ec2.compute.AWSEC2ComputeService.<init>(AWSEC2ComputeService.java:107)
> at
> org.jclouds.aws.ec2.compute.config.AWSEC2ComputeServiceDependenciesModule.configure(AWSEC2ComputeServiceDependenciesModule.java:89)
> 2) An exception was caught and reported. Message: access denied
> ("java.lang.reflect.ReflectPermission"
> "newProxyInPackage.org.jclouds.compute.config")
> at
> org.jclouds.compute.config.BaseComputeServiceContextModule.configure(BaseComputeServiceContextModule.java:96)
> 2 errors
> at
> com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:435)
> at
> com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:154)
> at
> com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:106)
> at com.google.inject.Guice.createInjector(Guice.java:95)
> at org.jclouds.ContextBuilder.buildInjector(ContextBuilder.java:402)
> at org.jclouds.ContextBuilder.buildInjector(ContextBuilder.java:326)
> at org.jclouds.ContextBuilder.buildView(ContextBuilder.java:608)
> at org.jclouds.ContextBuilder.buildView(ContextBuilder.java:588)
> at
> com.webperformance.bugs.jclouds.Jclouds_app_engine_bugServlet.doGet(Jclouds_app_engine_bugServlet.java:18)
> 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
> com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
> at
> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
> at
> com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:127)
> at
> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
> at
> com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
> at
> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
> at
> com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:63)
> 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
> com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125)
> at
> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
> at
> com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectRequest(DevAppServerModulesFilter.java:366)
> at
> com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectModuleRequest(DevAppServerModulesFilter.java:349)
> at
> com.google.appengine.tools.development.DevAppServerModulesFilter.doFilter(DevAppServerModulesFilter.java:116)
> 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.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:98)
> at
> org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
> at
> com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:491)
> 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 org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:547)
> at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
> at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
> at
> org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
> at
> org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
> Caused by: java.security.AccessControlException: access denied
> ("java.lang.reflect.ReflectPermission"
> "newProxyInPackage.org.jclouds.compute.config")
> at java.security.AccessControlContext.checkPermission(Unknown Source)
> at java.security.AccessController.checkPermission(Unknown Source)
> at java.lang.SecurityManager.checkPermission(Unknown Source)
> at
> com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkPermission(DevAppServerFactory.java:429)
> at java.lang.reflect.Proxy.checkNewProxyPermission(Unknown Source)
> at java.lang.reflect.Proxy.newProxyInstance(Unknown Source)
> at
> com.google.inject.assistedinject.FactoryProvider2.<init>(FactoryProvider2.java:285)
> at
> com.google.inject.assistedinject.FactoryModuleBuilder$1.configure(FactoryModuleBuilder.java:334)
> at com.google.inject.AbstractModule.configure(AbstractModule.java:59)
> at
> com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:223)
> at com.google.inject.AbstractModule.install(AbstractModule.java:118)
> at
> org.jclouds.compute.config.BaseComputeServiceContextModule.configure(BaseComputeServiceContextModule.java:96)
> at
> org.jclouds.aws.ec2.compute.config.AWSEC2ComputeServiceContextModule.configure(AWSEC2ComputeServiceContextModule.java:78)
> at com.google.inject.AbstractModule.configure(AbstractModule.java:59)
> at
> com.google.inject.spi.Elements$RecordingBinder.install(Elements.java:223)
> at com.google.inject.spi.Elements.getElements(Elements.java:101)
> at
> com.google.inject.internal.InjectorShell$Builder.build(InjectorShell.java:133)
> at
> com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:103)
> ... 43 more
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)