babashka

https://github.com/babashka/babashka. Also see #sci, #nbb and #babashka-circleci-builds .
danielgrosse 2020-09-30T06:08:33.205100Z

When I run a script using the bootleg pod, I now get a NullpointerException with the following error:

----- Error --------------------------------------------------------------------
Type:     java.lang.NullPointerException
Location: ***/static_website.clj:1:1

----- Context ------------------------------------------------------------------
1: (ns static-website.core
   ^--- 
2:  (:require [babashka.pods :as pods]))
3: 
4: (pods/load-pod "bootleg")
5: (require '[pod.retrogradeorbit.bootleg.utils :as utils])
6: 

----- Stack trace --------------------------------------------------------------
pod.retrogradeorbit.net.cgrand.xml - ***/static_website.clj:1:1
static-website.core                - ***/static_website.clj:4:1

danielgrosse 2020-09-30T06:09:51.206100Z

An verbose call with the classpath and main flag brought this additional info:

clojure.lang.ExceptionInfo: null
{:type :sci/error, :line 1, :column 1, :message nil, :callstack #object[clojure.lang.Delay 0x4d51040 {:status :ready, :val ((#object[clojure.lang.AFunction$1 0x39a2d783 "clojure.lang.AFunction$1@108981b80"] "bootleg") (#object[clojure.lang.AFunction$1 0x1c52cd9 "clojure.lang.AFunction$1@108019998"] document? "Document nodes are a parsing impelentation details and should never leak\n   outside of it." [x] (= :document (:type x))))}], :file "***/src/static_website/core.clj", :locals {}}
 at sci.impl.utils$rethrow_with_location_of_node.invokeStatic (utils.cljc:104)

danielgrosse 2020-09-30T06:10:35.207Z

As bootleg hadn't released a new version I suppose, bb had made a change here.

borkdude 2020-09-30T06:56:53.208800Z

Does it work with bootleg when used not as a pod though? Iโ€™m not aware of changes to the pod protocol that would break existing pods

Crispin 2020-09-30T07:00:20.210500Z

bootleg does push over a bunch of macro code that could be affecting things

borkdude 2020-09-30T06:57:47.209500Z

Maybe a question for @retrogradeorbit

Crispin 2020-09-30T06:59:09.210400Z

Hey what version of bb and bootleg is this with. I will try and reproduce.

Crispin 2020-09-30T07:00:20.210500Z

bootleg does push over a bunch of macro code that could be affecting things

Crispin 2020-09-30T07:04:48.211200Z

@danielgrosse is it possible to get a boiled down reproduction example that triggers the NPE?

danielgrosse 2020-09-30T07:06:56.212800Z

I run it with latest released version of bb and bootleg. It occurs with the example from the bootleg repo. But I try to setup something simple

Crispin 2020-09-30T07:09:05.213100Z

bootleg example should be sufficient. Which example?

Crispin 2020-09-30T07:09:27.213800Z

some how x is going in nil here by the looks

Crispin 2020-09-30T07:13:16.216500Z

I did have issues when podifying with passing metadata over the pod boundary. Turns out clojure's zipper implementations rely on embedded metadata in the data structure for functioning. Thought I had dealt with those issues (by keeping the zipper calls on the babashka side by sending that code over to be evaluated bb side). Maybe not. Will need to test to see.

Crispin 2020-09-30T07:23:02.217Z

ok. have reproduced it. Will investigate. https://github.com/retrogradeorbit/bootleg/issues/72

borkdude 2020-09-30T09:10:15.220100Z

@danielgrosse Found the bug. It's an issue with babashka.pods and bb 0.2.1. For now use 0.2.0 with the bootleg pod

2020-09-30T09:12:04.221300Z

Babashka seems to use nio.FileVisitor and FileVisitResult to build uberjars, so I thought it would be possible to use FileVisitor with bb, but apparently not. Would it be cheap to add these, since they are already used internally?

borkdude 2020-09-30T09:14:45.221900Z

@danielgrosse Now added bb 0.2.0 to glam:

$ glam install org.babashka/babashka@0.2.0
$ bb --version
babashka v0.2.0
so you can easily switch per shell: https://github.com/borkdude/glam

borkdude 2020-09-30T09:15:46.222700Z

@hugod I guess so. How would the interop look? I'm not sure if the interpreter already can handle that (if reify etc is involved)

borkdude 2020-09-30T09:17:43.222900Z

can you post a Clojure example?

2020-09-30T09:22:38.224900Z

the uberjar code is representative of what I was trying to do. Without reify though I guess this is a non-starter.

borkdude 2020-09-30T09:23:49.225100Z

The thing is, reify does work, but only for protocols at the moment

borkdude 2020-09-30T09:24:09.225300Z

and some Clojure interfaces which create objects that only work with Clojure, not when being passed back to Java

borkdude 2020-09-30T09:24:39.225500Z

if you want to have compatibility with both JVM and bb, use reader conditionals in that case and rewrite using map, filter, etc

2020-09-30T09:28:07.225700Z

ok, thanks for explaining

borkdude 2020-09-30T09:32:14.225900Z

at interpretation time we can't create new classes which is a fundamental limitation of graalvm, that's basically the problem. although we could maybe have support for a limited set of interfaces / superclasses. feel free to post an issue at bb and it might be addressed in the future

2020-09-30T09:37:02.226100Z

Itโ€™s a testament to bb that you donโ€™t have to think about the graalvm limitations most of the time.

borkdude 2020-09-30T09:38:47.226300Z

I think we could add support for it like this:

user=> (defn sci-reify [clazz impls] (when (= clazz Object) (reify Object (toString [this] ((get impls :toString) this)))))
#'user/sci-reify
user=> (reify Object (toString [this] "foo"))
#object[user$eval176$reify__177 0x6a0ac48e "foo"]
user=> (sci-reify Object {:toString (fn [_] "foo")})
#object[user$sci_reify$reify__173 0x38704ff0 "foo"]

borkdude 2020-09-30T09:39:13.226500Z

so then we will make some pre-defined supported interfaces in sci that you can use with reify

borkdude 2020-09-30T09:43:15.226700Z

https://github.com/borkdude/babashka/issues/600

2020-09-30T09:46:24.227100Z

are protocol extensions a similar problem?

borkdude 2020-09-30T09:47:09.227300Z

yes, but because they are not passed back to Java I have enough hooks to work around that

2020-09-30T09:53:21.227500Z

so protocol extensions should work? I tried extending http://clojue.java.io/Coercions onto nio.Path but get a nil pointer exception.

borkdude 2020-09-30T09:54:56.227700Z

they should work if babashka knows about that protocol. so far it only knows about Datafiable, Navigable, and interfaces IAtom, IDeref

borkdude 2020-09-30T09:55:17.227900Z

could add support for that protocol. issue welcome

borkdude 2020-09-30T09:58:42.228100Z

Here's the implementation for Datafiable: https://github.com/borkdude/babashka/blob/master/src/babashka/impl/protocols.clj

borkdude 2020-09-30T09:59:30.228500Z

Protocols are implemented as multimethods in sci (under the hood), since protocols also do compile time things, but multimethods don't

borkdude 2020-09-30T10:00:44.228800Z

so all functions that deal with these protocolized objects should be patched as well, to check for a sci-protocolized objects and if not, then defer to the old function

borkdude 2020-09-30T10:02:01.229100Z

major workarounds, but they do work :)

2020-09-30T10:02:45.229300Z

the flexibility the workarounds give seems worth it

borkdude 2020-09-30T10:03:50.229500Z

usually the fallback is implemented using a :default multimethod. I was lucky that this all kinda worked

borkdude 2020-09-30T10:26:19.230100Z

@danielgrosse Fix pushed to master. New bb binaries will be available in #babashka_circleci_builds in a few minutes

borkdude 2020-09-30T10:27:24.230200Z

Also made an issue for this: https://github.com/borkdude/babashka/issues/601

borkdude 2020-09-30T10:35:24.231100Z

Seems to work! @retrogradeorbit @danielgrosse

$ glam install org.babashka/babashka@0.2.2-SNAPSHOT retrogradeorbit/bootleg --force
$ cat /tmp/test_pod.clj
(ns mybbscript
  (:require [babashka.pods :as pods]))

(pods/load-pod "bootleg")
(require '[pod.retrogradeorbit.bootleg.utils :as utils])

(-> [:div
     [:h1 "Using Bootleg From Babashka"]
     [:p "This is a demo"]]
    (utils/convert-to :html))
$ bb /tmp/test_pod.clj
"<div><h1>Using Bootleg From Babashka</h1><p>This is a demo</p></div>"

3๐Ÿ‘
borkdude 2020-09-30T10:47:21.232200Z

Hmm I guess bootleg could also be useful in the context of the new web server

borkdude 2020-09-30T10:47:53.232600Z

To serve html

2020-09-30T10:48:25.233200Z

i think babashka might just replace python for me lmao

Crispin 2020-09-30T11:12:53.233400Z

somewhere in there is a web development framework waiting to get out. Just needing someone to tie it together...

motform 2020-09-30T12:40:37.235300Z

Is there a way to do oauth1 auth in bb? is it preferred to shell out? (the use case is the twitter api)

2020-09-30T12:47:40.235500Z

Although it's not a framework ... https://www.mxmmz.nl/blog/building-a-website-with-babashka.html

2020-09-30T12:48:00.235700Z

Interested to try the bootleg pod soon ๐Ÿค“

borkdude 2020-09-30T12:50:03.236200Z

Not sure, but there is an http client and http server now, so it should be possible using those maybe?

borkdude 2020-09-30T12:50:24.236600Z

and if you figure it out, an example gist would be highly appreciated

motform 2020-09-30T12:58:48.237700Z

thatโ€™s what I figured, yeah, Iโ€™ve never really used oauth before but Iโ€™ll keep at it!

2020-09-30T13:02:36.238100Z

I would say bb has all the ingredients with the client and server

borkdude 2020-09-30T13:20:03.238200Z

@hugod Are you on mac or linux or do you build bb from master?

2020-09-30T13:21:17.238400Z

on mac. using 0.2.1 at the moment, though I have built bb myself as well.

borkdude 2020-09-30T13:22:48.238600Z

This script now works:

(java.nio.file.Files/walkFileTree
 (.toPath (java.io.File. "."))
 (reify java.nio.file.FileVisitor
   (preVisitDirectory [this p attrs]
     (prn :pre-dir (str p))
     java.nio.file.FileVisitResult/CONTINUE)
   (postVisitDirectory [this p attrs]
     (prn :post-dir (str p))
     java.nio.file.FileVisitResult/CONTINUE)
   (visitFile [this p attrs]
     (prn :file (str p))
     java.nio.file.FileVisitResult/CONTINUE)))

borkdude 2020-09-30T13:23:16.239Z

I've yet to write a unit test for it

2020-09-30T13:25:52.239200Z

I donโ€™t know how you respond so quickly to everything! Thatโ€™s going to be very useful.

borkdude 2020-09-30T13:31:53.239400Z

well I've already had the idea for a long time and I've got a day off today ;)

borkdude 2020-09-30T13:37:50.239600Z

Pushed to master. I'll probably release 0.2.2 somewhere today

1๐ŸŽ‰
borkdude 2020-09-30T14:08:54.239900Z

I tried this, but I still get the same error

Darin Douglass 2020-09-30T14:30:44.240100Z

hmm, shucks. that fixed postal for me in a normal JVM context. not sure what more graal will need ๐Ÿ˜•

borkdude 2020-09-30T14:35:13.240400Z

I fixed that by adding a class to the reflection config. Now I'm looking at `javax.activation.UnsupportedDataTypeException: no object DCH for MIME type text/plain; charset=utf-8 `

Darin Douglass 2020-09-30T15:05:03.240600Z

feels like we're going down the rabbit hole of javax.mail soon. (i WORK at a clojure shop that deal with email, so a rabbit hole it is)

borkdude 2020-09-30T15:05:45.240800Z

Summary in https://github.com/borkdude/babashka/issues/599

borkdude 2020-09-30T15:06:04.241200Z

Maybe writing it as a pod wrapping that other library could work

borkdude 2020-09-30T15:16:15.241800Z

The next bb will support reifying http://java.io.FileFilter and java.nio.file.FileVisitor. What other classes are useful to reify in Clojure?

borkdude 2020-09-30T15:39:29.242400Z

@corasaurus-hex When you were working on the fs lib for bb, there was something like this you were running into right?

2020-09-30T17:31:19.242500Z

Hey. Does bb support reify nowadays? I recall getting bitten by http://java.io.FilenameFilter - https://github.com/clj-commons/fs/blob/642e0e6fc734b0855a4579d4518073b2192ac0ef/src/me/raynes/fs.clj#L8

borkdude 2020-09-30T17:50:52.242800Z

well, as of today yes, in #babashka_circleci_builds ;)

borkdude 2020-09-30T17:51:26.243Z

worth a try again with that lib I'd say

borkdude 2020-09-30T18:17:56.243200Z

Hmm, I guess it's FilenameFilter, and there's FileFilter. I'll add both

borkdude 2020-09-30T18:22:19.243400Z

pushed to master. fs seems to work now. btw this is the maintained repo: https://github.com/clj-commons/fs

2020-09-30T18:25:00.244Z

Exciting to hear about reify!

borkdude 2020-09-30T18:26:20.245Z

Yes. Note that reify will work only with a selection of pre-defined classes, so if you need more, let me know

1๐Ÿ‘
borkdude 2020-09-30T18:59:27.245700Z

Alrighty, pushed 0.2.2 with the fix for bootleg and some nice reify improvements: https://github.com/borkdude/babashka/blob/master/CHANGELOG.md#v022-2020-09-30

3๐Ÿ‘3๐Ÿ’ช3๐ŸŽ‰
borkdude 2020-09-30T19:21:22.246200Z

$ which bb
/Users/borkdude/.glam/repository/org.babashka/babashka/0.2.2/bb
$ bb --version
babashka v0.2.2
$ export BABASHKA_CLASSPATH=$(clojure -Spath -Sdeps '{:deps {clj-commons/fs {:mvn/version "1.5.2"}}}')
$ time bb -O -e '(ns foo (:require [me.raynes.fs :as fs])) (map str (fs/glob "*.md"))'
"/Users/borkdude/Dropbox/dev/clojure/babashka/CHANGELOG.md"
"/Users/borkdude/Dropbox/dev/clojure/babashka/README.md"
"/Users/borkdude/Dropbox/dev/clojure/babashka/CONTRIBUTING.md"
bb -O -e   0.03s user 0.02s system 92% cpu 0.057 total

42๐ŸŽ‰