Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Google App Engine restriction #238

Closed
anceschialberto opened this issue May 3, 2016 · 5 comments
Closed

Google App Engine restriction #238

anceschialberto opened this issue May 3, 2016 · 5 comments

Comments

@anceschialberto
Copy link

anceschialberto commented May 3, 2016

Hello!

I'm trying to run jsprit as a google cloud endpoint API, part of a Maven Java project.

This is the method I invoke:

public static VehicleRoutingProblemSolution getSolution(ArrayList<Coordinate> services, Coordinate depot) {

        /*
         * get a vehicle type-builder and build a type with the typeId "vehicleType" and one capacity dimension, i.e. weight, and capacity dimension value of 5
         */
        final int WEIGHT_INDEX = 0;
        VehicleTypeImpl vehicleType = VehicleTypeImpl.Builder.newInstance("vehicleType").addCapacityDimension(WEIGHT_INDEX, 5).build();
        // specify vehicle1 with open end, i.e. end is determined by the algorithm
        VehicleImpl vehicle1 = VehicleImpl.Builder.newInstance("vehicle1Id")
                .setType(vehicleType)
                .setStartLocation(Location.newInstance(depot.getX(), depot.getY()))
                .setReturnToDepot(false)
                .build();

        /*
         * build services (dove abitano i dipendenti) at the required locations, each with a capacity-demand of 1.
         */
        ArrayList<Service> servArr = new ArrayList<Service>();
        for (int i = 0; i < 30; i++) {
            servArr.add(Service.Builder.newInstance(Integer.toString(i)).addSizeDimension(WEIGHT_INDEX, 1)
                    .setLocation(Location.newInstance(services.get(i).getX(), services.get(i).getY())).build());
        }

        VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
        vrpBuilder.addVehicle(vehicle1);
        vrpBuilder.addAllJobs(servArr);
        VehicleRoutingProblem problem = vrpBuilder.build();

        // define an algorithm out of the box - this creates a large neighborhood search algorithm
        VehicleRoutingAlgorithm algorithm = Jsprit.createAlgorithm(problem);

        /*
         * and search a solution
         */
        Collection<VehicleRoutingProblemSolution> solutions = algorithm.searchSolutions();

        /*
         * get the best
         */
        VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions);

        return bestSolution;
    };

When I run the application I get this error:
java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.sun.reflect"

This is the full stack error:

SEVERE: exception occurred while calling backend method
[INFO] java.lang.ExceptionInInitializerError
[INFO]  at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.<clinit>(ClassLoaderContextSelector.java:59)
[INFO]  at org.apache.logging.log4j.core.impl.Log4jContextFactory.<init>(Log4jContextFactory.java:56)
[INFO]  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[INFO]  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
[INFO]  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
[INFO]  at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
[INFO]  at com.google.appengine.tools.development.agent.runtime.Runtime.newInstance_(Runtime.java:142)
[INFO]  at com.google.appengine.tools.development.agent.runtime.Runtime.newInstance(Runtime.java:163)
[INFO]  at org.apache.logging.log4j.LogManager.<clinit>(LogManager.java:83)
[INFO]  at java.lang.Class.forName0(Native Method)
[INFO]  at java.lang.Class.forName(Class.java:264)
[INFO]  at com.google.appengine.tools.development.agent.runtime.RuntimeHelper.checkRestricted(RuntimeHelper.java:70)
[INFO]  at com.google.appengine.tools.development.agent.runtime.Runtime.checkRestricted(Runtime.java:65)
[INFO]  at jsprit.core.problem.vehicle.VehicleImpl$Builder.<clinit>(VehicleImpl.java:110)
[INFO]  at java.lang.Class.forName0(Native Method)
[INFO]  at java.lang.Class.forName(Class.java:264)
[INFO]  at com.google.appengine.tools.development.agent.runtime.RuntimeHelper.checkRestricted(RuntimeHelper.java:70)
[INFO]  at com.google.appengine.tools.development.agent.runtime.Runtime.checkRestricted(Runtime.java:65)
[INFO]  at com.setproject.hometowork.Solver.getSolution(Solver.java:44)
[INFO]  at com.setproject.hometowork.service.VehicleRouteServiceAPI.getSolution(VehicleRouteServiceAPI.java:53)
[INFO]  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[INFO]  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[INFO]  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[INFO]  at java.lang.reflect.Method.invoke(Method.java:497)
[INFO]  at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:130)
[INFO]  at com.google.api.server.spi.SystemService.invokeServiceMethod(SystemService.java:363)
[INFO]  at com.google.api.server.spi.SystemServiceServlet.execute(SystemServiceServlet.java:113)
[INFO]  at com.google.api.server.spi.SystemServiceServlet.doPost(SystemServiceServlet.java:71)
[INFO]  at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
[INFO]  at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
[INFO]  at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
[INFO]  at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
[INFO]  at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
[INFO]  at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
[INFO]  at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:128)
[INFO]  at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
[INFO]  at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
[INFO]  at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
[INFO]  at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:63)
[INFO]  at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
[INFO]  at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:50)
[INFO]  at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
[INFO]  at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125)
[INFO]  at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
[INFO]  at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectRequest(DevAppServerModulesFilter.java:366)
[INFO]  at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectModuleRequest(DevAppServerModulesFilter.java:349)
[INFO]  at com.google.appengine.tools.development.DevAppServerModulesFilter.doFilter(DevAppServerModulesFilter.java:116)
[INFO]  at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
[INFO]  at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
[INFO]  at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
[INFO]  at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
[INFO]  at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
[INFO]  at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
[INFO]  at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:98)
[INFO]  at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
[INFO]  at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:513)
[INFO]  at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
[INFO]  at org.mortbay.jetty.Server.handle(Server.java:326)
[INFO]  at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
[INFO]  at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938)
[INFO]  at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)
[INFO]  at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
[INFO]  at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
[INFO]  at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
[INFO]  at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
[INFO] Caused by: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.sun.reflect")
[INFO]  at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
[INFO]  at java.security.AccessController.checkPermission(AccessController.java:884)
[INFO]  at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
[INFO]  at com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkPermission(DevAppServerFactory.java:429)
[INFO]  at java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1564)
[INFO]  at java.lang.Class.checkPackageAccess(Class.java:2372)
[INFO]  at java.lang.Class.checkMemberAccess(Class.java:2351)
[INFO]  at java.lang.Class.getMethods(Class.java:1614)
[INFO]  at org.apache.logging.log4j.core.impl.ReflectiveCallerClassUtility.<clinit>(ReflectiveCallerClassUtility.java:79)
[INFO]  ... 65 more

