Fork me on GitHub
#boot
<
2016-04-09
>
richiardiandrea00:04:20

Does the following mean that I am chaining to many tasks?

clojure.lang.ExceptionInfo: java.lang.RuntimeException: Method code too large!, compiling:(NO_SOURCE_PATH:0:0)
    data: {:file "/tmp/boot.user1305866973653506383.clj", :line 67}
clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: Method code too large!, compiling:(NO_SOURCE_PATH:0:0)
             java.lang.RuntimeException: Method code too large!
          clojure.asm.MethodWriter.getSize                 MethodWriter.java: 1872
       clojure.asm.ClassWriter.toByteArray                  ClassWriter.java:  775
                                       ...                                        
                         clojure.core/eval                          core.clj: 3081
                         boot.pod/eval-in*                           pod.clj:  437
                                       ...                                        
                         boot.pod/eval-in*                           pod.clj:  440
  confetti.boot-confetti/eval2819/fn/fn/fn                 boot_confetti.clj:  155
replumb.boot-pack-source/eval2560/fn/fn/fn              boot_pack_source.clj:   45
            boot.task.built-in/fn/fn/fn/fn                      built_in.clj:  416
... repeating tasks over and over

micha16:04:28

If any emacs cider users here would like to test this PR that would be awesome!

adamkowalski18:04:19

Hey I am trying to get a bare bones boot build working so I can figure out how it works but I am struggling. I am trying to make a task that will compile my cljs files, automatically reload them, and then start a cljs repl but I can’t seem to get it to happen. I have put together a demo repo here: https://github.com/adam-r-kowalski/demo When I run my dev task it seems as if no javascript files are ever made but it goes through and it says compiling js/main.js in the terminal.

micha20:04:44

one thing you can do to start debugging is to add the show task to the pipeline

micha20:04:46

like this:

micha20:04:55

boot dev show -f

micha20:04:07

that will print the fileset as a tree each time the pipeline is run

micha20:04:22

so you can see which things were created and where they are

micha20:04:11

however i think the problem you're seeing in this specific case is the order of the tasks in your pipeline

micha20:04:11

the reload and cljs-repl tasks actually emit clojurescript that needs to be compiled by the cljs task

micha20:04:22

can you try reordering the tasks like this:

micha20:04:09

oops durr

micha20:04:57

disregard that, what you have looks correct

adamkowalski20:04:31

interesting, when I run it with the show task it seems like a bunch of things are being created, and I even get notified that the build succeeded, yet I still can’t actually use the js files

micha20:04:56

your project looks fine to me, what exactly isn't working?

adamkowalski20:04:27

here is the output of boot show http://pastebin.com/gpwkr3w0

adamkowalski20:04:14

well the thing that isn't working is actually using the compiled js index.html. It seems like nothing actually gets served js wise

adamkowalski20:04:34

I can serve the index hiccup page, but it says that there isnt any js/main.js

micha20:04:44

i don't see the serve task anywhere

micha20:04:54

try doing boot dev serve

adamkowalski20:04:05

im not using the http serve task, I just wrote a really basic aleph server

adamkowalski20:04:25

its in src/clj/demo/server.clj

micha20:04:26

i son't see it in the pipeline

adamkowalski20:04:50

well I wanted to have two repls, one for the client and one for the server

adamkowalski20:04:30

so rather then having the dev task start the server, I first ran a boot repl and just called (server/start) which would fire up the server and show my index.html

micha20:04:44

ok cool, that seems fine

adamkowalski20:04:45

then i started the boot task and wanted to get a cljs repl with that

micha20:04:14

i think you want one repl server

micha20:04:20

and two separate clients perhaps

adamkowalski20:04:20

yeah I think what i was doing was running boot dev boot repl -> (server/start) boot repl -> (start-repl)

adamkowalski20:04:48

that way I was thinking that I would have the dev task which takes care of reloading, compiling, etc, and I would have one repl for the client, and another for the server

adamkowalski20:04:05

but it seems like the server has no way of actually getting the generated files from boot dev

micha20:04:41

@adamkowalski: ok i cloned the repo

micha20:04:48

i have the server working

micha20:04:10

i made just one repl server

micha20:04:17

and connected to it from multiple clients

micha20:04:28

one client is doing (boot (dev))

micha20:04:45

another client has the http server via (server/start)

adamkowalski20:04:03

and it loaded the js/main.js?

adamkowalski20:04:17

i think all it should be doing is log that the application started for now

micha20:04:33

i got the html from localhost:3000

micha20:04:42

one sec i check the js

micha20:04:05

computing...

micha20:04:15

looks like a compojure problem maybe

micha20:04:28

it serves the hiccup for any URI

micha20:04:43

ah that's the not-found route

adamkowalski20:04:27

yeah I wanted to do that on purpose

adamkowalski20:04:33

that way I can manage all my routing clientside

micha20:04:57

i can see the js file on the classpath

micha20:04:12

(-> "js/main.js" io/resource slurp print)

micha20:04:26

so i think it must be something with compojure

