clojupyter / clojupyter

a Jupyter kernel for Clojure
MIT License
835 stars 90 forks source link

How to add dependencies? #29

Closed fasiha closed 7 years ago

fasiha commented 7 years ago

In a stand-alone Clojure project, I’d add dependencies like Specter etc. to a project.clj.

How can I do this with Clojupyter? Is there a “master” dependency file?

pdenno commented 7 years ago

We added pomegranate as a dependency to deal with this. With pomegranate you can dynamically add to the classpath. For example in a clojupyter cell:

(do (use '[cemerick.pomegranate :only (add-dependencies)]) (add-dependencies :coordinates '[[latte "0.4.1-SNAPSHOT"]]) (require '(latte)))

fasiha commented 7 years ago

Super-duper-awesome, thank you!

I scratched my head for a moment wondering how load within-project namespaces, but then realized ns can be run any time and multiple times—so I can define as many modules within my working namespace and switch between them without needing any magic. So excellent!

kovkev commented 6 years ago

Hi!

I have this libGDX project that I built using Gradle. It generated a desktop-1.0.jar file. I can run it using java -jar desktop-1.0.jar, and it starts the game I wrote.

The game uses KryptoNet for networking, and I'd like to use the classes I defined in the game from clojupyter. I'd like to make network calls against the game in order to see how the game responds. I'd like to use the classes inside desktop-1.0.jar from clojupyter.

I followed the first two steps of the following: https://www.pgrs.net/2011/10/30/using-local-jars-with-leiningen/

  1. I have created a maven_repository directory inside my project directory.
  2. mvn install:install-file -Dfile=desktop-1.0.jar -DartifactId=desktop -Dversion=1.0 -DgroupId=desktop -Dpackaging=jar -DlocalRepositoryPath=maven_repository

(Actually, I don't remember what I had for groupId and artifactId. It did not save in my history.)

So far, I tried the following in clojupyter:

(do
(use '[cemerick.pomegranate :only (add-dependencies)])
(add-dependencies :coordinates '[[desktop "1.0"]] :repositories {"desktop" (str     (.toURI     (java.io.File. "maven_repository")))})
(require '(desktop))

for which I get

ArtifactNotFoundException Could not find artifact desktop:desktop:jar:1.0 in desktop (file:/Users/kevin/odev/clojupyter/maven_repository)  org.sonatype.aether.connector.file.FileRepositoryWorker.run (FileRepositoryWorker.java:257)

If I remove :coordinates '[[desktop "1.0"]] , I do not get any errors.

I cannot find documentation on :coordinates in the context of defproject .

In any case, thank you for clojupyter!

kovkev commented 6 years ago

What I have just tried is the following:

➜ ~ mvn install:install-file -Durl=file:repo -DgroupId=local -DartifactId=commons-exec -Dversion=1.1 -Dpackaging=jar -Dfile=/Users/kevin/school/winter2018/comp361/f2017-group13/desktop/build/libs/desktop-1.0.jar

, which successfully out my files into ~/.m2 , (along with many other dependencies like opengl!) :

➜  ~ unzip -l ~/.m2/repository/local/commons-exec/1.1/commons-exec-1.1.jar| grep -E     "(pandemic|opengl\/EXTAbg)"
        0  01-29-2018 19:11   com/pandemic/
        0  01-29-2018 19:11   com/pandemic/game/
        0  01-29-2018 23:24   com/pandemic/game/desktop/
      840  01-29-2018 23:24   com/pandemic/game/desktop/DesktopLauncher.class
     1406  01-29-2018 23:24   com/pandemic/game/PandemicGame.class
      768  01-29-2018 23:24   com/pandemic/game/PandemicNetwork$1.class
      790  01-29-2018 23:24   com/pandemic/game/PandemicNetwork$2.class
      505  01-29-2018 23:24   com/pandemic/game/PandemicNetwork$CharacterConnection.class
      788  01-29-2018 23:24   com/pandemic/game/PandemicNetwork.class
      306  01-29-2018 23:24   com/pandemic/game/WouldBeNiceTest.class
      335  12-28-2014 15:37   org/lwjgl/opengl/EXTAbgr.class
   909414  01-29-2018 18:35   pandemic-board.jpg
    70599  01-29-2018 18:35   pandemic-board-small.jpg
    70599  01-29-2018 18:35   pandemic-board-small copy.jpg
   909414  01-29-2018 18:35   pandemic-board copy.jpg
➜  ~

I am still unsure how to use pomegranate with this. I think I am missing some background knowledge that might not be clearly referenced in the readme.md? Any incantation of using pomegranate, require, import, and/or :import do not work.

kovkev commented 6 years ago

I managed to run add-dependencies successfully!

I used

(do
(use '[cemerick.pomegranate :only (add-dependencies)])
(java.io.File. "maven_repository")))})
(add-dependencies :coordinates '[[local/commons-exec "1.1"]] )
(require '(desktop))
)

Now, it seems like I simply need to import my class. I do not know how to list all the reacheable dependencies to verify that indeed, local/commons-exec has been added by add-dependencies.

After following the info given here: http://blog.bradlucas.com/posts/2017-06-07-importing-java-classes-in-clojure/

I tried

    (import 'com.pandemic.game PandemicGame)

to get

ClassNotFoundException com.pandemic.game  java.net.URLClassLoader.findClass (URLClassLoader.java:381)
kovkev commented 6 years ago

Alright, finally, I was able to import the class using

    (import '(com.pandemic.game WouldBeNiceToTest))

And just to completely close the loop on the idea (I am surprised I could not find anyone else discuss doing this with clojure), one can do the following:

(def foo (WouldBeNiceToTest.))
(.health foo 5) ;; `public int health(int a)` is a function in WouldBeNiceToTest .

This will give you the returned value from the .health method call, but will not show what the method sent to stdout.

ezmiller commented 5 years ago

@kovkev I'm trying to do this as well. Following the thread out, and looking in particular at https://github.com/clojupyter/clojupyter/issues/29#issuecomment-362024168 it looks as though in the end maven wasn't needed?

tye-shutty commented 3 years ago

In case anyone finds this thread from google: https://github.com/aria42/clojupyter/blob/mime-improvements/examples/html-demo.ipynb gives a demo on how to import 3rd party libraries that worked for me.