Fork me on GitHub
#boot
<
2016-01-10
>
msattel01:01:44

After updating boot I get the following exception: Multiple jar entries match : .*/pom.xml Anybody has an idea what could cause that exception.

micha01:01:18

@msattel: can you paste a full stacktrace please?

micha01:01:33

you shouldn't be seeing that

micha01:01:11

you can use the -vv option to boot itself to get full stacktraces

micha01:01:17

with no ansi colors

msattel01:01:17

Released [email protected][Permits = 1]... Installing project.jar... clojure.lang.ExceptionInfo: java.lang.Exception: Multiple jar entries match: .*/pom.xml {:file "/tmp/boot.user209501624813010180.clj", :line 49} at clojure.core$ex_info.invoke(core.clj:4593) at boot.main$main$fn_1272.invoke(main.clj:199) at boot.main$_main.invoke(main.clj:192) at clojure.lang.Var.invoke(Var.java:394) at org.projectodd.shimdandy.impl.ClojureRuntimeShimImpl.invoke(ClojureRuntimeShimImpl.java:159) at org.projectodd.shimdandy.impl.ClojureRuntimeShimImpl.invoke(ClojureRuntimeShimImpl.java:150) at boot.App.runBoot(App.java:390) at boot.App.main(App.java:467) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at boot.Loader.main(Loader.java:253) Caused by: java.util.concurrent.ExecutionException: java.lang.Exception: Multiple jar entries match: .*/pom.xml at java.util.concurrent.FutureTask.report(FutureTask.java:122) at java.util.concurrent.FutureTask.get(FutureTask.java:192) at clojure.core$deref_future.invoke(core.clj:2186) at clojure.core$future_call$reify__6736.deref(core.clj:6683) at clojure.core$deref.invoke(core.clj:2206) at boot.core$boot.doInvoke(core.clj:801) at clojure.lang.RestFn.invoke(RestFn.java:408) at boot.user$eval489.invoke(boot.user209501624813010180.clj:56) at clojure.lang.Compiler.eval(Compiler.java:6782) at clojure.lang.Compiler.load(Compiler.java:7227) at clojure.lang.Compiler.loadFile(Compiler.java:7165) at clojure.lang.RT$3.invoke(RT.java:319) at boot.main$main$fn_1272.invoke(main.clj:192) ... 11 more Caused by: java.lang.Exception: Multiple jar entries match: .*/pom.xml at boot.pod$find_in_jarfile.invoke(pod.clj:120) at boot.pod$pom_xml.invoke(pod.clj:190) at boot.aether$install.invoke(aether.clj:178) at clojure.lang.Var.invoke(Var.java:388) at clojure.lang.AFn.applyToHelper(AFn.java:160) at clojure.lang.Var.applyTo(Var.java:700) at clojure.core$apply.invoke(core.clj:630) at boot.pod$eval_fn_call.invoke(pod.clj:294) at boot.pod$call_in_STAR_.invoke(pod.clj:315) at clojure.lang.Var.invoke(Var.java:379) at org.projectodd.shimdandy.impl.ClojureRuntimeShimImpl.invoke(ClojureRuntimeShimImpl.java:109) at org.projectodd.shimdandy.impl.ClojureRuntimeShimImpl.invoke(ClojureRuntimeShimImpl.java:102) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:93) at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:28) at boot.pod$call_in_STAR_.invoke(pod.clj:318) at boot.task.built_in$fn__2203$fn__2204$fn__2210$fn__2211.invoke(built_in.clj:725) at boot.task.built_in$fn__2078$fn__2079$fn__2085$fn__2086.invoke(built_in.clj:618) at boot.task.built_in$fn__1903$fn__1904$fn__1914$fn__1915.invoke(built_in.clj:495) at boot.task.built_in$fn__1761$fn__1762$fn__1771$fn__1772.invoke(built_in.clj:342) at boot.task.built_in$fn__1594$fn__1595$fn__1601$fn__1602.invoke(built_in.clj:221) at boot.task.built_in$fn__1997$fn__1998$fn__2006$fn__2007.invoke(built_in.clj:555) at boot.core$run_tasks.invoke(core.clj:794) at boot.core$boot$fn__904.invoke(core.clj:804) at clojure.core$binding_conveyor_fn$fn__4444.invoke(core.clj:1916) at clojure.lang.AFn.call(AFn.java:18) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)

micha01:01:39

ah you're installing a jar that contains more than one pom.xml file

micha01:01:01

boot looks in the jar to find the pom.xml

micha01:01:42

the install task takes a --pom option

micha01:01:58

you can provide the path to the pom in the jar

