Fork me on GitHub
#boot
<
2016-08-29
>
chris_johnson01:08:27

newbie question: I’m using boot inside a CIDER repl session launched with cider-jack-in. I can call (get-env :boot-class-path) and see many JARs included there, including the .jar wherein I know to reside a certain fn

chris_johnson01:08:10

yet, when I call (require ‘[the-fn.namespace :refer [the-fn another-fn]]) I get told NoClassDefFoundError

chris_johnson01:08:38

and I’m just not sure where to look next. Could my CIDER session be messing things up somehow?

micha01:08:10

@chris_johnson the namespace is in a jar file?

micha01:08:59

what is the namespace called?

chris_johnson01:08:15

datomic.backup-cli

micha01:08:43

you can do like ( "datomic/backup_cli.clj")

chris_johnson01:08:52

I am trying to write up an AWS Lambda function to do backups so I don’t have to run a c3.large instance just to do a nightly cron job

micha01:08:55

if that returns a URL then you know it's on the classpath

micha01:08:08

require can still fail if it fails to compiler for whatever reason

micha01:08:43

ah yeah aws lambda and clojure is ... weird

chris_johnson01:08:14

well that part I’m not so worried about, yet

chris_johnson01:08:12

I’m worried about how I’m following other examples (gists and posts) of how to do the thing I want to do at all and …apparently it just doesn’t work when I try it?

micha01:08:47

i don't know a lot about cider unfortunately, being a vim user

micha01:08:59

you can try it in the boot repl perhaps

micha01:08:09

and if that works then it's probably related to the cider configuration

chris_johnson01:08:21

oh, I see what’s wrong

chris_johnson01:08:32

so earlier I had just physically cp’d the jar into my ~/.m2/repository (since it’s not distributed directly) and then later I thought “well maybe I should mvn install from the checkout I have just to see if I missed something”

chris_johnson01:08:09

and now instead of the 6MB .jar file, in my ~/.m2/repository I find a 3.7KB, 7-line-long “.jar file"

chris_johnson01:08:37

so that’s at least something I have to fix before I go looking for problems downstream of it, sorry for bothering the channel

micha01:08:46

haha no worries

chris_johnson01:08:05

thanks a ton for the tip though, I didn’t know about that and it helped me just now

micha01:08:28

yeah sometimes you don't get all the info from the exception that require throws

chris_johnson01:08:34

<aliens_guy>Maven</aliens_guy>

micha01:08:48

are you good at maven stuff btw?

chris_johnson01:08:59

I’m not …terrible?

micha01:08:04

i've been trying to find out some things about how it's done

chris_johnson01:08:25

I’ve been doing it a long time but I don’t have the urge to learn more about it than I have to

micha01:08:35

so i have a project with some dependencies, and those have dependencies that will be pulled into my project transitively

micha01:08:30

if one of those dependencies has a <repositories> element in the POM with repositories that i have not configured in my pom.xml, is Maven going to add those to my project automatically to resolve the transitive dependencies?

chris_johnson01:08:25

oh wow - I wouldn’t think so but I’d have to gin up a test case to be sure

micha01:08:27

i made a test today with boot where i modified a pom to add <repositories> and some bogus deps, and sure enough it does add them to my project. but that seems somewhat unsound

micha01:08:52

i'm curious what real mvn tool does in this situation

chris_johnson01:08:52

so like if you had a transitive dependency on Datomic and wanted to pull it in from automatically, you mean

chris_johnson01:08:11

and your actual project POM didn’t know anything about

micha01:08:21

well in my case i have a project that depends on tailrecursion/warp, which is in my local .m2 cache

micha01:08:33

this is like a junk dependency i use for testing things

chris_johnson01:08:47

mmm, local cache is very different from a separate remote repo from Maven’s perspective though

micha01:08:56

i modified its pom to include a <repository> that went to like http://example.com

micha01:08:10

and added a bogus dependency that doesn't exist in any of my project repos

micha01:08:26

i added the bogus dep to the tailrecursion/warp pom

micha01:08:43

when i resolve deps Aether does try to use a repo at http://example.com

micha01:08:55

to find the bogus dependency

