layout | title | rightmenu | permalink |
---|---|---|---|
default |
Migration guide, v4 to v5 |
false |
/migration-guide-javalin-4-to-5 |
The most significant change is that Javalin no longer supports Java 8, with Java 11 being the new minimum version. This is because Jetty 9 (what Javalin has been running on since 2017) has been end-of-lifed, and later Jetty versions require Java 11. Jetty 11 is the latest stable version of Jetty.
Javalin used to live as a personal project at github.com/tipsy/javalin
, but it has now been moved into an
organization at github.com/javalin/javalin
. All old links/remotes redirect, everything works as before.
The core
package has been removed, flattening the package structure of Javalin.
Some other things have also been moved around.
// core package
import io.javalin.core.compression -> import io.javalin.compression
import io.javalin.core.config -> import io.javalin.config
import io.javalin.core.event -> import io.javalin.event
import io.javalin.core.security -> import io.javalin.security
import io.javalin.core.util -> import io.javalin.util
import io.javalin.core.util.Header -> import io.javalin.http.Header
// plugin package
import io.javalin.plugin.rendering.vue -> import io.javalin.vue
import io.javalin.plugin.json -> import io.javalin.json
The HttpCode
enum class has been renamed to HttpStatus
.
Configuration has been changed significantly. All config options used to be available
directly on the config consumer in Javalin.create { config }
, but in Javalin 5 most
of the old config options have been moved into subconfigs. You can find the full overview at
/documentation#configuration.
Context
is now an interface (you can get access to internal functionality by casting toJavalinServletContext
)ctx.req
andctx.res
are nowctx.req()
andctx.res()
ctx.cookieStore#
is nowctx.cookieStore()#
ctx.seekableStream()
is nowctx.writeSeekableStream()
ctx.resultString()
is nowctx.result()
,ctx.resultStream()
is nowctx.resultInputStream()
ctx.resultFuture()
has been removed (see more in the "Future rework" section)- In Kotlin, the reified
xyzAsClass
functions now have to be imported (sinceContext
is now an interface)
In Javalin 4 we had Context#future(future, callback)
,
which has been changed to Context#future(futureSupplier)
. The recommended
way to use futures in Javalin 5 is to lean on the CompletableFuture
API and
call Javalin's Context
methods in those callbacks:
{% capture java %} app.get("/", ctx -> ctx.future(() -> myFuture .thenAccept(result -> ctx.result(result)) .exceptionally(error -> ctx.result("Error: " + error)) ); }); {% endcapture %} {% capture kotlin %} app.get("/") { ctx -> ctx.future { myFuture.thenAccept { ctx.result(it) } myFuture.exceptionally { ctx.result("Error: " + it) } } } {% endcapture %} {% include macros/docsSnippet.html java=java kotlin=kotlin %}
In Javalin 4, clients weren't automatically closed, this allowed people to keep lists of clients outside of the handler.
But in Javalin 5 we're no longer blocking connections by default for SSE clients, so you have to explicitly enable it using SseClient#keepAlive()
if you want to restore old behavior.
{% capture java %} ArrayList clients = new ArrayList<>();
app.sse("/sse", client -> { client.keepAlive(); client.onClose(() - > clients.remove(client)); clients.add(client); }); {% endcapture %} {% capture kotlin %} val clients = mutableListOf()
app.sse("/sse") { client -> client.keepAlive() client.onClose { clients.remove(client) } clients.add(client) } {% endcapture %} {% include macros/docsSnippet.html java=java kotlin=kotlin %}
The _conf.inner
field has been renamed to cfg.pvt
(config private) to
further discourage use. It's still okay to use it (if you know what you are doing).
The main javalin/javalin
repo has been on a diet, and a lot of things have been moved out.
A few things have been removed altogether.
The OpenAPI DSL and reflection based annotation API (javalin-openapi
module) has been replaced by a
new annotation processor based project by a very talented
new Javalin contributor, @dzikoysk, who is also the author
of Reposilite (repo, website).
Reposilite is currently running both
Javalin v5 and Javalin OpenAPI v5 in production.
This new OpenAPI plugin should have significantly fewer issues than the old module!
All template engines have been moved to a separate javalin-rendering
artifact.
To use template engines in Javalin 5 you have to add this dependency, and call MyTemplateEngine.init()
,
which will make the template engine register itself on JavalinRenderer
with the proper extension.
You could also call JavalinRender.register(engine, extension...)
manually.
Related to the Jetty 11 change, the MicrometerPlugin
has been removed. This had to be done because
Micrometer does not support Jetty 11:
micrometer-metrics/micrometer#3234
It will hopefully return (to the core) soon!
- The
javalin-graphql
artifact might be re-released undercommunity
sub-group in the future. - The
javalin-without-jetty
artifact hopefully won't return, but if it does... it will be under thecommunity
sub-group) - The
javalin-osgi
artifact can return to the core as soon as someone makes a PR.
The JavalinVue
singleton has been removed. Instead of JavalinVue.configOption = ...
,
you can now configure Vue through Javalin.create { config.vue.configOption = ... }
.
The CORS plugin has been completely rewritten to be more flexible. Instead of the two methods
enableCorsForAllOrigins()
and enableCorsForOrigin(@NotNull String... origins)
on the config object you now pass a
lambda to config.plugins.enableCors()
to configure CORS.
{% capture java %} Javalin.create(config -> { config.plugins.enableCors(cors -> { cors.add(corsConfig -> { // replacement for enableCorsForOrigin(@NotNull String... origins) corsConfig.allowHost(/* add your origins here */); //replacement for enableCorsForAllOrigins() corsConfig.anyHost(); }); });
}).start(); {% endcapture %} {% capture kotlin %} Javalin.create { config -> config.plugins.enableCors { cors -> cors.add { corsConfig -> //replacement for enableCorsForOrigin(@NotNull String... origins) corsConfig.allowHost(/* add your origins here */) //replacement for enableCorsForAllOrigins() corsConfig.anyHost() } } }.start() {% endcapture %} {% include macros/docsSnippet.html java=java kotlin=kotlin %}
Check out the CORS plugin page for more details on the rewritten CORS plugin and its capabilities.
It's hard to keep track of everything, but you can look at the full commit log between the last 4.x version and 5.0.
If you run into something not covered by this guide, please edit this page on GitHub!