adamkowalski20:04:23

hmm, so is there an example of like a barebones setup that shows how to get a backend, frontend, and boot working together?

adamkowalski20:04:00

just launch a server like jetty/http-kit/whatever, serve an index html and the javascript and get all the reloading?

micha20:04:04

have you seen that?

adamkowalski20:04:25

thanks looks interesting

micha20:04:35

i think the problem you're seeing is with compojure

micha20:04:55

it does a lot of magical things that usually don't work simple_smile

adamkowalski20:04:10

haha, do you have any recommendations for an alternative

adamkowalski20:04:29

im not opinionated about my stack

micha20:04:30

we sometimes use just the routing part

micha20:04:35

from compojure

micha20:04:50

that's the part that matches and destructures the URI

micha20:04:25

but like we were having a lot of problems with compojure automatically doing things that would cause problems

micha20:04:48

like encoding the response in a weird way

micha20:04:04

or trying to and then throwing exceptions when it didn't work

micha20:04:07

ah here is the problem

adamkowalski20:04:33

oh my resource path is not setup correctly?

micha20:04:03

i think that's just not a good way to do it (the way compojure does that)

micha20:04:40

you can use the wrap-resource ring middleware

micha20:04:47

instead of the compojure resources

micha20:04:24

that will work fine, (-> ... (wrap-resource :root ""))

adamkowalski20:04:48

ok thanks i’ll try that

dominicm20:04:54

@micha You should use bidi

micha20:04:57

@adamkowalski: let me know if that doesn't work i'll investigate further

adamkowalski20:04:47

oh that looks cool

micha20:04:30

our app is actually running in a proxy, with some requests being routed to a legacy backend, and some being processed locally

dominicm20:04:34

Compojure was one of the early recommendations, and I think people encounter it a lot in tutorials/blogs/etc. Bidi feels more Clojure-y. Data all the way down. Just routing.

micha20:04:22

yeah we have a lot of stats, logging and other things that we need to do in the proxy to process the responses

micha20:04:49

so things that make the assumption that they can return a response directly to the client won't work

dominicm21:04:15

@micha: Yeah. bidi is what you want.

micha21:04:12

let me compute! that's the motto

adamkowalski21:04:04

ok this is really weird… i have [ring “1.4.0”] in my dependencies in my set-env! but I cant access the ring.middleware namespace

adamkowalski21:04:11

all that is available is ring.util lol

micha21:04:41

@adamkowalski: boot show -d and boot show -p are your friends there

adamkowalski21:04:58

oh and @dominicm: how is bidi on cljs? have you made it work with the html5 history api?

adamkowalski21:04:36

@micha: yeah its got it in boot show -d

adamkowalski21:04:25

oh wow boot show -p is awesome

micha21:04:01

ring.middleware.resource/wrap-resource

martinklepsch21:04:11

@richiardiandrea: did the send! stuff work out for you?

dominicm21:04:52

@adamkowalski: 90% of bidi is: take string and routes, resolve value in route structure. And also take routes and value, and return string.

richiardiandrea21:04:16

@martinklepsch: I was trying than I noticed a problem on my side, I need to fix it and try again

dominicm21:04:21

I'm not sure if the html5 history api is implemented by bidi itself, but it might be, and I've just not used it

micha21:04:59

looks like you could pass the route from the callback to match-route

adamkowalski21:04:01

so you do hash based routing?

adamkowalski21:04:33

@micha: whats the boot equivalent of lein clean -> lein deps

micha21:04:52

@adamkowalski: there is no "clean" task!

micha21:04:06

boot doesn't make any stale things that could be cleaned

micha21:04:23

lein deps --> boot show -d

adamkowalski21:04:28

alright i gotta head out but thanks for all the help!

micha21:04:43

good luck! simple_smile

micha21:04:01

@dominicm: bidi looks like a good thing to replace what we have in our frontend, too

dominicm21:04:32

@micha: Yeah, bidi is great that way

micha21:04:44

one thing that would be great is to be able to change the routes as they appear in the URI without changing the names of the routes (for the bi-directional rendering)

micha21:04:28

looks like bidi can handle that kind of thing pretty easily

richiardiandrea21:04:11

@martinklepsch: I confirm that send! solves the problem, opening a PR as we speak

micha21:04:50

how can i make a clojure type hint for a native array of some java type?

richiardiandrea21:04:34

@micha are you creating the array?

micha21:04:44

well i have this:

micha22:04:05

(Files/copy ^Path src ^Path tmp fs/copy-opts)

micha22:04:41

the last argument is of the type array of java.nio.file.attribute.StandardCopyOption

micha22:04:04

i'm not sure how to make the type hint at the call site there

richiardiandrea22:04:31

you just need the type hint

micha22:04:36

yeah i'm jsut trying to avoid the reflection there

micha22:04:48

it's in a tight section of code in the fileset stuff

richiardiandrea22:04:50

well yeah there is a weird way, let me find it

richiardiandrea22:04:29