micha01:08:19

this http://example.com repo is only in the tailrecursion/warp pom, which is the weird part

micha01:08:41

this seems kind of uncool, because who knows what will end up in your .m2 cache

chris_johnson01:08:46

how did tailrecursion/warp get into your repo? I understand that you’re using it as a test sled but did you mvn install it from a local source or pull it from somewhere remote and then start modifying it?

micha01:08:01

yes it's in clojars

micha01:08:13

i pulled it into local .m2 then modified the pom in place

chris_johnson01:08:35

that’s disturbing - I wouldn’t have thought that Maven would do that, though I could see it happening for things you install locally

chris_johnson01:08:54

though I guess the resolver probably shouldn’t care either way

chris_johnson01:08:22

well, that’s beyond my direct knowledge of Maven, sadly - I’d have to gin up some test cases locally to better characterize its behavior

micha01:08:48

yeah i've seen the <repositories> in the pom.xml files but i always assumed that that was only used at build time, when the jar associated with the pom was built, by maven

chris_johnson01:08:50

I wouldn’t have expected vanilla Maven to do that at all, fwiw

chris_johnson01:08:14

well, I know that that’s probably not true

micha01:08:28

it's confusing that pom.xml is both the defacto package descriptor and the build tool spec file

chris_johnson01:08:40

for example if you declare a parent POM, Maven will go looking for it and incorporate it into the effective POM for the current task or mojo or whatever

chris_johnson01:08:35

I’m surprised to learn that it will do the same thing for transitive deps just because, as you say, “hey, why is ru.h4xx0r.lulz/r00tk1t being downloaded!?"

micha01:08:58

or worse, org.clojure/clojure is downloaded from there

chris_johnson01:08:08

but the machinery for fetching stuff it doesn’t have right now and folding it into the effective environment is definitely there

micha01:08:14

and then pinned to that repo because of the metadata.xml in your local .m2

micha01:08:27

like i could make a malicious repo, then mirror every jar in clojars, with rootkit modifications

chris_johnson01:08:06

this seems to me to be something that would have been exploited just mercilessly if it were really true, though

chris_johnson01:08:05

I will investigate further and let you know what I find, maybe set up a remote repo that shadows something in clojars or central in S3 and see if I can make it break with vanilla Maven and a couple of pom.xmls

micha01:08:07

there is a ticket tracking this issue btw: https://github.com/boot-clj/boot/issues/496

chris_johnson01:08:40

oh man this is getting annoying. I can’t get boot repl to pull my leiningen creds out of gpg - I get

clojure.lang.ExceptionInfo: Assert failed: gpg: problem with the agent: Inappropriate ioctl for device
                            gpg: decryption failed: No secret key

                            (zero? exit)

chris_johnson01:08:01

I fixed this once and now I can neither remember what I had to do nor find the wiki or docs page that told me

chris_johnson01:08:03

right, I’ve done all that and had it working

micha01:08:51

and command line gpg -d ~/.lein/credentials.clj works ok?

chris_johnson01:08:54

and then I foolishly killed that iterm2 session and now it …doesn’t work again. I know there was a thing I had to do with GPG itself but I can’t remember what - I bet it’s in the leiningen docs linked there though, let me go look again

chris_johnson01:08:43

it does and moreover after I do that then boot repl works too

micha01:08:57

man i just put the things in env vars

chris_johnson01:08:58

so it is something to do with gpg agent caching

chris_johnson01:08:11

where’s the fun in that?

micha01:08:12

that way i can manage the gpg stuff in the shell

chris_johnson01:08:34

you’ll never learn any ancient history of your toolset by just doing the thing that works right away!

micha01:08:44

that's my dream

chris_johnson01:08:00

hooray - progress:

1. Unhandled java.lang.NoSuchMethodError
   com.fasterxml.jackson.databind.JavaType.isReferenceType()Z

chris_johnson01:08:19

at least I’m finding the thing on the classpath now

micha01:08:23

i bet it's parsing an error message from gpg

micha01:08:41

or trying to parse it as json

chris_johnson01:08:03

