2017-09-03 2 views
1

In unserer Clojure Code-Basis haben wir ein Protokoll:lein uberjar kann eine Implementierung nicht in Deftype definiert finden

(ns project.repository) 

(defprotocol Repository 
    (index [this fields unique])) 

Ein Typ

(ns project.mongo (:require 
    [monger.collection :as mc] 
    [monger.core :as mg] 
    [project.repository :refer :all])) 

(deftype MongoRepository [db collection-name] 
    Repository 
    (index [this fields unique] 
    (mc/ensure-index db collection-name fields {:unique unique}))) 

(defn mongo-repository [db coll] (MongoRepository. db coll)) 

(def mongo-db ((mg/connect-via-uri "mongodb://127.0.0.1/bots") :db)) 

Und eine Instantiierung

(ns project.users (:require 
    [lp-bots.storages.repository :refer :all] 
    [lp-bots.storages.mongo :refer [mongo-repository mongo-db]])) 

(def users-storage (mongo-repository mongo-db "users")) 
(index users-storage [:key1 :key2] true) 

Dies funktioniert gut bei interaktiver Verwendung von REPL oder gestartet mit lein run, aber lein uberjar unveränderlich thro ws eine Ausnahme:

Exception in thread "main" java.lang.ExceptionInInitializerError, compiling:(/tmp/form-init118199196859405970.clj:1:72) 
    ... 
Caused by: java.lang.ExceptionInInitializerError 
    ... 
Caused by: java.lang.IllegalArgumentException: No implementation of method: :index of protocol: #'project.repository/Repository found for class: project.mongo.MongoRepository 
    at clojure.core$_cache_protocol_fn.invokeStatic(core_deftype.clj:568) 
    at clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:560) 
    at project.repository$fn__557$G__514__566.invoke(repository.clj) 
    at project.users__init.load(Unknown Source) 
    at project.users__init.<clinit>(Unknown Source) 

Der seltsamste Teil ist, dass das Problem verschwindet, wenn (index) in einem (let) genannt wird:

(def users-storage 
    (let [u (mongo-repository mongo-db "leads")] 
    (index u [:key1 :key2] true) 
    u)) 

Irgendwelche Gedanken auf, was könnte den Unterschied verursachen?

+0

Versuchen Sie AOT-Compilation mit lein uberjar zu tun? –

+0

@akond Ja! Diese Anforderung ging beim Kopieren und Einfügen des Codes in die Frage verloren. Die Frage wurde korrigiert. – 0x60

+0

@minhtuanguyen Das machen wir. Wir haben: aot: all in project.clj und die Ausnahme wird während einer Kompilierung geworfen. – 0x60

Antwort

0

Ich würde vermuten, dass es etwas damit zu tun hat, eine Verbindung zu MongoDB herzustellen, wenn die project.mongo ns oder die project.users ns kompiliert werden. Diese Zeilen sollten wahrscheinlich in einem Funktionsaufruf sein, die beim Start aufgerufen wird, anstatt als der Code geladen wird:

(def mongo-db ((mg/connect-via-uri "mongodb://127.0.0.1/bots") :db)) 

und

(index users-storage [:key1 :key2] true) 
Verwandte Themen