micha01:01:02

the resource path

micha01:01:21

usually when you deploy a jar you won't want to have multiple pom.xmls in there

msattel01:01:25

so isn't that a problem with my pom task???

msattel01:01:49

and thanks for your advice, I will test it

micha01:01:50

are you making an uberjar?

micha01:01:06

maybe if you paste your build.boot

micha01:01:16

something will stand out

micha01:01:01

if you could paste it into a snippet in slack it will be easier to read simple_smile

msattel01:01:48

(task-options! pom { :project 'wareblog :version version } target { :dir '#{"target"} :no-clean false } aot {:namespace '#{wareblog.embedded}} jar { :manifest {"description" "test clojure and boot"} :main 'wareblog.embedded }) (deftask build "Building the project" [] (comp (aot) (target) (pom) (uber) (jar) (install)))

msattel01:01:31

and this is my env:

msattel01:01:36

(set-env! :source-paths #{"src/main/clj","src/test/clj","src/main/resources"} :resource-paths #{"src/main/resources","src/test/resources"} :dependencies '[ [adzerk/boot-test "1.0.4"] [adzerk/boot-cljs "0.0-2814-4"] [org.clojure/clojure "1.7.0-RC1"] [environ "1.0.0"] [ring/ring-core "1.3.2"] [http-kit "2.1.18"] [bidi "1.18.11"] [liberator "0.12.2"] [com.taoensso/timbre "3.4.0"];logging [selmer "0.8.2"];templates [com.stuartsierra/component "0.2.3"] ])

micha01:01:13

so if you do boot pom show -f do you see more than one pom.xml file?

micha01:01:41

you are making an uberjar

micha01:01:59

so you will need to specify the path to your pom in the task-options

msattel01:01:32

I see one pom.xml file

micha01:01:00

(task-options!
  install {:pom "META-INF/maven.wareblog/pom.xml"})

micha01:01:03

or something like that

micha01:01:20

but installing/deploying uberjars is pretty unusual

micha01:01:37

why are you making an uberjar there?

micha01:01:47

if you're using maven you can just declare dependencies, no?

micha01:01:36

deploying an uberjar will defeat the whole dependency system

micha01:01:46

and you will end up with conflicts

micha01:01:53

that you can't see or debug

micha01:01:12

uberjars are for applications, which you don't need to install in maven

micha01:01:18

you just run them

micha01:01:00

but if you really do want to deploy an uberjar to a maven repo you can just specify which pom you want to install/deploy with

msattel01:01:44

thanks a lot for that explanation, I will test

msattel01:01:55

I just thought it might be a good idea to install a uberjar, because I wanted to package the application in a single jar file. What is the best way to package an app with all its dependencies in your opinion?

micha01:01:19

uberjar is perfect for that

micha01:01:34

but why do you want to install it in you maven repository though?

micha01:01:43

i.e., the install task

micha01:01:03

you just want a jar that you can run via java -jar ... right?

micha01:01:24

yeah you can just remove the install task from your build there

micha01:01:55

and put the target task after the jar task so the jar file is written to the target dir

micha01:01:11

the output of one task becomes the input to the next

micha01:01:31

so you want to feed the jar file produced by the jar task to the target task

micha01:01:33

if that makes sense

micha01:01:25

if you want just the jar file in the target dir you can add this in between the jar and target tasks:

micha01:01:18

(comp
  ...
  (jar)
  (sift :include #{#"\.jar$"})
  (target))

micha01:01:28

where ... is your other tasks you already have there

micha01:01:48

then you'll have a target directory with just the single jar in it

msattel01:01:49

very nice, actually where is that documented?

micha01:01:51

you can do boot -h to see a list of all tasks

micha01:01:58

or in the repl (boot (help))

micha01:01:11

and for documentation for a specific task you can do

micha01:01:20

boot sift --help for example

micha01:01:27

or in the repl (doc sift)

msattel01:01:40

ok thank you

micha01:01:41

also there are API docs on github

micha01:01:56

for example

msattel01:01:25

and final question

msattel01:01:29

Implicit target dir is deprecated, please use the target task instead. Set BOOT_EMIT_TARGET=no to disable implicit target dir.

msattel01:01:50

just wondering why it tells me to use the taget task, because actually I am using it

micha01:01:59

you can set that in your shell environment like export BOOT_EMIT_TARGET=no

micha01:01:07

or in your ~/.boo/boot.properties file

micha01:01:29

this is because boot didn't have a target task until recently

micha01:01:44

the default behavior was to write to the target directory automatically

micha01:01:56

but we found that this wasn't so useful

msattel01:01:11

awesome, thank you for the help

micha01:01:14

because most of the time you're either working in the classpath, like when you're testing

micha01:01:29

or you want to emit the target stuff to somewhere in the cloud

micha01:01:41

emitting files to the local filesystem for each iteration was a waste

micha01:01:07

so the BOOT_EMIT_TARGET env var is for compatibility

micha01:01:24

by default boot will continue doing what it did before

micha01:01:44

it's a feature flag basically

msattel01:01:39

I like having an explicit target directory, as in most cases I prefer explicit definition over implicit magic.

msattel01:01:23

Nice work, I am really excited to find out more about boot, have to leave now, thank you for your support.

micha01:01:10

have fun! come back if you run into issues simple_smile

richiardiandrea17:01:27

^ this is so cool!

martinklepsch17:01:52

@richiardiandrea: what? zerobitcoin?

richiardiandrea17:01:20

By the way I didn't forget your confetti but the boot porting of my project is going to happen soon πŸ˜‰

martinklepsch17:01:50

@richiardiandrea: no worries simple_smile

richiardiandrea17:01:16

Actually I thought zerobitcoin was new bitcoins project, but well, dunno

flyboarder19:01:24

is anyone else having issues with boot 2.6-SNAPSHOT not finding some project files?

micha19:01:35

@flyboarder: what kind of issues?

flyboarder19:01:08

just that some files in my src/ folder are not picked up, it worked fine with 2.5.5

micha19:01:28

can you make an example?

flyboarder19:01:05

possibly, im not sure what the difference between the files that are picked up and the ones which are not

flyboarder19:01:34

ill see if i can reproduce on a smaller repo

micha19:01:56

what do you mean by "picked up"

micha19:01:02

like they don't ever make it into the fileset?

micha19:01:17

do youhave a .bootignore file?

micha19:01:40

ok just checking lol

micha19:01:50

is your monitor plugged in?

flyboarder19:01:03

hahah πŸ˜› yeah it’s weird

micha19:01:35

i will deploy a new snapshot, it's possible that one is not 100% up to date

flyboarder20:01:28

@micha: i figured it out, once it hits a folder in src/ in this case src/state no letters after s in my src/ folder is seen

micha20:01:29

ok new snapshot available

flyboarder20:01:09

@micha: looks like it isnt recursively going through src/

flyboarder20:01:29

im working on a demo

flyboarder20:01:33

@micha: I pushed a change and removed all the useless code

martinklepsch20:01:17

@juhoteperi: ^ now people cant easily copy the clojars coordinates anymore

juhoteperi21:01:51

I know... but I hate that each time I do release I forget to run build-jar and then I can't do a release because it updates the readme just before push and then push fails because repo is not clean

juhoteperi21:01:52

It's not possible to use javascript links in github, but it would probably be possible to link to a page which would copy the coordinate upon page load

richiardiandrea21:01:02

Guys just a theoretical question, why do I need :scope "test" when declaring a dependency in boot? Is it the same meaning as in maven?

micha21:01:26

@richiardiandrea: yes, it prevents that dependency from being included as a transitive dependency of a project that depends on your project

juhoteperi21:01:50

Also prevents the dependency being included in uberjar

micha21:01:33

it'll stil be in the generated pom.xml of course

mathiasx21:01:30

hey micha, alandipert, are you guys still interested in using something like boot-sassc with JRuby + Sass (for Compass) or did you guys end up rolling your own solution? https://github.com/mathias/boot-sassc/issues/12#issuecomment-132851213

richiardiandrea21:01:46

in tenzing I see that it requires for instance boot-reload at the beginning of build.boot but can't I do it just in the development task (that is where I need it) ?

micha21:01:56

@mathiasx: we're using boot-sassc currently with libsass

micha21:01:14

@richiardiandrea: yes you can

mathiasx21:01:30

@micha: OK to PM so I don’t clutter up the channel? lol

micha21:01:26

@richiardiandrea: the benefit of adding the test dependency is that you can resolve all your deps at once

micha21:01:38

which reduces the possiblity of dependency conflicts

micha21:01:50

like maven was really not designed for dynamically adding dependencies

micha21:01:00

because of the way it internally resolves dependency conflicts

richiardiandrea21:01:12

@micha thanks, I feel that after setting the options in development I could call the big require, or maybe split set-dev! where I just set deps and development where I actually require and do stuff...

richiardiandrea21:01:23

@micha: great thanks for expanding on this

micha21:01:54

like if the dependency you add dynamically has transitive dependencies that conflict with ones already loaded

micha21:01:16

if you did them all at once aether would resolve those dependencies differently

micha21:01:22

because it can see the whole graph

richiardiandrea21:01:28

ah wow did not know that

richiardiandrea21:01:34

make sense though

juhoteperi21:01:20

Also, without top level require you can't refer to required vars directly but would need to use resolve to resolve symbols to vars in runtime

richiardiandrea21:01:07

so I can't do

(deftask run []
  (require
   '[adzerk.boot-cljs      :refer [cljs]]
   '[adzerk.boot-cljs-repl :refer [cljs-repl start-repl]]
   '[adzerk.boot-reload    :refer [reload]]
   '[pandeiro.boot-http    :refer [serve]]
   '[crisptrutski.boot-cljs-test :refer [test-cljs]])
  (comp (serve)
        (watch)
        (cljs-repl)
        (reload)
        (build)))

juhoteperi21:01:02

(comp ((resolve 'pandeiro.boot-http/serve)) (watch) ((resolve 'adzerk.boot-cljs.repl/cljs-repl)) ... would work

juhoteperi21:01:53

Clojure will read the whole file first and try to resolve all symbols to vars, without top-level require reader can't resolve symbols to vars.

richiardiandrea21:01:08

understand, but I guess I can stick with the top level require, as the performance hit is minimal

richiardiandrea21:01:34

boot is faster than lein in any case on my machine

micha21:01:57

you can also wrap in eval instead of using resolve i think

micha21:01:38

(deftask foo []
  (require '[sadf.qwer :refer [foop]])
  (eval '(foop 100)))

micha21:01:43

i think that would work

richiardiandrea21:01:56

less verbose, I can try that out

esnunes21:01:17

where can I find boot.build example files?

richiardiandrea21:01:54

clojure.lang.ExceptionInfo: Unable to resolve symbol: cljs in this context

esnunes21:01:57

I want tasks to: build jar file, run tests whenever a file is saved, run repl, run app

micha21:01:19

@esnunes: the README for boot on github is a start

esnunes21:01:00

I read the whole README file, it tells me how boot works and how to create tasks. I've just realized there is "documentation" link right on the top, which points out to the wiki

esnunes21:01:05

thanks @micha

richiardiandrea21:01:10

(deftask build []
  (require
   '[adzerk.boot-cljs      :refer [cljs]])
  (comp (speak)
                 (resolve 'adzerk.boot-cljs/cljs)))
does not work here, but I am just experiment, I will follow the standard path I guess simple_smile

micha21:01:21

plenty of examples there simple_smile

richiardiandrea21:01:37

just toying around

juhoteperi21:01:47

@richiardiandrea: Try wrapping (resolve...) in paretheses

richiardiandrea21:01:05

right because it returns a function πŸ˜„

micha21:01:06

@esnunes: also the boot wiki and api docs

esnunes21:01:27

@micha I was avoiding search for examples right on google or github due to the fact that as boot is a very active project I might end up finding outdated examples, I will focus on wiki and api docs first simple_smile, thanks

richiardiandrea21:01:53

(deftask build []
  (require
   '[adzerk.boot-cljs      :refer [cljs]])
  (comp (speak)
        ((eval 'adzerk.boot-cljs/cljs))
        ))
works too!

micha21:01:19

@esnunes: we haven't made any breaking changes since 2.0.0, which was december 2014 i think

micha21:01:30

but the tasks may have changed since then, of course

esnunes21:01:43

nice, I'm totally new to boot, actually new to clojure too

richiardiandrea21:01:46

@micha: I guess you could even think about wrapping this require plus ((resolve ...)) in some sort of macro that does expose the symbol in the body...jst throwing ideas around πŸ˜‰

micha21:01:46

yeah you could make a macro that evals each expression separately at runtime

micha21:01:57

clojure does that itself for top level forms

micha21:01:32

that's why you can do this in your build.boot:

micha21:01:55

(require '[foo.bar :refer [baz]])

(baz 100)

micha21:01:15

because the clojure compiler will compile and eval each top level form separately

micha21:01:31

but each top level form is compiled as a unit

micha21:01:59

so inside of there you can't introduce new bindings except with let etc

micha21:01:13

i mean you can, but the compiler won't see them

micha21:01:34

because the require that's inside the top level form won't be evaluated until the entire top level form is compiled

richiardiandrea21:01:48

@micha it feels cleaner (to me at least) to have a require in the task that needs it, that is reason of my idea...but I can live with the way it is now :)

micha21:01:29

yeah you can do that for tasks especially

micha21:01:40

since the tasks don't have any transitive dependencies

micha21:01:54

so there isn't any chance of the dependency problems i described before