«Помогите Артуру найти его ограниченный класс» или «как я могу сделать Google App engine счастливым»

#java #google-app-engine #clojure #compojure #appengine-magic

#java #google-app-engine #clojure #compojure #appengine-волшебство

Вопрос:

где-то здесь я использую java.rmi.server.UID , что расстраивает GAE. После того, как: только для моих зависимостей до мозга костей, я в тупике.

 (ns helloworld.core
  (:use ;[hiccup.core]
        [hiccup.page-helpers :only (html5 include-css)]
        [clojure.contrib.string :only (split)]
        [compojure.core :only (defroutes GET)]
        [hiccup.middleware :only (wrap-base-url)])
  (:require [appengine-magic.core :as ae]
            [compojure.route :as route
              :only (resources not-found) ]
            [compojure.handler :as handler :only (site)])
  (:gen-class :extends javax.servlet.http.HttpServlet))

 (defn index-page
  ([name]
     (html5
      [:head
       [:title (str "Hello " name)]
       (include-css "/css/style.css")]
      [:body
       [:h1 (str "Hello " name)]]))
  ([] (index-page "World")))

(def match-opperator
  { "add"       
    "subtract" -
    "multiply" *
    "divide"   /})

(defroutes hello-routes
  (GET "/:f/*" [f amp; x]
       (index-page (apply (match-opperator f)
                          (map #(Integer/parseInt %)
                               (split #" " (:* x))))))
  (GET "/" [] (index-page))
  (route/resources "/")
  (route/not-found "Page not found"))

(def app
     (-> (handler/site hello-routes)
         (wrap-base-url)))

(ae/def-appengine-app helloworld-app #'app)
  

Я могу загрузить его в jetty, и он отлично работает,
после загрузки на сервер приложений для разработчиков я получаю это:

HTTP ОШИБКА 500

Проблема с доступом / multiply / 1 2% 204% 208. Причина:

 java.rmi.server.UID - это ограниченный класс. Пожалуйста, ознакомьтесь с руководством разработчика Google App Engine для получения более подробной информации.

Вызвано:

java.lang.Ошибка в NoClassDefFoundError: java.rmi.server.UID - это ограниченный класс. Пожалуйста, ознакомьтесь с руководством разработчика Google App Engine для получения более подробной информации.
 на com.google.appengine.Инструменты.разработка.агент.среда выполнения.Runtime.reject(Времявыполнения.java:51) 
 в org.apache.commons.загрузка файла.диск.DiskFileItem.(DiskFileItem.java: 103)
 на java.lang.Class.forName0 (собственный метод) 
 на java.lang.Class.forName(Class.java:186)
 в ring.middleware.multipart_params$загрузка__4414__auto__.invoke(multipart_params.clj:1)
 в ring.middleware.multipart_params__init.load(неизвестный источник)
 в ring.middleware.multipart_params__init.(Неизвестный источник)
 на java.lang.Class.forName0 (собственный метод) 
 на java.lang.Class.forName(Class.java:264)
 в clojure.lang.RT.loadClassForName(RT.java: 1578)
 в clojure.lang.RT.load(RT.java:399)
 на clojure.lang.RT.load(RT.java:381)
 в clojure.core $load$fn__4519.invoke(core.clj:4915)

ps: вот мой project.clj, если это поможет:

(defproject helloworld "1.0.0-SNAPSHOT"
 :описание "FIXME: написать описание"
 : зависимости [[org.clojure /clojure "1.2.1"]
 [org.clojure /clojure-contrib "1.2.0"]
 [compojure "0.6.2"]
 [ошибка "0.3.4"]]

 :dev-зависимости [[appengine-magic "0.4.1"]
 [swank-clojure "1.2.1"]])

Ответ №1:

FWIW Я не думаю, :only что это что-то изменит для GAE. Вероятно, он следит за тем, какие классы вы загружаете, и отказ refer от функции не останавливает загрузку ее кода.

Не имея опыта работы с конкретным доменом, кроме просмотра stacktrace, я думаю, что обработчик, вызывающий проблему, вероятно, compojure.handler/site , который включает в себя wrap-multipart-params . Я сомневаюсь, что вам нужна эта функция для вашего приложения, поэтому посмотрите, сможете ли вы обойтись compojure.handler/api . Затем, если вам действительно нужны определенные обертки из site , оберните их вручную.

Опять же, учитывая мое предыдущее замечание о загрузке классов, я предполагаю, что код для multipart-params загружается, как только вы require задаете compojure.handler пространство имен, поэтому то, что вы делаете после этого, может не иметь значения. Я полагаю, вам, возможно, даже придется просто выполнить перенос из api и site вручную; это не очень сложно. Тогда вы должны быть в состоянии никогда require не использовать пространство имен multipart-params.

Комментарии:

1. (def app (-> (handler / site hello-routes) (wrap-base-url))) становится просто: (def app (-> hello-routes (wrap-base-url)))