it actually follows the Java notation, I have it somewhere (when I was contributing to Counterclockwise I needed it)

micha22:04:24

the java type name is [Ljava.nio.file.StandardCopyOption;

richiardiandrea22:04:53

then there is a reader macro

richiardiandrea22:04:52

so I think I found an old post where it is discussed, dunno if it has been improved: https://groups.google.com/forum/#!topic/clojure/TFLUw8GSAbY

micha22:04:27

oh wow ok

micha22:04:30

@richiardiandrea: i dont' really understand the issue with boot.main/-main and the reloading warnings

micha22:04:49

boot.App/runBoot should be creating fresh pods

richiardiandrea22:04:17

loads the script again

richiardiandrea22:04:29

probably not in an isolated pod

micha22:04:39

but boot.main/-main is called only once

micha22:04:50

runBoot makes a new pod and calls -main in that

micha22:04:00

so it only should run once in each pod

micha22:04:42

like in my multi-module demo

micha22:04:47

you don't see those warnings

richiardiandrea22:04:01

i might be wrong, maybe I did not follow the threading properly, but

richiardiandrea22:04:11

so maybe I am using runBoot in the wrong way?

richiardiandrea22:04:37

this was the original runboot

micha22:04:07

the function accepts the core pod (that's where -main will be called) as an argument

micha22:04:16

are you creating a new main pod each time you call runboot?

micha22:04:05

yeah it looks like you're making a new pod there

micha22:04:33

well the first time

micha22:04:44

if the pipeline runs a second time you'll get the warnings

richiardiandrea22:04:51

so there is maybe something else going on

micha22:04:52

because you're reusing the same core pod again

micha22:04:42

maybe create the new core pod inside the with-pass-thru scope

richiardiandrea22:04:55

creating a new middleware every time

richiardiandrea22:04:49

now I am worried that I have done something horrible 😄 😱

micha22:04:59

if you are using the watch task or something that runs the pipeline more than once

richiardiandrea22:04:56

forcing the calls, but this was introduced later

richiardiandrea22:04:03

it was generating warnings earlier

micha22:04:20

i don't see any changes to boot.App, so i don't think any regressions were introduced with this PR

richiardiandrea22:04:49

yes I have not touched that, and runboot is your original task as well

micha22:04:57

this is very strange and curious

micha22:04:38

i wonder if somehow load-file is escaping the pod

richiardiandrea22:04:06

yes I was checking the clojure source

micha22:04:14

i don't think so, because i think require ends up being load-file at the end, and require seems to work okay

micha22:04:31

but it's been a while since i traced that part of clojure.core

richiardiandrea22:04:51

and how would it "escape" a pod for instance, it would need to modify the classpath basically right?

micha22:04:23

it would need to modify the parent of the clojure classloader or something

richiardiandrea22:04:30

it is static which is already scary 😄

richiardiandrea22:04:58

ok I am not going to paste anymore source I swear 😉

micha22:04:36

Util.sneakyThrow(e);

micha22:04:48

what an invention he discovered

richiardiandrea22:04:41

I see LOAD-FILE is interned but not declared anywhere...

richiardiandrea22:04:25

Compiler/loadFile

micha22:04:47

i wonder if we want clojure.core/load instead of load-file

richiardiandrea22:04:03

yeah, probably the former

richiardiandrea22:04:28

@micha but you see load calls RT.makeClassLoader() line 7200

richiardiandrea22:04:41

so it is escaping the pod right?

micha22:04:56

good question

micha22:04:38

so in boot.main/-main a temp file is created

micha22:04:55

but perhaps a directory can be craeted instead

micha22:04:07

and the boot.user namespace written there

micha22:04:20

then we could add that dir to the classpath and use clojure.core/load on it

micha22:04:27

or just require really

richiardiandrea22:04:07

yes probably better

richiardiandrea22:04:22

then @micha my patch should not be changed right? do you want me to open an issue with this to keep track?

micha22:04:56

yeah i think we can merge what we have

micha22:04:09

the load-file thing will be a pain to fix

micha22:04:40

it's not easy to make a temp directory

micha22:04:00

i'm not sure if we have acess to the boot tempdirs stuff there

richiardiandrea22:04:06

yeah...that's why I was thinking it requires you assistance and maybe some hammock time 😉

micha22:04:31

should i squash the commits?

micha22:04:43

or do you want to keep them as separate commits?

richiardiandrea22:04:16

I would like to keep them separate, I already kept only the most "significant" but it depends on you too of course

micha22:04:18

well you have access to merge it however you prefer

micha22:04:54

it's all good, whichever you prefer

richiardiandrea22:04:35

yeah I would merge like this (do I have access to merge myself?)

richiardiandrea22:04:49

it is a pity that all these warnings are going to show up

micha22:04:50

you should

richiardiandrea22:04:25

mmm...nope...in any case I have to fly in 4 mins..:D

richiardiandrea22:04:58

and I still think that in case of parallel execution we should not reload the script, so we should not pass by that part of -main...

richiardiandrea22:04:09

but at least we found the culprit