This is my pom.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>

    <groupId>com.setproject.hometowork</groupId>
    <artifactId>hometowork</artifactId>

    <properties>
        <app.id>set-core</app.id>
        <app.version>2</app.version>
        <appengine.version>1.9.34</appengine.version>
        <gcloud.plugin.version>2.0.9.74.v20150814</gcloud.plugin.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.showDeprecation>true</maven.compiler.showDeprecation>
    </properties>

    <prerequisites>
        <maven>3.1.0</maven>
    </prerequisites>

    <dependencies>
        <!-- Compile/runtime dependencies -->
        <dependency>
            <groupId>com.google.appengine</groupId>
            <artifactId>appengine-api-1.0-sdk</artifactId>
            <version>${appengine.version}</version>
        </dependency>
        <dependency>
            <groupId>com.google.appengine</groupId>
            <artifactId>appengine-endpoints</artifactId>
            <version>${appengine.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>
        <dependency>
            <groupId>jsprit</groupId>
            <artifactId>jsprit-core</artifactId>
            <version>1.6.2</version>
        </dependency>
        <dependency>
            <groupId>jsprit</groupId>
            <artifactId>jsprit-analysis</artifactId>
            <version>1.6.2</version>
        </dependency>
        <dependency>
            <groupId>jsprit</groupId>
            <artifactId>jsprit-instances</artifactId>
            <version>1.6.2</version>
        </dependency>
        <dependency>
            <groupId>com.google.maps</groupId>
            <artifactId>google-maps-services</artifactId>
            <version>0.1.12</version>
        </dependency>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20140107</version>
        </dependency>
        <dependency>
            <groupId>com.google.appengine.tools</groupId>
            <artifactId>appengine-gcs-client</artifactId>
            <version>RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.google.apis</groupId>
            <artifactId>google-api-services-storage</artifactId>
            <version>v1-rev71-1.21.0</version>
        </dependency>

        <!-- Test Dependencies -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-all</artifactId>
            <version>2.0.2-beta</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.google.appengine</groupId>
            <artifactId>appengine-testing</artifactId>
            <version>${appengine.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.google.appengine</groupId>
            <artifactId>appengine-api-stubs</artifactId>
            <version>${appengine.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <repositories> <!-- add this, if you don't have any repository definitions yet -->
        <repository>
            <id>jsprit-releases</id>
            <url>https://github.com/jsprit/mvn-rep/raw/master/releases</url>
        </repository>
    </repositories> <!-- add this, if you don't have any repository definitions yet -->

    <build>
        <!-- for hot reload of the web application-->
        <outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>versions-maven-plugin</artifactId>
                <version>2.1</version>
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>display-dependency-updates</goal>
                            <goal>display-plugin-updates</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <version>3.1</version>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <webXml>${project.build.directory}/generated-sources/appengine-endpoints/WEB-INF/web.xml</webXml>
                    <webResources>
                        <resource>
                            <!-- this is relative to the pom.xml directory -->
                            <directory>${project.build.directory}/generated-sources/appengine-endpoints</directory>
                            <!-- the list has a default value of ** -->
                            <includes>
                                <include>WEB-INF/*.discovery</include>
                                <include>WEB-INF/*.api</include>
                            </includes>
                        </resource>
                    </webResources>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.google.appengine</groupId>
                <artifactId>appengine-maven-plugin</artifactId>
                <version>${appengine.version}</version>
                <configuration>
                    <enableJarClasses>false</enableJarClasses>
                    <appId>${app.id}</appId>
                    <version>${app.version}</version>
                    <!-- Comment in the below snippet to bind to all IPs instead of just localhost -->
                    <!-- address>0.0.0.0</address>
                    <port>8080</port -->
                    <!-- Comment in the below snippet to enable local debugging with a remote debugger
                         like those included with Eclipse or IntelliJ -->
                    <!-- jvmFlags>
                      <jvmFlag>-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n</jvmFlag>
                    </jvmFlags -->
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>endpoints_get_discovery_doc</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
              <groupId>com.google.appengine</groupId>
              <artifactId>gcloud-maven-plugin</artifactId>
              <version>${gcloud.plugin.version}</version>
              <configuration>
                <set_default>true</set_default>
              </configuration>
            </plugin>
        </plugins>
    </build>

</project>

I think jsprit uses some library that's not in the Google App Engine white list ("accessClassInPackage.sun.reflect"). Is it possible a workaround for this issue?

Thanks a lot

@oblonski
Copy link
Member

oblonski commented May 5, 2016

Seems that it has problems to create the logger: https://github.com/graphhopper/jsprit/blob/master/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/vehicle/VehicleImpl.java#L110. It might be related to this: #185? Dont know for sure ...

@anceschialberto
Copy link
Author

anceschialberto commented May 8, 2016

Thank you so much! I've managed to migrate to slf4j and bind to java.util.logger.
I've also forked your mvn-rep and point my custom jsprit 1.6.4-SNAPSHOT pom.xml to it.
Now I have to deploy my custom jsprit to my forked repository, and I've tried to execute some commands to build and deploy it:

Albertos-MBP:jsprit albertoanceschi$ mvn deploy [INFO] Scanning for projects... [INFO] ------------------------------------------------------------------------ [INFO] Reactor Build Order: [INFO] [INFO] jsprit [INFO] jsprit-core [INFO] jsprit-analysis [INFO] jsprit-instances [INFO] jsprit-examples [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building jsprit 1.6.4-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-enforcer-plugin:1.1.1:enforce (enforce-versions) @ jsprit --- [INFO] [INFO] >>> maven-source-plugin:2.2.1:jar (attach-sources) > generate-sources @ jsprit >>> [INFO] [INFO] --- maven-enforcer-plugin:1.1.1:enforce (enforce-versions) @ jsprit --- [INFO] [INFO] <<< maven-source-plugin:2.2.1:jar (attach-sources) < generate-sources @ jsprit <<< [INFO] [INFO] --- maven-source-plugin:2.2.1:jar (attach-sources) @ jsprit --- [INFO] [INFO] --- maven-javadoc-plugin:2.9.1:jar (attach-javadocs) @ jsprit --- [INFO] Not executing Javadoc as the project is not a Java classpath-capable package [INFO] [INFO] --- maven-install-plugin:2.4:install (default-install) @ jsprit --- [INFO] Installing /Users/albertoanceschi/IdeaProjects/jsprit/pom.xml to /Users/albertoanceschi/.m2/repository/jsprit/jsprit/1.6.4-SNAPSHOT/jsprit-1.6.4-SNAPSHOT.pom [INFO] [INFO] --- maven-deploy-plugin:2.7:deploy (default-deploy) @ jsprit --- Downloading: https://github.com/anceschialberto/mvn-rep/raw/master/snapshots/jsprit/jsprit/1.6.4-SNAPSHOT/maven-metadata.xml Uploading: https://github.com/anceschialberto/mvn-rep/raw/master/snapshots/jsprit/jsprit/1.6.4-SNAPSHOT/jsprit-1.6.4-20160508.165459-1.pom [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary: [INFO] [INFO] jsprit ............................................. FAILURE [ 3.167 s] [INFO] jsprit-core ........................................ SKIPPED [INFO] jsprit-analysis .................................... SKIPPED [INFO] jsprit-instances ................................... SKIPPED [INFO] jsprit-examples .................................... SKIPPED [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3.334 s [INFO] Finished at: 2016-05-08T18:55:00+02:00 [INFO] Final Memory: 18M/177M [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy (default-deploy) on project jsprit: Failed to deploy artifacts: Could not find artifact jsprit:jsprit:pom:1.6.4-20160508.165459-1 in jsprit-snapshots (https://github.com/anceschialberto/mvn-rep/raw/master/snapshots) -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

Could you please tell me which mvn commands should be executed in order to respect the right build life cycle? Thank you.

@oblonski
Copy link
Member

oblonski commented May 8, 2016

do mvn clean install on your fork

@anceschialberto
Copy link
Author

Great, thank you so much @oblonski ! 👍

If anyone is interested, I've forked jsprit 1.6.4-SNAPSHOT and customized it.
I've migrated from log4j to slf4j 1.7.21, so for example it can be binded to use java.util.Logger and executed on Google App Engine!

https://github.com/anceschialberto/jsprit

@karussell
Copy link
Member

I've migrated from log4j to slf4j 1.7.21

Are you sure that this is not possible with log4j? E.g. this questions indicates it works. Maybe just reflections are not allowed on the app engine? Will calling something like LoggerFactory.getLogger(getClass()) help?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants