puniverse / pulsar

Fibers, Channels and Actors for Clojure
http://docs.paralleluniverse.co/pulsar/
Other
911 stars 53 forks source link

Adding pulsar dep breaks refactor-nrepl plugin #43

Open jjcomer opened 9 years ago

jjcomer commented 9 years ago

When I add pulsar as a dependency (with quasar), the refactor-nrepl plugin is prevented from loading. If I remove pulsar, the plugin starts working again. The cider-nrepl plugin does not have this issue. Not sure where this defect lies, if it is in the plugin or in plusar.

circlespainter commented 9 years ago

I don't know much about refactor-nrepl but I tried adding the Leiningen plugin to a basically empty project with no deps (specifically no Quasar/Pulsar and no agents) and when I run lein repl I get the following:

Error loading refactor-nrepl.middleware: java.io.FileNotFoundException: Could not locate cider/nrepl/middleware/util/misc__init.class or cider/nrepl/middleware/util/misc.clj on classpath: , compiling:(refactor_nrepl/middleware.clj:1:1)
Exception in thread "main" java.lang.RuntimeException: Unable to resolve var: refactor-nrepl.middleware/wrap-refactor in this context, compiling:(/tmp/form-init5440298671210986450.clj:1:1477)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6651)
    at clojure.lang.Compiler.analyze(Compiler.java:6445)
    at clojure.lang.Compiler.analyze(Compiler.java:6406)
    at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6646)
    at clojure.lang.Compiler.analyze(Compiler.java:6445)
    at clojure.lang.Compiler.analyze(Compiler.java:6406)
    at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6646)
    at clojure.lang.Compiler.analyze(Compiler.java:6445)
    at clojure.lang.Compiler.access$100(Compiler.java:38)
    at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6050)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6644)
    at clojure.lang.Compiler.analyze(Compiler.java:6445)
    at clojure.lang.Compiler.analyze(Compiler.java:6406)
    at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782)
    at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5217)
    at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3846)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6642)
    at clojure.lang.Compiler.analyze(Compiler.java:6445)
    at clojure.lang.Compiler.eval(Compiler.java:6700)
    at clojure.lang.Compiler.eval(Compiler.java:6693)
    at clojure.lang.Compiler.eval(Compiler.java:6693)
    at clojure.lang.Compiler.load(Compiler.java:7130)
    at clojure.lang.Compiler.loadFile(Compiler.java:7086)
    at clojure.main$load_script.invoke(main.clj:274)
    at clojure.main$init_opt.invoke(main.clj:279)
    at clojure.main$initialize.invoke(main.clj:307)
    at clojure.main$null_opt.invoke(main.clj:342)
    at clojure.main$main.doInvoke(main.clj:420)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at clojure.lang.Var.invoke(Var.java:383)
    at clojure.lang.AFn.applyToHelper(AFn.java:156)
    at clojure.lang.Var.applyTo(Var.java:700)
    at clojure.main.main(main.java:37)
Caused by: java.lang.RuntimeException: Unable to resolve var: refactor-nrepl.middleware/wrap-refactor in this context
    at clojure.lang.Util.runtimeException(Util.java:221)
    at clojure.lang.Compiler$TheVarExpr$Parser.parse(Compiler.java:659)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6644)
    ... 34 more
REPL server launch timed out.

This is the project file (project generated with lein new <name>):

(defproject basic "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.6.0"]]
  :plugins [[refactor-nrepl "1.1.0"]])

Is that the issue you're running into? Else what's the trace/log, if any? How do you know the plugin is prevented from loading? If you can share a testable reproduction of the issue it can greatly help.

jjcomer commented 9 years ago

This works with lein repl:

(defproject dep-test "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.7.0"]]
  :plugins [[refactor-nrepl "1.1.0"]])

This one breaks with the above error you quote.

(defproject dep-test "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.7.0"]
                 [co.paralleluniverse/pulsar "0.7.2"]]
  :java-agents [[co.paralleluniverse/quasar-core "0.7.2"]]
  :plugins [[refactor-nrepl "1.1.0"]])

And to be thorough :wink: this one works too:

(defproject dep-test "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.7.0"]
                 [co.paralleluniverse/pulsar "0.7.2"]]
  :java-agents [[co.paralleluniverse/quasar-core "0.7.2"]])
jjcomer commented 9 years ago

Also interesting is that both of these work:

(defproject dep-test "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.7.0"]]
  :java-agents [[co.paralleluniverse/quasar-core "0.7.2"]]
  :plugins [[refactor-nrepl "1.1.0"]])
(defproject dep-test "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.7.0"]
                 [co.paralleluniverse/pulsar "0.7.2"]]
  :plugins [[refactor-nrepl "1.1.0"]])
circlespainter commented 9 years ago

Here (Linux Mint 17.2 Rafaela, Oracle JDK 1.8.0_60-b27 64-bit on MBP late 2008) this too breaks with the above error:

(defproject dep-test "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.7.0"]]
  :plugins [[refactor-nrepl "1.1.0"]])
jjcomer commented 9 years ago

I'm running Ubuntu 15.04 -- Leiningen 2.5.2 on Java 1.8.0_60 Java HotSpot(TM) 64-Bit Server VM

Also tried wiping out the my user profile. Turns out you need cider-nrepl too.

Here is the base then:

