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

*data-readers* not properly populated #47

Closed
avescodes opened this issue Dec 24, 2014 · 9 comments
Closed

*data-readers* not properly populated #47

avescodes opened this issue Dec 24, 2014 · 9 comments

Comments

@avescodes
Copy link
Contributor

When using boot with Datomic, it seems as if *data-readers* is not being properly populated.

In boot, *data-readers* is empty, even with Datomic included as a dependency:

code/tmp  ▸ boot -d com.datomic/datomic-free repl
nREPL server listening: 0.0.0.0:59655
REPL-y 0.3.5, nREPL 0.2.6
Clojure 1.6.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_20-b26
        Exit: Control+D or (exit) or (quit)
    Commands: (user/help)
        Docs: (doc function-name-here)
              (find-doc "part-of-name-here")
Find by Name: (find-name "part-of-name-here")
      Source: (source function-name-here)
     Javadoc: (javadoc java-object-or-class-here)
    Examples from clojuredocs.org: [clojuredocs or cdoc]
              (user/clojuredocs name-here)
              (user/clojuredocs "ns-here" "name-here")
boot.user=> *data-readers*
{}

Whereas in Leiningen, *data-readers* contains Datomic's db/id et al readers.

code/tmp  ▸ lein try com.datomic/datomic-free
WARNING!!! version ranges found for:
[com.datomic/datomic-free "RELEASE"] -> [com.amazonaws/aws-java-sdk "1.8.11" :exclusions [javax.mail/mail org.apache.httpcomponents/httpclient commons-logging]] -> [com.amazonaws/aws-java-sdk-core "1.8.11"] -> [joda-time "[2.2,)"]
Consider using [com.datomic/datomic-free "0.9.5078" :exclusions [joda-time]].


nREPL server started on port 59665 on host 127.0.0.1 - nrepl://127.0.0.1:59665
REPL-y 0.3.5, nREPL 0.2.6
Clojure 1.6.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_20-b26
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=> *data-readers*
{db/id #'datomic.db/id-literal, db/fn #'datomic.function/construct, base64 #'datomic.codec/base-64-literal}
@avescodes
Copy link
Contributor Author

From @micha's response on Question about data readers with datomic and boot:

The data_readers.clj files that are used to set up the tag readers are only parsed by Clojure during its own bootstrap process. This means that only those data_readers.clj files that are on the classpath when the JVM starts will be parsed. Boot, however, allows you to add things to the classpath dynamically. We're going to add this code to boot in the next release, but the workaround for now is to call a private function from clojure.core that will re-scan the classpath and install any new reader files:

(#'clojure.core/load-data-readers)

Be sure to call this function after any calls to set-env! that pull new dependencies or directories into the classpath.

I'd propose one of two solutions:

  • Document this in boot's already great docs.
  • Modify set-env! to reload data readers when it is done adding dependencies.

@avescodes
Copy link
Contributor Author

That said, adding (#'clojure.core/load-data-readers) after set-env! in my build.boot does not seem to change the value of *data-readers*

@avescodes
Copy link
Contributor Author

Repro case of load-data-readers not persisting:

code/tmp  ▸ boot -d com.datomic/datomic-free repl
nREPL server listening: 0.0.0.0:59826
REPL-y 0.3.5, nREPL 0.2.6
Clojure 1.6.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_20-b26
        Exit: Control+D or (exit) or (quit)
    Commands: (user/help)
        Docs: (doc function-name-here)
              (find-doc "part-of-name-here")
Find by Name: (find-name "part-of-name-here")
      Source: (source function-name-here)
     Javadoc: (javadoc java-object-or-class-here)
    Examples from clojuredocs.org: [clojuredocs or cdoc]
              (user/clojuredocs name-here)
              (user/clojuredocs "ns-here" "name-here")
boot.user=> *data-readers*
{}
boot.user=> (#'clojure.core/load-data-readers)
{base64 #'datomic.codec/base-64-literal, db/fn #'datomic.function/construct, db/id #'datomic.db/id-literal}
boot.user=> *data-readers*
{}
boot.user=> (alter-var-root #'clojure.core/*data-readers* (constantly {:foo :bar}))
{:foo :bar}
boot.user=> *data-readers*
{}

EDIT: It seems as if alter-var-root does not take effect on *data-readers* for some reason...

@avescodes
Copy link
Contributor Author

Derp again, it seems like further down in the aforementioned thread the updated suggestion is to run:

(#'clojure.core/load-data-readers)
(set! *data-readers* (.getRawRoot #'*data-readers*))

Seems convoluted enough to wrap up nicely for end users. (Anyways, I've hope you've enjoyed watching me go through the learning process...)

@martinklepsch
Copy link
Member

Tripped upon this very same thing and got to the same solution. Also via the Hoplon forum.

I tried using the REPLs init option to run a file when the real starts but couldn't get it to work.
Probably that's not the right place place to fix this anyway.

@alandipert
Copy link
Contributor

Closing, but interested parties may consider moving what they found useful from Discourse and this thread to the wiki.

@danielsz
Copy link
Contributor

danielsz commented Dec 6, 2015

Tripped on this, too. The workaround works, but brings complexity to the table, since running the code snippet makes sense in development under boot, but not in production where it's deployed as an artefact.

danielsz added a commit to danielsz/system that referenced this issue Dec 6, 2015
@danielsz
Copy link
Contributor

danielsz commented Dec 6, 2015

This is fixed in system as of 0.2.1-SNAPSHOT.

https://github.com/danielsz/system

For non-system users, you can try injecting the following task in your build pipeline.

(deftask data-readers []
    (fn [next-task]
      (fn [fileset]
        (#'clojure.core/load-data-readers)
        (with-bindings {#'*data-readers* (.getRawRoot #'*data-readers*)}
          (next-task fileset)))))

sagehan pushed a commit to sagehan/miaom-demo that referenced this issue Apr 26, 2016
          which will cause  *data-reader* symbol lose its values!
          I had researched hard and couldn't solved it , so commit it here

          error messages: "No reader function for tag db/id"

          please read those posts:
          boot-clj/boot#47
          http://hoplon.discoursehosting.net/t/question-about-data-readers-with-datomic-and-boot/99
@danielcompton
Copy link

danielcompton commented May 4, 2017

An update on anyone hitting this still, you can call: (boot.core/load-data-readers!) in your build.boot to force this to be loaded. You can see more discussion at https://hoplon.discoursehosting.net/t/question-about-data-readers-with-datomic-and-boot/99/9.

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

No branches or pull requests

6 participants