Early Feedback Request: Kotlin-mail


#1

At work I spend a lot more time with JavaMail than I’d like to. It’s an awesome library, but it’s also really old (as in it’s targeted to older JVMs, and doesn’t take advantage of newer stuff, like enums or generics). I’ve thought about writing a replacement - or at least a wrapper of some kind - to make it a little more modern. Coming across kotlin, I thought this would be a great way to learn the language and build a better JavaMail at the same time.

The project is at https://github.com/SlothLabs/kotlin-mail, and there’s instructions for pulling it from Maven Central there as well. The feature set is lacking - mainly just builders for searching and sorting an IMAP folder - but it’s still only in 0.1.0. By 1.0.0 I’d like to wrap the entire JavaMail library, with the end goal being a full replacement.

I’d love any feedback at all. There’s API docs but no user guide yet; for now, there’s a sandbox-ish test class I’m using to flesh out usability/features, but I know that won’t work in the long run (and it isn’t commented anyways). I’m still new to kotlin, so no clue if I’m doing things “idiomatically” or if I’m using it as a better Java (I don’t think that’s the case, but still…), so any kind of code review feedback would be appreciated as well.

And of course if there’s any kind of bugs or feature requests or anything, feel free to throw them in the issues bucket on github too :slight_smile:

Thanks!


#2

Great work! You’re totally on the right track with wrapping JavaMail rather than trying to reimplement it, and this is exactly the kind of thing Kotlin shines at.

Please don’t feel like there’s a difference between “idiomatic Kotlin” and “a better Java”. Kotlin is not a religion and doesn’t have strong opinions on the write way to do things, which is one reason many of us like it. And besides, other than being kind of old and verbose, Java itself isn’t deeply flawed, so there are many worse things than a better Java.

With respect to your API, judging purely from the code snippet in the README, my thoughts are:

  • Is it really needed to use the + operator in the way you’re doing? This feels a bit like operator overloading abuse to me.
  • Maybe you can separate out the lifetime management. I get that you want to ensure the IMAP sessions/folders are closed, but your users may not want to follow the “open, run a code block, close” pattern all the time. It’d be more Kotlinish to add a use method to the underlying JavaMail objects, so you can do imap(...).use { ... } if you want that pattern, or just stash the result of the imap function somewhere else.
  • Look into RxJava/RxKotlin to expose observables of folder changes. It’s pretty nice.

You could also generate some API docs using Dokka, which would help explain what’s included in the wrapper beyond just the README.

Looking forward to a much needed refresh of a trusty workhorse!


#3

Thanks - that’s exactly the kind of feedback I was looking for!

I’ve been on a bit of a language binge lately and “idiomatic” is thrown out there a lot; I might’ve used it a little incorrectly. The main thing I meant was more “am I using the language correctly, and are there features I’m over- or under- using.” And Java is a good language, but after 15+ years of working with it I’m just a little tired of it :slight_smile:

Re: Operators - I completely forgot to document it, but there is an alternative to the overloaded operators. The methods in the example just generate JavaMail SearchTerm instances, and the operators add them (i.e. raw SearchTerms) to the builder. There’s additional methods that combine the operations - withFrom("blah") instead of +from("blah"). Theres also some infix functions for syntactic sugar, so you can also call +(from("blah") and subject("test")).

The connection stuff is a valid point, and something I’ve thrown around in the back off my mind for a bit. I know I’m by far not the only use case out there, but in my work I’ve mostly used JM from a web app, so there’s no long-running state. You open the connection, do your stuff, then close it. I know that loses the advantage of IMAP’s server side caching/sessions, but that’s been better than just having a ton of open connections bogging down the server. Regardless, I agree that’s definitely a necessity moving forward; starting out though I’m building off things I’ve wished JM had in my experience (hence IMAP before SMTP, POP, or even GMail extensions).

You also added a suggestion with .use(); that’s something I want to add as well - I don’t believe JM’s Store classes implement Closeable/AutoCloseable, and that’s been annoying too.

I’ve only barely worked with anything from RxJava, but I’m all for the reactive/async approach. I’m not sure about including it in the main library, just to minimize dependencies, but that’s definitely a great idea for an additional module if nothing else. (And maybe it’d be worth pulling into the main API; just a little leery of having the extra dependency if it wouldn’t be used as much as the non-reactive versions.)

The API does have dokka comments, and the doc jar should be available with the artifact in Maven Central as well. This is the first project of any kind I’ve released to the wild, so I have no clue how that actually comes across. Also don’t really have any idea how to set up travis and github pages to host the docs. I have started a wiki on github for it, so hopefully I can keep that going too.

Thanks again for the feedback! Anxious to hear more :slight_smile: