Javalin - A simple web framework for Java and Kotlin

Overview

Chat at https://discord.gg/sgak4e5NKv Chat at https://gitter.im/javalin-io/general CI License Maven

Javalin - A simple web framework for Java and Kotlin

Javalin is a very lightweight web framework for Kotlin and Java which supports WebSockets, HTTP2 and async requests. Javalin’s main goals are simplicity, a great developer experience, and first class interoperability between Kotlin and Java.

Javalin is more of a library than a framework. Some key points:

  • You don't need to extend anything
  • There are no @Annotations
  • There is no reflection
  • There is no other magic; just code.

General information:

Quickstart

Add dependency

Maven

<dependency>
    <groupId>io.javalingroupId>
    <artifactId>javalinartifactId>
    <version>4.3.0version>
dependency>

Gradle

implementation "io.javalin:javalin:4.3.0"

Start programming (Java)

ctx.result("Hello World")); } }">
import io.javalin.Javalin;

public class HelloWorld {
    public static void main(String[] args) {
        Javalin app = Javalin.create().start(7000);
        app.get("/", ctx -> ctx.result("Hello World"));
    }
}

Start programming (Kotlin)

ctx.result("Hello World") } }">
import io.javalin.Javalin

fun main() {
    val app = Javalin.create().start(7000)
    app.get("/") { ctx -> ctx.result("Hello World") }
}

Examples

This section contains a few examples, mostly just extracted from the docs. All examples are in Kotlin, but you can find them in Java in the documentation (it's just syntax changes).

Api structure and server config

val app = Javalin.create { config ->
    config.defaultContentType = "application/json"
    config.autogenerateEtags = true
    config.addStaticFiles("/public")
    config.asyncRequestTimeout = 10_000L
    config.dynamicGzip = true
    config.enforceSsl = true
}.routes {
    path("users") {
        get(UserController::getAll)
        post(UserController::create)
        path(":user-id") {
            get(UserController::getOne)
            patch(UserController::update)
            delete(UserController::delete)
        }
        ws("events", userController::webSocketEvents)
    }
}.start(port)

WebSockets

ws.onConnect { ctx -> println("Connected") } ws.onMessage { ctx -> val user = ctx.message (); // convert from json string to object ctx.send(user); // convert to json string and send back } ws.onClose { ctx -> println("Closed") } ws.onError { ctx -> println("Errored") } }">
app.ws("/websocket/:path") { ws ->
    ws.onConnect { ctx -> println("Connected") }
    ws.onMessage { ctx ->
        val user = ctx.message<User>(); // convert from json string to object
        ctx.send(user); // convert to json string and send back
    }
    ws.onClose { ctx -> println("Closed") }
    ws.onError { ctx -> println("Errored") }
}

Filters and Mappers

... } // runs before requests to /some-path/* app.before { ctx -> ... } // runs before all requests app.after { ctx -> ... } // runs after all requests app.exception(Exception.class) { e, ctx -> ... } // runs if uncaught Exception app.error(404) { ctx -> ... } // runs if status is 404 (after all other handlers) app.wsBefore("/some-path/*") { ws -> ... } // runs before ws events on /some-path/* app.wsBefore { ws -> ... } // runs before all ws events app.wsAfter { ws -> ... } // runs after all ws events app.wsException(Exception.class) { e, ctx -> ... } // runs if uncaught Exception in ws handler">
app.before("/some-path/*") { ctx ->  ... } // runs before requests to /some-path/*
app.before { ctx -> ... } // runs before all requests
app.after { ctx -> ... } // runs after all requests
app.exception(Exception.class) { e, ctx -> ... } // runs if uncaught Exception
app.error(404) { ctx -> ... } // runs if status is 404 (after all other handlers)

app.wsBefore("/some-path/*") { ws ->  ... } // runs before ws events on /some-path/*
app.wsBefore { ws -> ... } // runs before all ws events
app.wsAfter { ws -> ... } // runs after all ws events
app.wsException(Exception.class) { e, ctx -> ... } // runs if uncaught Exception in ws handler

JSON-mapping

// map array of Todos to json-string ctx.json(todos) } app.put("/todos") { ctx -> // map request-body (json) to array of Todos todos = ctx.body >() ctx.status(204) }">
var todos = arrayOf(...)
app.get("/todos") { ctx -> // map array of Todos to json-string
    ctx.json(todos)
}
app.put("/todos") { ctx -> // map request-body (json) to array of Todos
    todos = ctx.body<Array<Todo>>()
    ctx.status(204)
}

File uploads

ctx.uploadedFiles("files").forEach { (contentType, content, name, extension) -> FileUtil.streamToFile(content, "upload/$name") } }">
app.post("/upload") { ctx ->
    ctx.uploadedFiles("files").forEach { (contentType, content, name, extension) ->
        FileUtil.streamToFile(content, "upload/$name")
    }
}

