Fork me on GitHub
#clojure-uk
<
2019-07-01
>
dharrigan08:07:06

I'm having an interop issue. Something that is a oneliner in Kotlin, doesn't work in Clojure, getting an IllegalAccessError in Clojure 😞

jasonbell08:07:30

what’s the one liner?

dharrigan08:07:55

A protobuf object that I call toByteArray on, i.e., message.toByteArray(). Works perfectly in Kotlin. The same in clojure (.toByteArray message) throws me an IllegalAccessException (JVMs in both cases is OpenJDK 12) and I'm on Clojure 1.10.1), here's what clojure is telling me...

dharrigan08:07:28

Execution error (IllegalAccessError) at com.foo.Foo$Bar/getSerializedSize (Bar.java:7881).
class com.foo.Foo$Bar tried to access private field com.google.protobuf.AbstractMessage.memoizedSize (com.foo.Foo$Bar and com.google.protobuf.AbstractMessage are in unnamed module of loader 'app')

dharrigan08:07:03

It's been stumping me all Sunday 😞

dharrigan08:07:39

I'm even considering just writing a tiny kotlin/java library/jar that does that for me, but I thought that clojure/java interop would come to my rescue 🙂

jasonbell08:07:52

tried to access private…..

dharrigan08:07:08

Yes, but it works perfectly in Kotlin, zero illegal access issues

jasonbell08:07:44

so what does the Kotlin/Java code look like?

dharrigan08:07:48

and I would hazard a guess that if I did the same in plain old java, it would be the same, after all, .toByteArray is a valid, legal method on the protobuf object, not hidden.

mccraigmccraig08:07:21

@dharrigan at a guess, clojure is attempting to reflectively access the field, and kotlin is linking - there are some JVM bugs around reflective access not implementing precisely the same access semantics as linking. i have encountered similar before, and the only solutions were either [a] a compiled proxy or [b] dynamically removing the access restriction if your security manager permits it

dharrigan08:07:40

@mccraigmccraig that's very useful information! thank you 🙂

dharrigan08:07:15

I have done this as well (set! *warn-on-reflection* true) and not seeing any warnings

dharrigan08:07:20

does that help?

mccraigmccraig08:07:37

dunno @dharrigan, it's been a while

mccraigmccraig08:07:07

i was just looking for the issue in the 3rd party java library where i encountered the problem, but i can't even remember which lib it was in ...

jasonbell08:07:18

There are days @dharrigan than the ease of writing some Java to do all the nasty stuff you’re trying to interop and shimming in you Clojure code just wins.

jasonbell08:07:38

I’ve written stuff around the google apis in Clojure and they’re a pain.

jasonbell08:07:07

All depends on the assumption that others will be able to maintain it all going forward.

3Jane08:07:17

> I’ve written stuff around the google apis in Clojure and they’re a pain.

3Jane08:07:21

fixed that for you

3Jane08:07:37