oh no, this is past the gpg issue, this is the response to (require ‘[datomic.backup-cli :refer [backup list-backups]])

chris_johnson01:08:27

dropping out of emacs and decrypting the creds file in the shell session was good enough

chris_johnson01:08:43

I did get it to present me the password prompt before but man, it hurt

chris_johnson01:08:09

like, mandatory M-x redraw-display after successful passphrase input hurt

chris_johnson01:08:28

I’m not …super sad about maybe just having to start off my workday with a quick gpg -d

micha01:08:50

the way i do it is i usually have vim open in one tmux tab, and boot repl in another

micha01:08:05

vim can still connect automatically to the running repl server

micha01:08:18

but i can also type in a regular repl for stuff like that

chris_johnson01:08:51

I like vim a lot, but I like CIDER a lot more

chris_johnson01:08:17

I’m sure it’s just a matter of knowledge investment though, I don’t really think there’s anything either toolchain can do that the other cannot

micha01:08:31

vim-fireplace is pretty minimal

micha01:08:49

it does like maybe 5% of what cider does

chris_johnson02:08:21

yeah, but how much of what cider does do I actually …use? a tiny bit more each week as I force myself to learn, I guess

chris_johnson02:08:15

so now what I really want is not (get-env :boot-class-path) but something very like mvn dependency:tree

micha02:08:37

boot show -d

chris_johnson02:08:43

because I am pretty sure what’s happening here is a nearest-neighbor is pulling in “the wrong Jackson"

micha02:08:46

and boot show -p

micha02:08:03

-p will show dependency conflicts

micha02:08:23

-d shows the dependency tree

chris_johnson02:08:28

holy crap that’s so fast from inside a repl

micha02:08:40

yeah everything is cached and memoized and whatnot

chris_johnson02:08:56

yay, I did it! Or at least, some N lines of dependency-graph chirurgery later, I get to an exception coming from the transactor code itself

chris_johnson03:08:41

I never again want to live in a world where I navigate Java dependency graphs without (boot (show “-d”)) and (boot (show “-p”)), wow

jonpither09:08:25

Hi - trying to get uber working... looks like succeeds but no uber is being created

martinklepsch09:08:56

@jonpither: are you having the target task at the end of your pipeline?

jonpither09:08:08

just added - thanks

jonpither09:08:56

I can't get build-docker to work here: https://github.com/adzerk-oss/boot-beanstalk, would this be for the same reason?

martinklepsch10:08:22

@jonpither: not sure what's not working for you but if you expect some files to show up in target or similar and they don't then the target task likely is what you need

lmergen13:08:31

what would be the best way to incorporate a (:refer-clojure :exclude [foo]) into my build.boot ? i’m probably missing something obvious ?

lmergen13:08:02

(specifically, i’m doing (deftask test [] …) and want to get rid of the warnings that clojure.core/test is being replaced by boot.user/test

martinklepsch13:08:05

@lmergen there's some solution to this but I usually just use test! instead of test

martinklepsch13:08:20

not an answer I know 😛

lmergen13:08:23

that appears to be the more pragmatic approach

micha14:08:00

@lmergen you can use ns-unmap

micha14:08:05

boot.user=> (doc ns-unmap)
-------------------------
clojure.core/ns-unmap
([ns sym])
  Removes the mappings for the symbol from the namespace.

micha14:08:46

the refer-clojure form adds mappings which you can remove later with ns-unmap

micha14:08:01

(ns-unmap *ns* 'test)

micha14:08:33

once you've unmapped the name you can still access the var via its fully qualified name, ie clojure.core/test

lmergen15:08:36

a-ha! that’s pretty cool, thanks!

pvinis18:08:23

is there a boot app with compojure-api?

pvinis18:08:33

i would like an example for that..

martinklepsch19:08:47

@pvinis this doesn't use compojure-api but plain compojure but I guess the difference isn't that big: https://github.com/Deraen/saapas

juhoteperi19:08:03

@pvinis Yeah, just add dependency to compojure-api, replace defroutes with defapi and follow Compojure-api guides, doesn't really differ anything from examples using Lein

pvinis19:08:57

thanks both 🙂

pvinis19:08:02

i will try now