OpenAPI (Swagger)

Javalin has an OpenAPI (Swagger) plugin. Documentation can be enabled both through a DSL and through annotations, and Javalin can render docs using both SwaggerUI and ReDoc. Read more at https://javalin.io/plugins/openapi.

Special thanks

Comments
  • Swagger things

    Swagger things

    https://bitbucket.org/atlassian/swagger-request-validator https://github.com/ShikaSD/javalin-swagger https://github.com/manusant/SparkSwagger https://github.com/swagger-api/swagger-codegen

    HELP WANTED 
    opened by tipsy 59
  • Javalin 4 wishlist

    Javalin 4 wishlist

    The master branch is now in 4.0.0 mode, write any feature requests here.

    Changes: https://javalin.io/news/javalin-4-development-updates

    Current version:

    <dependency>
      <groupId>io.javalin</groupId>
      <artifactId>javalin</artifactId>
      <version>4.0.0.ALPHA4</version>
    </dependency>
    
    HELP WANTED INPUT WANTED 
    opened by tipsy 47
  • Enable Mockito Tests: An Interface for Context

    Enable Mockito Tests: An Interface for Context

    If Context would be an interface instead of a class, it could easily be mocked in unit tests.

    My router delegates certain paths to controllers that have methods which only take a Context object. If this would be an interface, I could mock it and only unit test my controller in isolation.

    All the test examples I have found in this repository use full integration test that I would like to avoid (at least for my controller unit tests).

    opened by grote 46
  • Brackets based parser (fixes #667)

    Brackets based parser (fixes #667)

    This is a brackets based parser as described in #667.

    Currently the new parser is not supported in the OpenApi DSL. I added a small abstraction layer to the path parser creation. The interface only contains the public methods for now.

    Implementation details

    • Brackets are forbidden as part of a parameter name but wildcards are allowed
    • Brackets are counted for each segment separately to provide an early way out
    • Wildcards cannot be directly adjacent to a path parameter. Otherwise /*{hi} would behave differently from /{hi}*. In the second case the path parameter would only accept a single character.

    I am unsure on how to adapt the OpenApiDsl to the new bracket parser. Might extend the interface with the internal variables required. Some parts would need to be adopted to deal with the new MultipleSegments class in PathSegment2.

    I look forward to feedback.

    opened by Playacem 42
  • Javalin 3.0 suggestions and feature request

    Javalin 3.0 suggestions and feature request

    Feel free to discuss Javalin 3.0 in this issue.

    Please create new issues if you have specific requests.

    The current milestone (roadmap) can be seen here: https://github.com/tipsy/javalin/milestone/7

    Current changelog: https://github.com/tipsy/javalin/compare/dbf20902ebe2e0d3d0a3f0a2d1545fca3d59ac45...HEAD

    Javalin 2.8.X will receive security updates when 3.0 is out, but no new features.

    Alpha/beta builds available at: https://javalin.io/future/documentation

    Progress

    Misc

    • [x] Rewrite configuration setup
    • [x] Remove old validation methods and simplify Validator classes
    • [x] Make routing case sensitive
    • [x] Let FileRenderer throw exception
    • [x] Add config option: asyncRequestTimeout
    • [x] Add config option: enforceSsl
    • [x] Rework event system
    • [x] Rework package structure
    • [x] Consider publishing a javalin-servlet separately (rejected)
    • [x] Expose JavalinServlet in a better way
    • [x] OpenAPI/Swagger support

    WebSocket

    • [x] Simplify WebSocket API (make all websockets take a WsContext)
    • [x] Add WebSocket AccessManager
    • [x] Add to/from JSON to WebSocket methods
    • [x] Human-readable method names for WebSocket interfaces
    • [x] Add cookies to WsContext
    • [x] Add attributes to WsContext
    • [x] Sync WsContext and Context APIs (use Context proxy)
    • [x] Add wsBefore/wsAfter and wsException
    opened by tipsy 37
  • Validation functionality (discussion, input wanted)

    Validation functionality (discussion, input wanted)

    I'm considering including some functionality for validating user input. Typical things that need to be validated are:

    ctx.pathParam("user-id")
    ctx.queryParam("isbn")
    ctx.formParam("username")
    

    You could potentially include the validate function on the Context:

    val isbn = ctx.validate(Param.QUERY, "isbn").matches(isbnRegex).get() ?: throw BadRequestResponse()
    val username = ctx.validate(Param.FORM, "username").minLength(5).get() ?: throw BadRequestResponse()
    

    But since there are a lot of possible entry points, a general validation function (util) would probably be better?

    val isbn = validate(ctx.queryParam("isbn")).matches(isbnRegex).get() ?: throw BadRequestResponse()
    val username = validate(ctx.formParam("username")).minLength(5).get() ?: throw BadRequestResponse()
    

    This issue is intended for discussion. Should the functionality be included? If yes, how should it work?

    HELP WANTED INPUT WANTED 
    opened by tipsy 37
  • Create simple JMH performance test suite

    Create simple JMH performance test suite

    It would be nice if we could test the differences in performance between different Javalin versions. We could create a simple test setup like this: https://github.com/orangy/http-benchmarks

    Things to include:

    • Simple Hello World
    • Responses of different lengths (and compressions), both static and dynamic
    • Uploads
    • Methods that parse information from requests

    Things not to include

    • WebSockets
    • JSON serialization
    HELP WANTED 
    opened by tipsy 35
  • Upgrade to Jetty 11

    Upgrade to Jetty 11

    When moving to Jetty 11, a lot of code will have to be rewritten. If we are to move back to Java, this would be the time.

    Edit: This ticket contains some discussion on moving from Kotlin back to Java, but we have decided to not do that as part of the Jetty 11 change.

    INPUT WANTED 
    opened by tipsy 34
  • Add brotli compression

    Add brotli compression

    Describe the feature Add brotli compression to Javalin.

    Additional context We should probably also rename the current configuration (.disableDynamicGzip()) to something along the lines of

    dynamicCompression: true
    
    HELP WANTED FEATURE REQUEST GOOD FIRST ISSUE 
    opened by pkkummermo 34
  • GH-1385 Reimplement JavalinServlet to protect async request handling against race-conditions

    GH-1385 Reimplement JavalinServlet to protect async request handling against race-conditions

    Context

    • Discussion on Javalin's Discord server about a new possibilities of raising race condition vulnerabilities (continuation of spotted and reproduced #1385)

    Resolves

    • Fix https://github.com/tipsy/javalin/issues/1385 - the root of the problem, fixes internals to properly handle presented scenarios, but still exposes user to potential race condition side-effects and maybe even more that we still didn't find out
    • Resolves https://github.com/tipsy/javalin/issues/1278 - overall better async support as it's currently dangerous to any concurrent env, espeically with tools like Loom or Kotlin Coroutines
    • Resolves https://github.com/tipsy/javalin/issues/1402 - enhanced async handling, improved api (consistent - removed some runtime flags that forbidden future result handling in before/async context)

    About

    Reimplemented JavalinServlet reuses previous logic and imitates behaviors described by tests. Flow implementation may look complicated for the first time, but in the end it's just a recursive iteration over 2 queues to provide lazy creation of a new phase of request lifecycle. PR adds ~150 new lines, but like half of them is just a cost of spacing & moving request handling to standalone class.

    Pros:

    • Uses persistent future container for each scope and guarantees future completion
    • Separates request lifecycle from request handling
    • Supports future result handling by each handler (by design)
    • Provides more detailed description of request lifecycle

    Cons:

    • ~I don't quite like the idea of 2 queues, might be improved in the future.~ resolved
    • Ported error handling looks kinda dirty and I think it could be simplified in the future, but I don't really want to play about this topic right, especially that it could affect compatibility and it should be a topic of another issue
    • Obviously might be slightly slower, but it shouldn't be a problem (future stage per handler + one queue). It's natural cost of concurrent layer

    Extra

    1. ~New implementation does not enable async handling in before & after routes (other scopes) yet, but makes it possible. Anyway, such a change could be a topic of another issue.~ Well, I've already enabled it as I'm using Javalin based on this branch for 2 months already, because imo it's just more stable and safe impl than the official release.
    2. Not sure if async pipeline should use async timeout per each layer or whole queue (currently the second one). Should be discussed during (*1)
    opened by dzikoysk 33
  • Improvements to Validation API!

    Improvements to Validation API!

    This is issue is for suggesting improvements to the Javalin's validation API (Validator/Rule classes)

    To consider:

    • Allow Nullable Types to Be Processed By Validator (https://github.com/tipsy/javalin/issues/991)
    • Allow custom validation errors and validation rules overriding (https://github.com/tipsy/javalin/issues/993)
    • Add validator method returning default value (https://github.com/tipsy/javalin/pull/835)
    HELP WANTED INPUT WANTED 
    opened by tipsy 33
  • Investigate virtual threads implementation for http thread-pool

    Investigate virtual threads implementation for http thread-pool

    Using Loom's virtual threads as a default thread-pool for Javalin might not be the best idea for several reasons, tl;dr it's not straightforward replacement for old thread-pools or reactive programming.

    • Memory - Virtual threads are not free, an uncontrolled number of virtual threads can exhaust heap, so such implementation should control number of processed requests.
    • CPU - Executing cpu-sensitive (no blocking I/O calls) requests on smaller thread-pool will significantly reduce overall application performance.

    Current implementation of Loom in Javalin is in my opinion quite wrong, because it exposes virtual thread directly to the world without any limits:

    • https://github.com/javalin/javalin/blob/68ee4742e4b39c5656d04207d08c8c9a1c4f087f/javalin/src/main/java/io/javalin/util/ConcurrencyUtil.kt#L56-L65

    Because of that and the fact that in general it should not be treated as replacement to the old approach, I think we should start by not enforcing Loom as default if it's available:

    https://github.com/javalin/javalin/blob/68ee4742e4b39c5656d04207d08c8c9a1c4f087f/javalin/src/main/java/io/javalin/util/ConcurrencyUtil.kt#L18-L19

    Jetty provides preview implementation of Loom for QueuedThreadPool, but we should investigate if it respects all limits defined by QueuedThreadPool. If not, we should somehow create such API if we want to support Loom directly in Javalin, so user can set those limits and control Loom at some point.

    The general recommendation is to investigate Loom in various aspects in terms of usage with Javalin and test how it really works in various environments and if it really provides anything in term of benefits. Atm for me it should be only used by users that are aware of the way it works and they're intentionally working on infrastructure around that, every other user should still relay on regular QueuedThreadPool used by Javalin for years as it's just fine for most users.

    Related discussion on Discord:

    1. https://discord.com/channels/804862058528505896/957002566728835073/1058059076111700028
    opened by dzikoysk 0
  • Errors deleting multipart tmp files

    Errors deleting multipart tmp files

    Hello. On Windows we found this bug with jetty.

    2022-12-09 18:27:47 WARN Request:1472 - Errors deleting multipart tmp files java.lang.RuntimeException: java.io.IOException: Could Not Delete File at org.eclipse.jetty.util.MultiException.ifExceptionThrowRuntime(MultiException.java:148) at org.eclipse.jetty.server.MultiPartFormInputStream.delete(MultiPartFormInputStream.java:463) at org.eclipse.jetty.server.MultiPartFormInputStream.deleteParts(MultiPartFormInputStream.java:438) at org.eclipse.jetty.server.MultiParts$MultiPartsHttpParser.close(MultiParts.java:101) at org.eclipse.jetty.server.Request.onCompleted(Request.java:1468) at org.eclipse.jetty.server.HttpChannel.onCompleted(HttpChannel.java:966) at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:485) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:282) at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314) at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100) at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53) at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:421) at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:390) at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:277) at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.lambda$new$0(AdaptiveExecutionStrategy.java:139) at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:411) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:933) at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1077) at java.base/java.lang.Thread.run(Thread.java:834) Caused by: java.io.IOException: Could Not Delete File at org.eclipse.jetty.server.MultiPartFormInputStream$MultiPart.delete(MultiPartFormInputStream.java:328) at org.eclipse.jetty.server.MultiPartFormInputStream$MultiPart.cleanUp(MultiPartFormInputStream.java:339) at org.eclipse.jetty.server.MultiPartFormInputStream.delete(MultiPartFormInputStream.java:450) ... 17 more

    BUG 
    opened by osivinyuk 5
  • error using NullSessionCache

    error using NullSessionCache

    Actual behavior (the bug) I upgraded javalin to 5.0.1 but it shows me some errors regarding NullSessionCache session. The error is shown when I use NullSessionCache and if I use DEfaultSessionCache the error is gone. Previously with version 4.6.6 it did not show me the errors but I updated the project to 5.0.1 and I started to have these errors

    Log error

    [JettyServerThreadPool-22] WARN org.eclipse.jetty.server.session.SessionHandler - Unable to release Session Session@1b9e4c47{id=node0jmzq6nhemx001phi4ch6qhluc0,x=node0jmzq6nhemx001phi4ch6qhluc0.node0,req=0,res=true}
    java.sql.SQLException: deadlock; update conflicts with concurrent update; concurrent transaction number is 32919 [SQLState:40001, ISC error code:335544336]
        at org.firebirdsql.gds.ng.FbExceptionBuilder$Type$1.createSQLException(FbExceptionBuilder.java:539)
        at org.firebirdsql.gds.ng.FbExceptionBuilder.toFlatSQLException(FbExceptionBuilder.java:304)
        at org.firebirdsql.gds.ng.wire.AbstractWireOperations.readStatusVector(AbstractWireOperations.java:140)
        at org.firebirdsql.gds.ng.wire.AbstractWireOperations.processOperation(AbstractWireOperations.java:204)
        at org.firebirdsql.gds.ng.wire.AbstractWireOperations.readSingleResponse(AbstractWireOperations.java:171)
        at org.firebirdsql.gds.ng.wire.AbstractWireOperations.readResponse(AbstractWireOperations.java:155)
        at org.firebirdsql.gds.ng.wire.AbstractFbWireDatabase.readResponse(AbstractFbWireDatabase.java:211)
        at org.firebirdsql.gds.ng.wire.version10.V10Statement.execute(V10Statement.java:329)
        at org.firebirdsql.jdbc.AbstractPreparedStatement.internalExecute(AbstractPreparedStatement.java:538)
        at org.firebirdsql.jdbc.AbstractPreparedStatement.executeUpdate(AbstractPreparedStatement.java:188)
        at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)
        at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java)
        at org.eclipse.jetty.server.session.JDBCSessionDataStore.doUpdate(JDBCSessionDataStore.java:786)
        at org.eclipse.jetty.server.session.JDBCSessionDataStore.doStore(JDBCSessionDataStore.java:712)
        at org.eclipse.jetty.server.session.AbstractSessionDataStore.lambda$store$2(AbstractSessionDataStore.java:191)
        at org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1447)
        at org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1484)
        at org.eclipse.jetty.server.session.SessionContext.run(SessionContext.java:87)
        at org.eclipse.jetty.server.session.AbstractSessionDataStore.store(AbstractSessionDataStore.java:202)
        at org.eclipse.jetty.server.session.AbstractSessionCache.release(AbstractSessionCache.java:564)
        at org.eclipse.jetty.server.session.SessionHandler.complete(SessionHandler.java:358)
        at org.eclipse.jetty.server.Request.lambda$leaveSession$0(Request.java:424)
        at org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1465)
        at org.eclipse.jetty.server.Request.leaveSession(Request.java:424)
        at org.eclipse.jetty.server.Request.onCompleted(Request.java:1460)
        at org.eclipse.jetty.server.HttpChannel.onCompleted(HttpChannel.java:966)
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:485)
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:282)
        at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314)
        at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)
        at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
        at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:421)
        at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:390)
        at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:277)
        at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.lambda$new$0(AdaptiveExecutionStrategy.java:139)
        at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:411)
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:933)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1077)
        at java.base/java.lang.Thread.run(Thread.java:829)
    Caused by: org.firebirdsql.jdbc.FBSQLExceptionInfo: deadlock
    

    Expected behavior I expected NullSessionCache to still work as good as version 4.6.6

    To Reproduce javalin 5.0.1 implements session as follows

    fun sqlSessionHandler() = SessionHandler().apply {
        sessionCache = NullSessionCache(this).apply {
            sessionDataStore = JDBCSessionDataStoreFactory().apply {
                setDatabaseAdaptor(DatabaseAdaptor().apply {
                    //setDriverInfo(SVR_CONF.jdbcDriver, SVR_CONF.dbSessionURL)
                    datasource = HikariCP.dataSource()
                })
            }.getSessionDataStore(sessionHandler)
        }
        httpOnly = true
    }
    
    

    Additional context Possible issue upgrading jetty 9.x to 11.x on javalin 5.0.1

    opened by Gugu04 2
  • Improve techempower benchmark

    Improve techempower benchmark

    So, Javalin is back here: https://www.techempower.com/benchmarks/#section=data-r21&l=zik0vz-6bj&test=composite

    But it's not looking so fast. Maybe we can fix that?

    The repo for the benchmark code is here: https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/Java/javalin

    Some things we should do:

    • [x] Update to newest Javalin
    • [x] Replace Pebble with JTE and precompiled templates
    • [x] Remove before/after/error stages from request lifecycle
    • [x] Cleanup database controller
    • [x] Use custom JSON setup
    • [ ] Enable Loom via --enable-preview and Java 19
    • [ ] Copy DB stuff from vertx or jooby?
    • [ ] ~Enable HTTP2~ (not supported by wrk)
    • [ ] ~See if we can make Jackson faster~

    Here is our branch: https://github.com/javalin/FrameworkBenchmarks/tree/javalin-improvements

    opened by tipsy 27
  • Who's using Javalin?

    Who's using Javalin?

    We have a "Who's using Javalin?" section on the webpage. The initial list is based on publicly available information from GitHub/Gitlab, Maven, and user websites:

    image

    ⚠️ If you want your company added to the list, please comment on this issue.

    Not all companies can be added - The bigger and/or more noble your company/project is, the better your chances are :)

    This issue replaces https://github.com/javalin/javalin.github.io/issues/18 from the website repo

    opened by tipsy 3
Owner
David (javalin.io)
Creator of https://javalin.io (https://github.com/tipsy/javalin)
David (javalin.io)
The modular web framework for Java and Kotlin

∞ do more, more easily Jooby is a modern, performant and easy to use web framework for Java and Kotlin built on top of your favorite web server. Java:

jooby 1.5k Dec 16, 2022
Firefly is an asynchronous web framework for rapid development of high-performance web application.

What is Firefly? Firefly framework is an asynchronous Java web framework. It helps you create a web application Easy and Quickly. It provides asynchro

Alvin Qiu 289 Dec 18, 2022
An evolving set of open source web components for building mobile and desktop web applications in modern browsers.

Vaadin components Vaadin components is an evolving set of high-quality user interface web components commonly needed in modern mobile and desktop busi

Vaadin 519 Dec 31, 2022
Ninja is a full stack web framework for Java. Rock solid, fast and super productive.

_______ .___ _______ ____. _____ \ \ | |\ \ | | / _ \ / | \| |/ | \ | |/ /_\ \ / | \

Ninja Web Framework 1.9k Jan 5, 2023
ZK is a highly productive Java framework for building amazing enterprise web and mobile applications

ZK ZK is a highly productive Java framework for building amazing enterprise web and mobile applications. Resources Documentation Tutorial ZK Essential

ZK 375 Dec 23, 2022
A web MVC action-based framework, on top of CDI, for fast and maintainable Java development.

A web MVC action-based framework, on top of CDI, for fast and maintainable Java development. Downloading For a quick start, you can use this snippet i

Caelum 347 Nov 15, 2022
A server-state reactive Java web framework for building real-time user interfaces and UI components.

RSP About Maven Code examples HTTP requests routing HTML markup Java DSL Page state model Single-page application Navigation bar URL path UI Component

Vadim Vashkevich 33 Jul 13, 2022
Vaadin 6, 7, 8 is a Java framework for modern Java web applications.

Vaadin Framework Vaadin allows you to build modern web apps efficiently in plain Java, without touching low level web technologies. This repository co

Vaadin 1.7k Jan 5, 2023
Apache Wicket - Component-based Java web framework

What is Apache Wicket? Apache Wicket is an open source, java, component based, web application framework. With proper mark-up/logic separation, a POJO

The Apache Software Foundation 657 Dec 31, 2022
Micro Java Web Framework

Micro Java Web Framework It's an open source (Apache License) micro web framework in Java, with minimal dependencies and a quick learning curve. The g

Pippo 769 Dec 19, 2022
True Object-Oriented Java Web Framework

Project architect: @paulodamaso Takes is a true object-oriented and immutable Java8 web development framework. Its key benefits, comparing to all othe

Yegor Bugayenko 748 Dec 23, 2022
An Intuitive, Lightweight, High Performance Full Stack Java Web Framework.

mangoo I/O mangoo I/O is a Modern, Intuitive, Lightweight, High Performance Full Stack Java Web Framework. It is a classic MVC-Framework. The foundati

Sven Kubiak 52 Oct 31, 2022
The Grails Web Application Framework

Build Status Slack Signup Slack Signup Grails Grails is a framework used to build web applications with the Groovy programming language. The core fram

grails 2.7k Jan 5, 2023
jetbrick web mvc framework

jetbrick-webmvc Web MVC framework for jetbrick. Documentation http://subchen.github.io/jetbrick-webmvc/ Dependency <dependency> <groupId>com.githu

Guoqiang Chen 25 Nov 15, 2022
🚀 The best rbac web framework. base on Spring Boot 2.4、 Spring Cloud 2020、 OAuth2 . Thx Give a star

?? The best rbac web framework. base on Spring Boot 2.4、 Spring Cloud 2020、 OAuth2 . Thx Give a star

pig-mesh 4.3k Jan 8, 2023
RESTEasy is a JBoss project that provides various frameworks to help you build RESTful Web Services and RESTful Java applications

RESTEasy RESTEasy is a JBoss.org project aimed at providing productivity frameworks for developing client and server RESTful applications and services

RESTEasy 1k Dec 23, 2022
Java Web Toolkit

What is JWt ? JWt is a Java library for developing web applications. It provides a pure Java component-driven approach to building web applications, a

null 48 Jul 16, 2022
:rocket: Lightning fast and elegant mvc framework for Java8

Based on Java8 + Netty4 to create a lightweight, high-performance, simple and elegant Web framework ?? Spend 1 hour to learn it to do something intere

Blade Framework 5.7k Dec 28, 2022
:rocket: Lightning fast and elegant mvc framework for Java8

Based on Java8 + Netty4 to create a lightweight, high-performance, simple and elegant Web framework ?? Spend 1 hour to learn it to do something intere

Blade Framework 5.7k Jan 5, 2023