(also, hi! 411 I'm a Sunday roast >< )

3Jane08:07:25

(also... I know Google has a huge reputation, but has there been anything Googley that is not a pain / works well released recently?)

3Jane08:07:47

(...I guess a lot of people are happy with go, so maybe that?)

jasonbell08:07:58

Let me think: BigQuery Java API, an utter pain….. GoogleAds Java API, an utter pain….. nope can’t think of anything else.

flefik09:07:52

<-- not happy with golang

flefik09:07:04

the biggest upside with golang imo is that there is only one way of doing things generally, and golang doesnt give you very much rope to hang yourself with

flefik09:07:41

it’s hard (er) to write poor code in golang than say, in any proper OOP language

dharrigan09:07:53

@jasonbell Yes, I think so to. Clojure interop gets you there most of the time, but sometimes, a bit of java/kotlin to ease things isn't bad

dharrigan09:07:32

I'm doing protobuf stuff and man, the sooner we move to a more reasonable dataformat the better

thomas09:07:06

what is the problem with Protobuf @dharrigan (sorry if I missed this earlier on) and what you prefer instead?

thomas09:07:26

(besides your little interop problem you are having)

Conor09:07:45

@lady3janepl GKE is very nice (mostly)

Conor09:07:12

Certainly a lot better than doing it yourself and better than AWS/Azure's version

dharrigan09:07:54

Internally, we're discussing using other formats such as messagepack, cap'n proto (by the original other of protobu (https://capnproto.org/)), CBOR (since we deal with IoT devices and it's RFC spec'ed), Flatbuffers etc..

dharrigan09:07:36

We find protobuf a bit clunky for our needs and other formats can encode more efficiently thesedays

dharrigan09:07:25

We're also still consdiering doing everything (internally) as JSON, since it's ubiquitous.

dharrigan09:07:13

and most importantly, easy to debug

thomas10:07:37

surely you mean simple? 😉

dharrigan10:07:17

and that 🙂

yogidevbear11:07:12

Morning 🙂 New Clojure In article with the team at AppsFlyer is finally live. I hope you enjoy reading. Please share some retweet love if you can ❤️ https://twitter.com/yogidevbear/status/1145647419989925888

👍 12
clj 4
juxt 4
dharrigan15:07:34

for those with a passing interest, @alexmiller helped me solve my problem with the interop with protobuf

dharrigan15:07:15

> I had a rogue import of a protobuf library all the way from rebel readline which included the cljs libraries which included the closure compiler which included a version of protobuf that I am not using!

dharrigan15:07:19

this solved it

dharrigan15:07:43

:rebel {:extra-deps {com.bhauman/rebel-readline {:mvn/version "RELEASE" :exclusions [org.clojure/google-closure-library
                                                                                       rewrite-cljs/rewrite-cljs]}}

dharrigan15:07:58

this tool helped a lot (Alex's recommendation)

dharrigan15:07:12

so, there you go. classpath issue. 🙂

😢 4
mccraigmccraig07:07:08

always painful!

otfrom16:07:21

aws is always a dns issue

otfrom16:07:27

jvm is always a classpath issue

otfrom16:07:35

c++ is always LD_LIBRARY_PATH

otfrom17:07:02

I was wondering if people could help me with some naming. 😄

otfrom17:07:33

I'm outputting things to charts, csv, and excel files atm. For each thing I need to do some manipulation to get the data into the right shape

otfrom17:07:00

for excel and csv, the shapes are the same. It is a vector of vectors where the first vector is the header

otfrom17:07:50

for the charts it varies a lot more, there are different ways of pivoting the data to create grouped or stacked bar charts. I'm moving on to some multi line charts and heatmaps soon that will have even yet more shapes.

otfrom17:07:24

I've been struggling quite a bit with good names (and looking at some d3 examples where things like x0 and x1 are used for domain and subdomains on charts, I can see that even Mike Bostock is too)

djtango10:07:46

as compact and icky as x0 and x1 are, they kind of are in the natural language of the domain if you are trying to talk about a chart...

otfrom11:07:21

interesting. I've been looking at d3, grammar of graphics, and pivot tables to try to get some of the language and haven't been that happy, but x0 (for the main labelled x axis grouping) and x1 for the grouping on top of each x0 label is the way to go?

djtango14:07:48

I guess so - if you're plotting data on a 2D chart, then you have an x-axis and a y-axis On a given axis, you plot the variable which corresponds to that axis. The most general name you can give that is x / y respectively. If you want to plot more than one variable you introduce numerical count. Perhaps you could try horizontal-variable or horizontal-var but if you are expecting the reader of the code to be familiar with charts, and the local context of the code corresponds to axes/charts then x0 x1 etc probably is the most natural choice

practicalli-johnny08:07:01

It would be useful to describe the shape of the argument data and return data in a doc string. This would help others and of course future Bruce 😁

otfrom14:07:59

I like to punish future Bruce for trusting past Bruce. 🙂

practicalli-johnny17:07:31

Your so evil Bruce when not hugging people 😂

otfrom19:07:00

This is true

otfrom17:07:49

anyone got any good ways of thinking about these output, but not domain specific manipulations?

otfrom17:07:11

sometimes I can fake it by doing anonymous functions, but some of these I want to re-use or are too big to go in as an anon-fn

otfrom17:07:35

if you are at all interested in the concrete detail you can see it in a public repo here: https://github.com/MastodonC/witan.send.ingest

otfrom11:07:21

interesting. I've been looking at d3, grammar of graphics, and pivot tables to try to get some of the language and haven't been that happy, but x0 (for the main labelled x axis grouping) and x1 for the grouping on top of each x0 label is the way to go?