(defproject dep-test "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.7.0"]]
  :plugins [[refactor-nrepl "1.1.0"]
            [cider/cider-nrepl "0.9.1"]])
circlespainter commented 9 years ago

Adding :bootclasspath true (which tells Leiningen to add the agent JAR to the boot class path as well) seems to solve the issue, although it's not completely clear why to me; I just don't know enough about those plugins' architecture (or leiningen's plugins classloading architecture for that matter).

This relates to classloading hierarchies anyway, for example quasar-core needs be added to the boot class path as well when instrumenting JDK parts; this is because it adds reference to some Quasar runtime classes during instrumentation (which must be loadable by the JDK classloader afterwards).

Does this work for you?

beppu commented 9 years ago

@circlespainter Adding :bootclasspath true makes the refactor-nrepl error go away, but then the pulsar code stops working.

I started with https://github.com/yogthos/pulsar-example and edited its project.clj to look like:

(defproject pulsar-example "0.1.0-SNAPSHOT"
  :description "a sample project using Pulsar"
  :url "https://github.com/yogthos/pulsar-example"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.7.0"]
                 [co.paralleluniverse/pulsar "0.7.3"]
                 [co.paralleluniverse/quasar-core "0.7.3"]]

  :plugins [[refactor-nrepl "1.1.0"]
            [cider/cider-nrepl "0.9.1"]]

  :bootclasspath true

  :manifest {"Premain-Class" "co.paralleluniverse.fibers.instrument.JavaAgent"
             "Agent-Class" "co.paralleluniverse.fibers.instrument.JavaAgent"
             "Can-Retransform-Classes" "true"
             "Can-Redefine-Classes" "true"}

  :java-agents [[co.paralleluniverse/quasar-core "0.7.3"]]

  :main pulsar-example.core
  :uberjar-name "pulsar-example.jar"
  :aot [pulsar-example.core])

The REPL loaded just fine, but when I tried to run (-main), it threw a NullPointerException.

1. Unhandled java.lang.NullPointerException
   (No message)

              ActorLoader.java:  368  co.paralleluniverse.actors.ActorLoader/loadCurrentClass
              ActorLoader.java:  392  co.paralleluniverse.actors.ActorLoader/getCurrentClassFor
              ActorLoader.java:  379  co.paralleluniverse.actors.ActorLoader/getReplacementFor0
              ActorLoader.java:  117  co.paralleluniverse.actors.ActorLoader/getReplacementFor
                    Actor.java:  135  co.paralleluniverse.actors.Actor/checkReplacement
                    Actor.java:  235  co.paralleluniverse.actors.Actor/spawn
                    Actor.java:  203  co.paralleluniverse.actors.Actor/spawn
                      core.clj:   29  pulsar-example.core/-main
                          REPL:    1  pulsar-example.core/eval15500
beppu commented 9 years ago

A Workaround

Normally, I have the refactor-nrepl and cider-nrepl plugins setup in my ~/.lein/profiles.clj.

To remove refactor-nrepl, I create a project-specific profiles.clj in the root of the project that overrides :plugins:

{:user {:plugins ^:replace [[lein-pprint "1.1.1"]
                            [cider/cider-nrepl "0.9.1"]]}}

Notice that it doesn't include refactor-nrepl. I can live without that plugin, and at least I have a working REPL with pulsar again.

circlespainter commented 9 years ago

@beppu Thanks for posting a workaround. I'll be looking further into this issue.

stig commented 8 years ago

Same issue for me with pulsar 0.7.3. @beppu 's work-around works. (I too specify refactor-nrepl in ~/.lein/profiles.clj`.)

expez commented 8 years ago

@circlespainter the problem you encountered in the second post of this thread is caused by your not specifying a cider-nrepl version in your profiles.clj. We assume that dependency is :provided, because our plugin works on all versions of that middleware and we didn't want to pollute the classpath unnecessarily by specifying some specific version (and risk overriding the user's preference) when we don't have to.

expez commented 8 years ago

Here are a few other threads discussing this same issue:

https://github.com/puniverse/pulsar/issues/20 https://github.com/clojure-emacs/refactor-nrepl/issues/107

circlespainter commented 8 years ago

@expez Thanks, it doesn't look like the instrumentation errors in https://github.com/clojure-emacs/refactor-nrepl/issues/107 are the source of the issue because when not using auto-instrumentation I can see no errors in the full instrumentation logs (they can be obtained by adding :options "vdc" to the agent entry).

Some tricky interaction with mranderson is possible but it sounds strange that it only happens with refactor-nrepl and not with cider-nrepl.

This definitely requires some more investigation.

malchmih commented 8 years ago

@circlespainter Thanks for your investigation! I would really love to have this solved, since cider-nrepl + refactor-nrepl is my main programming environment.

greboide commented 7 years ago

does someone has a solution to this, im falling in the same error? also i wasnt able to remove refactor-nrepl as suggested because it is being called by emacs and i dont know how to prevent it from calling automatically, even though it isnt listed in my project.clj file. Any help is appreciated...

expez commented 7 years ago

@greboide to get rid of refactor-nrepl do (setq cljr-inject-dependencies-at-jack-in nil) in your .emacs

clj-refactor is injecting its own middleware. Without it quite a few refactorings won't work anymore.

greboide commented 7 years ago

nice, thank you @expez im such a noobie with clojure, i dont think im going to refactor just now, anyway it works like a charm without it!