13 ms·
Show HN: I finished v5 of a JVM framework I've spent spent half a decade making
- didip 4y agoJavalin is the bomb! I don’t know why Java community likes to make things complicated.
- takoid 4y ago“An idiot admires complexity, a genius admires simplicity, a physicist tries to make it simple, for an idiot anything the more complicated it is the more he will admire it, if you make something so clusterfucked he can't understand it he's gonna think you're a god cause you made it so complicated nobody can understand it. That's how they write journals in Academics, they try to make it so complicated people think you're a genius.” - Terry A. Davis
- robertlagrant 4y agoWould prefer if this were worded more simply.
- the_only_law 4y agoI mean, you see who it’s attributed to…
- manishsharan 4y agoI like Jetty. Javalin is nice for Kotlin but Jetty + java has worked well for me.
- Scarbutt 4y agoWhat do you use for routing and DI? do you use Jetty handlers or the servlet API?
- mateuszf 4y agoDropwizard is cool if you write REST microservices. It uses embedded jetty, JAX-RS, Jackson, metrics, etc. As far as I know it's inspiration for Spring Boot, and it's simpler and ready to use on production.
- speedgoose 4y agoIt looks inspired by express.js, is it the case or are they both inspired by an older framework?
- tipsee 4y agoBoth inspired by Sinatra, the OG :)
- samtheprogram 4y agoExpress is inspired by Connect JS in terms of middleware — middleware written for Connect works in Express. The middleware style I believe is originally inspired by Rack, a Ruby project. Sinatra, also Ruby, predates Express and is based on Rack (in a similar way to Express, which used to be based on Connect if I’m not mistaken). I’m not sure what inspired Sinatra, but that’s probably the influence you’re seeing in these frameworks.
- stefs 4y agoi'm using javalin in production without problems. i have a custom html templating engine and can't wait to try the virtual threads. had no problems at all. i really like it. thanks!
- sgammon 4y agoheard great things about Javalin and I'm curious to check it out. congrats!
- michaelcampbell 4y agoBefore I saw the site, I just saw the headline and thought, "Another one I might look at, after I do something serious in Javalin".
- stevoski 4y agoThis is Javalin and it is great. We switched to it a few months ago from another micro-framework.
- tipsee 4y agoIndeed it is! May I asked what you switched from?
- topspin 4y agoI'll guess and say Spark. Not the big data Spark. This one: sparkjava.com A nice piece of work in its own right.
- stevoski 4y agoYou guessed correctly! Spark was fine, but was abandoned. Which means it was stuck using an end-of-life’d version of Jetty. Which meant that we could no longer pass security audits. Whereas Javalin continues to get frequently updated.
- topspin 4y agoSpark ruined me. Everyone expects Spring, but dealing with Spring and all the pointless annotation magic is a misery; I find myself longing to just use Spark and forgo all that crap. I suppose I'll try Javalin then next time I have the choice.
- michaelcampbell 4y ago> Spark was fine, but was abandoned. Aw, that's sad to hear. I've been out of JVM-in-anger space for awhile, but I always liked Spark when I was.
- dang 4y agoRelated: Show HN: Javalin 1.0 – A Kotlin/Java web framework - https://news.ycombinator.com/item?id=15644430 https://news.ycombinator.com/item?id=15644430 - Nov 2017 (87 comments) Show HN: Javalin, a Java/Kotlin REST API Framework - https://news.ycombinator.com/item?id=14434089 https://news.ycombinator.com/item?id=14434089 - May 2017 (21 comments)
- tipsee 4y agoThe good old days!
- rrampage 4y agoHow does Javalin compare with Dropwizard which is also quite lightweight?
- tipsee 4y agoJavalin offers way less, it's more or less just the web routing layer. No databases, no ORM, no config loading, etc.
- pkulak 4y agoI'm pretty sure the "Hello Javalin World" Kotlin example won't compile, just FYI.
- tipsee 4y agoSeems to compile fine here, what's the issue? Edit: I was looking at the wrong snippet, the offending snippet has been fixed.
- gavinray 4y agoProbably not used to seeing lambdas inside of parens: .get("/", ctx -> ctx.result("Hello World")) Could also be written as .get("/") { ctx -> ctx.result("Hello World") } The second form seems much more common in Kotlin.
- tipsee 4y agoYeah, no, he was 100% correct, I was just looking at the wrong snippet. It's been fixed now :)
- pkulak 4y agoHuh, I wonder what's different with my setup. I would need to put curly braces around that closure before it would compile, i.e: .get("/", { ctx -> ctx.result("Hello World") }) Closures defined only by the arrow are a Java thing... or so I thought. :D
- tipsee 4y ago> Closures defined only by the arrow are a Java thing... or so I thought. :D In fairness, I think you did copy the Java version. There's a little switch in the code boxes where you can toggle the language, if you switch to Kotlin you get the version with trailing closures :) Edit: I'm an idiot, I see the snippet you mean now. It's been updated now, give it a minute.
- 4y ago
- adamredwoods 4y agoI just started using this! Spring Boot seemed so convoluted, having to go to a website to even begin. And then to have the Tomcat dependency seemed like a heavy lift just to get a "hello world" working. Virtual threads seems to be the way to go. Virtual threads in Java 19: https://www.infoq.com/articles/java-virtual-threads/ https://www.infoq.com/articles/java-virtual-threads/
- dopidopHN 4y agoExcellent resource on virtual thread by one of the authors! Thanks. I have to see I’m pleased to see Java moving fast those days. I’m still digesting 17 and 18, but that give me a reason to look at 19. I honestly project loom was far from reaching that level of “standardness” … so I haven’t looked into it in years
- NightMKoder 4y agoI haven’t tried this framework, but just looking at some examples, the web sockets and sse seem a bit out of place. In a Loom world you’d expect these to use channels or queues or something similar in a loop - not callbacks. Callback hell is what virtual threads try to avoid. I’m not sure if loom has any primitives like go’s multi-channel select that might make this workable though. In either case Loom and frameworks that use it are super exciting! I’m looking forward to removing the 20 different thread pools we need to avoid deadlocks and just using the common one in our Clojure apps.
- uup 4y agoHaving recently implemented a WebSocket service in Go, the Javalin way seems preferable. This is what a similar Go version would look like: wsHandler := func(w http.ResponseWriter, r \*http.Request) { conn, err := upgrader.Upgrade(w, r) if err != nil { w.SendStatus(http.StatusInternalServerError) return } ctx, ctxCancel := context.WithCancel(context.Background()) var wg sync.WaitGroup wg.Add(1) go func() { defer sync.Done() for { msg, err := conn.ReadMessage() if err != nil { return } } }() msgPipe := make(chan []byte, 1024) wg.Add(1) go func() { defer wg.Done() for { select { case <-ctx.Done(): return case msg := <- msgPipe if err := conn.WriteMessage(msg); err != nil { return } } } }() go func() { <- ctx.Done() wg.Wait() close(msgPipe) }() } I like Go, but I found writing WebSocket code very annoying.
- pron 4y agoWe don't have selectable channels yet, but they're not needed as much in Java as they are in Go, because often multiple channels are used to signal cancellation, whereas in Java there's a standard mechanism for cancellation (Thread.interrupt() at the low level, with Future.cancel being higher level, and JEP 428's structured concurrency being higher level still https://openjdk.org/jeps/428 https://openjdk.org/jeps/428).
- simonw 4y agoI find that hello world example very pleasant to look at. Love that it's effectively a one-liner. public static void main(String[] args) { var app = Javalin.create(/*config*/) .get("/", ctx -> ctx.result("Hello World")) .start(7070); }
- jannes 4y agoLooks very similar to Express.js which came out in 2011 and has been one of the most popular frameworks in the Node.js world. https://expressjs.com/en/starter/hello-world.html https://expressjs.com/en/starter/hello-world.html
- moralestapia 4y agoCongratulations! This is great! Java deserves its comeback among the wave of nu-programming we are going through.
- stefs 4y agoyou can also use it with kotlin
- tasuki 4y ago> Java deserves its comeback among the wave of nu-programming we are going through. What is nu-programming? And why would Java deserve a comeback?
- moralestapia 4y ago>nu-programming I made that one up. >And why would Java deserve a comeback? Java is an extremely mature piece of technology, and having used it on the enterprise, I can attest that few things come close on flexibility and stability. Also, functional languages on top of the JVM (clojure, kotlin, scala) are very interesting on their own. Java deserves some love from this new wave of paradigm changes like "write-once-run-anywhere" v2.0, monadic programming, serverless functions, etc...
- KronisLV 4y ago> Java is an extremely mature piece of technology, and having used it on the enterprise, I can attest that few things come close on flexibility and stability. Very much agreed, as long as you don't have to deal with legacy projects with Java 8 to Java 11 migration, which might sour the view of the language as a whole for some folks. I think Java doesn't get as much love nowadays due to some of the frameworks having to deal with historical baggage (e.g. Spring being unwieldy, which is at least partially why people prefer Spring Boot), though Java probably isn't the only language for which this is the case: https://earthly.dev/blog/brown-green-language/ https://earthly.dev/blog/brown-green-language/ That said, Java and .NET are both good options in my eyes - reasonably productive, with pretty decent type systems and good runtime performance. Not perfect, but almost always decent choices. Oh, and the runtimes themselves are pretty great, especially because we get languages like Kotlin, Scala for the JVM and F# for the CLR. Then again, for different use cases I wouldn't scoff at Python, Ruby or Node either. Even something like PHP can be passable in some cases.
- spapas82 4y agoCan we use this to render traditional apps (no js frameworks)?
- recursivedoubts 4y agoJavalin is amazing. Kudos.
- iammiles 4y agoI just wanted to say thank you for your work. The straightforward docs are some the best in my opinion when you want to go from "How do I do ..." to answer. I ended up using Javalin with Kotlin and SQLite to build my wedding website. Most of my projects are lucky to see the light of day, but with a very persistent project manager and a simple lightweight framework, I was able to ship a fantastic product with very little fuss.
- tipsee 4y agoHey, thank you for using it. Single-page docs are also my favorite, and Javalin/jdbi/SQLite is my goto for quick stuff! > but with a very persistent project manager Your partner? :D
- iammiles 4y agoYep! At least they didn't mind when I was drinking on the job.
- Scarbutt 4y agoI can see how DI will be overkill for a wedding website and Javalin/jdbi/sqlite is more than enough but for most business applications written in Java you really wish you had started with DI. Any DI libs you recommend for working with Javalin?
- tipsee 4y agoHard disagree on needing a DI library, manual DI is great.
- Scarbutt 4y agoDisagree on using a lib? cause I guess doing manual DI is still DI.
- tipsee 4y agoYes, disagree on needing a library. The way your comment was worded made it seem to me like you were saying all serious Java applications need a DI library, I'm sorry if I misunderstood you. I prefer doing my ID manually, so no recommendation :)
- kcbanner 4y agoJavalin has been powering one of my projects for years now without issues. Really great framework. Thanks!
- sandGorgon 4y agothis is very cool. quick question though - do u have a gradle build setup ? im new to java and saw this problem on spring boot. That you needed to have this bunch of complex directory structures cos of the way java packages worked. for e.g. the test directories were parallel to the src directory, so they could be named with the same package name. for a single file...i can just run java. but it would be nice to see a gradle setup that keeps simplicity and yet can have thousands of files and testcases organised in a nice structure. secondly, it is nice that you have Jetty hooks. Can you also have CORS & proxy protocol ? its literally mandatory to have this stuff if ur deploying on any of the k8s based clouds. e.g. https://stackoverflow.com/questions/73225314/accept-proxy-protocol-v2-traffic-with-jetty-in-spring-boot https://stackoverflow.com/questions/73225314/accept-proxy-pr...
- tipsee 4y agoI'm not super sure what you're asking, but Javalin doesn't care at all about your directory structure. You can add it as a dependency to any existing gradle project you have, and import it like any other Java library (like java.lang.String).
- matsemann 4y agoThat's not a spring thing, but a java tools convention (having a src and test folder etc). Nothing stops you from doing it differently, but most tools work out of the box if you follow that setup. So better to just do it than having to fight with / configure every part of your pipeline.
- sandGorgon 4y agoim not disputing that. im wondering if javalin came with one out-of-the-box is all.
- davidoniumz 4y agoI successfully used Javalin in a project using Kotlin + Koin for dependency injection + jOOQ for database access. Was a joy to setup and work in that project. Thank you! Congratulations on the major release and keep up the good work.
- tdudzik 4y agoJDBI also could be really nice as a minimalistic layer for a db access
- ekvintroj 4y agoI usted Javalin a few months ago for a kotlin api. It's awesome!
- jpgvm 4y agoI have used Javalin for a number of Kotlin backend projects of late, thanks for all your hard work!
- heurisko 4y agoGiven Project Loom hasn't been available, how does it utilise Virtual Threads already?
- oweiler 4y agoProject Loom is in preview, and far from available. As far as I can see, Javalin doesn't make use of virtual threads yet.
- tipsee 4y agoIt does :) We use reflection to build the Virtual Thread Factory if the user has Loom enabled in their enviroment: https://github.com/javalin/javalin/blob/master/javalin/src/main/java/io/javalin/util/ConcurrencyUtil.kt#L32-L91 https://github.com/javalin/javalin/blob/master/javalin/src/m...
- pron 4y agoVirtual threads are already available in the current version of the JDK (19) as a Preview feature. Because it's not a preview language feature but a preview API, libraries can use it without compiling with --enable-preview, either with reflection or by having the application supply a virtual thread ThreadFactory, which means they can make use of virtual threads if the application turns preview features on. Preview language features are different as they require compiling with --enable-preview, which creates a "poisoned" class file that cannot be loaded at all without preview enabled, so preview language features are not recommended for use by libraries, but preview APIs are fine (see JEP 12: Preview Features https://openjdk.org/jeps/12 https://openjdk.org/jeps/12).
- tipsee 4y agoIf you run this on JDK19 with *--enable-preview*, Javalin will use Virtual Threads for the Server ThreadPool (as well as all other ThreadPools it has).
- daveidol 4y agoHow does it compare to coroutines in Kotlin?
- de6u99er 4y agoPeeking int the docs, it reminds me a little bit of Vert-X. What do you think qbout such a statement?
- tipsee 4y agoI respect Vert.x a lot, so I'm flattered, but Vert.x is a huge beast with focus on performance. Javalin is basically a tiny UX layer on top of Jetty. I don't think they are very similar frameworks. Javalin's focus is on being "good enough" all around, but with the best possible developer experience.
- voidfunc 4y agoJavalin is great and a worthy successor to its predecessor Sparkjava
- vincnetas 4y agoWhat happened to sparkjava? Edit: looks like its alive and kicking : https://sparkjava.com/news https://sparkjava.com/news
- potency 4y agoCurious as to what has kept you motivated to continue working on the project this long? So many open source developers don't last nearly as long or jump to something new once the novelty of the project wears off.
- tipsee 4y agoI've been dogfooding it hard, which is a great incentive to keep working on it. I think we have 20 Javalin projects where I work. It's also gotten pretty popular lately (3m downloads last 12months), which of course helps a lot :)
- danaugrs 4y agoJavalin is a great name!
- helfire 4y agoHow does the dev tooling work? Rebuild & restart the app each time? I find working on any sizable codebase this can take minutes even on the latest spring-boot. Quakrus has an interesting live reloading classloader.
- ris58h 4y agoIf you use IDEA you can right-click modified .java file and click 'Compile and Reload File' https://www.jetbrains.com/help/idea/altering-the-program-s-execution-flow.html#reload_classes https://www.jetbrains.com/help/idea/altering-the-program-s-e...
- tipsee 4y agoRebuild and restart. Javalin itself starts in milliseconds (the test suite starts and stops servers across 600+ tests in less than 10 seconds). If you run in debug mode in IDEA, or use some hot-swapping tool like dcevm or jrebel, you won't always need to restart. I don't think there will ever be a dedicated tool provided by Javalin for this.
- freedomben 4y agoThis looks great! I did Java professionally for years but when all the jobs moved to EE I bailed for Ruby/Rails and similar. Java the language I've always really enjoyed. It's the frameworks and hundreds of design patterns that repelled me. I felt like they were all needlessly complex. If frameworks like this one were more common in Java world, I may never have left. This looks really nice! I wish more Java devs approached things with KISS and simple in mind, rather than looking at every problem as a way to apply some obscure design pattern that involves 15 levels of abstraction and indirection for a relatively simple microservice.
- cies 4y agoCongrats on the release! I reviewed Javalin lately and it was high on my list. We use quite a bit of Kotlin and look for a framework. I really dislike the magic that annotations bring to most popular Java frameworks (and Hibernate). I prefer most is just code". Kotlin helped us a lot in making our code more type safe, especially the KProperty way of referring to methods made a difference. Though I ended up leaning towards KTor, with Javalin as a close second. How would anyone with more knowledge compare the two (Javalin and KTor)?
- binkHN 4y ago> ...would anyone with more knowledge compare the two (Javalin and KTor)? I'd love to hear more on this as well. While I've done some minor stuff with Ktor, because JetBrains, I too would love some insight related to these as well.
- pron 4y agoVery nice! Just a minor nitpick (for those who care about the details of OpenJDK's development): virtual threads are not Project Loom, but rather one of the JEPs contributed to the JDK by Project Loom. There are two in JDK 19 (425 and 428), another in advanced stages (429), and there will probably be more. OpenJDK Projects aren't features but teams working on producing features focused on some area and then offering them to the JDK.
- tipsee 4y ago> Just a minor nitpick (for those who care about the details of OpenJDK's development): virtual threads are not Project Loom, but rather one of the JEPs contributed to the JDK by Project Loom. Thanks for clearing that up. Would adding a "from" be sufficient? and it uses Virtual Threads (“Project Loom”) by default and it uses Virtual Threads (from “Project Loom”) by default
- zmmmmm 4y agoWell done! Can't wait to see Loom become the default for web frameworks. Also spotted the Vue plugin - great to see this as so many light weight web apps with a few pages can benefit from using Vue but setting up all the build chain is such a drama that it's usually not worth it. Look forward to trying it out.
- tipsee 4y agoThank you! The Vue support is the thing in Javalin I'm the most proud of. There are a hundred web frameworks for the JVM, but none of them have anything close to the Vue support Javalin has. Some people think it's trash, but for me it's perfect.
- madm0d 4y agoNot trash at all, thanks for making it. In general thanks for keeping Javalin simple and opinionated, it is my goto when I get to decide!
- the-alchemist 4y agoSome quick questions: - are you using an already-existing HTTP engine, like Jetty or Tomcat? - how do virtual threads fit into a web framework? - do virtual threads make debugging more difficult? (A more general JVM question, I suppose) - any performance / readability benefit, or just a coolness factor?
- tipsee 4y agoare you using an already-existing HTTP engine, like Jetty or Tomcat? Yes, Javalin is built on top of Jetty. - how do virtual threads fit into a web framework? Most JVM web frameworks (Jetty included) have a thread based request lifecyle (one thread handles one request from beginning to end). The java.lang.Threads are extremely expensive (~1mb memory), while Virtual Threads are very cheap (~0mb memory). We also have another ThreadPool for JSON streaming, and one for writing async responses. Using Virtual Threads for these things reduces overall memory pressure. - do virtual threads make debugging more difficult? (A more general JVM question, I suppose) Not that I know, but I've never used this in production myself. - any performance / readability benefit, or just a coolness factor? The alternative here is java.lang.Threads, so primarily the memory footprint. There is no readability difference. When developing, you don't see this at all.
- rkalla 4y agoNothing to do with the project, but I read through it, so... 1. It's built natively on Jetty - very tight integration, not just some libs running in a Jetty container. 2. Web is inherently Request/Response - all of this can be handled with dramatically less resource requirements using Virtual Threads. Web is sort of the absolutely-best-use-case for Virtual Threads where as a Game Engine would be the opposite of that (one critical rendering thread and MAYBE a few extra long-lived threads for processing physics, audio, etc.) 3. I haven't tried debugging a Loom project but it's been in incubation for just under 100 years so I have to imagine this has been figured out. 4. About twice the throughput and 1/2 the latency of full OS threads - https://github.com/ebarlas/project-loom-comparison https://github.com/ebarlas/project-loom-comparison
- kitd 4y agoCongrats on v5. Have you tried it yet with GraalVM and native compilation? Any gotchas?
- tipsee 4y agoThanks! We had some interest in running Javalin on GraalVM in the past, but no one has updated the tutorial in many years. It used to work though, so I bet it still would, if you really wanted it to.
- kitd 4y agoMy concern would be around reflection, which I think you said gets used when running with virtual threads? and which native compilation can't handle easily. It may need a Quarkus-like pre-build step to generate glue code to work round it.
- sgt 4y agoGreat work. It's fascinating to see how "modern" Java looks these days.
- markhahn 4y agodoesn't JVM sniff of the 00's?
- floodfx 4y agoI haven’t written Java or Kotlin in years but this makes me want to try it again. Nice work!
- Matthias247 4y agoLooks interesting! One question about the response methods: If I would be using something like `ctx.result(inputStream)` - would it block the [lightweight] thread until all data is written. Or would the handler return and the data transfer happen in the background? One use-case I've only see marginally addressed in some frameworks is being able to run code past the point where all data is written - e.g. to record logs and metrics around the outcome of a request - e.g. whether the client hung up or all data was stored in socket buffers. If sending the result "blocks", that kind of code can be added naturally with a try/finally block around it. As far as I understand the docs, it might not block, but one might be able to install an "After" handler? Or would that also only run before the response is actually sent?
- tipsee 4y agoIf I would be using something like `ctx.result(inputStream)` - would it block the [lightweight] thread until all data is written. Or would the handler return and the data transfer happen in the background? There is no difference between OS threads and virtual threads in this scenario, and everything in Javalin is blocking (by default). The `ctx.result()` method doesn't actually write anything directly, it sets a result that will be written later. If you add an "After" handler, this also happens before the request is written. When the request is finally written, it's written on the same thread, and it is a blocking operation. There is a `RequestLogger` you can hook into that fires after the response has been written.
- reactor 4y agoLooks nice. Does it support hot reload? We use Quarkus heavily at work and one of the nifty feature is its ability to hot reload (fast restart to be specific) within few millisec, which makes our development quite a joy, kind of spoiled by that to be honest. If not now, any plan to support it in future?
- JodieBenitez 4y agoThat's probably the first time I see a java web framework api that actually makes me want to try it.
- seinecle 4y agoJavalin is also super good at serving content via a web API, too. To external clients or within a bigger app. I wonder how Loom will speed up concurrent calls to my APIs served by Javalin.
- amitchau 4y ago[dead]
- davidguetta 4y agoOn twentieth of a century !!
- djmips 4y agoDid half a decade sound more impressive than 5 years?
- tipsee 4y agoYes :)
- adibalcan 4y agoFrom my understanding this framework doesn’t include an ORM. I consider the ORM one of the most important component for a web framework