Below is a list of changes since Lift 3.0 organized by the type of change and sorted by the PR number.
Formats
object with tuplesAsArrays
set to true. The one caveat with this functionality is that it doesn't consistently support Scala primitives, so if you're using tuples inside a larger, more complex structure you'll want to use the Java boxed types instead of Scala primitives where applicable (so, java.lang.Integer
instead of Int
). However, if the tuple contains case classes you should be able to use primitives inside those without issue: this caveat only affects primitives directly in the tuple. The README for lift-json documents all of this, and Matt Farmer wrote a blog post demonstrating it in a more narrative style if that's more your thing.RestHelper
, folks would find themselves firing off futures that needed to do i18n or something else that required session access, only to have that session context missing when the future actually executed. @pdyraga added a new helper, LAFutureWithSession.withCurrentSession
, aliased as S.sessionFuture
, which can be used to create an LAFuture
task that has access to the session. There is a similar helper, FutureWithSession.withCurrentSession
, that will spawn a task as a Scala Future
with access to the session. The resulting futures can be chained and combined with other futures and will preserve their session access. This includes all APIs in Scala's Future
in Scala 2.12, as well.NaN
, PositiveInfinity
, and NegativeInfinity
as their respective string values (NaN
, -Infinity
, Infinity
). This is actually not correct JSON, as these are not supported JSON numeric values. Many if not most JSON parsers will choke on this output, including browser parsers. One notable exception is if anyone is eval
ing JSON as JavaScript directly---but this is a very unsafe practice. As of M3, we default to rendering these as null
instead, and provide a new RenderSettings
customization that allows you to switch back to the old rendering approach, or to switch to an approach that throws an exception if these special values are found (which can be paired with tryo
to produce a Failure
in these cases).BoxLogging
helpers. The new BoxLogging
helper provides functions for logging boxes and then continuing to operate on the box, allowing logging to become a fluent part of the Box
interaction. It provides methods that can allow for logging empties and failures, or just failures. It also allows logging these to different log levels, and allows for different adapters to be applied.liftVanilla.onEvent
returned false, we'd just return that value. Now, we now check for the existence of event.preventDefault
and trigger it and stopPropagation
if the handler returned false
. We also return that return that false
value for older browsers to work with.lift-json
has gained significant parser performance improvements, and is now competitive with the jawn parser in most of jawn's microbenchmarks, making it one of the fastest Scala JSON parsers across a variety of parsing scenarios.*Async
methods on the MongoDB record implementation that will return Future
s to the calling code, meaning you can now easily compose Mongo Record operations with other non-blocking code. Hat tip to @eltimn and @marekzebrowski for their work on this.FileInputStream
and FileOutputStream
usage. @eltimn moved much of Lift's internal usage of FileInputStream
and FileOutputStream
to their more GC-friendly java.nio
equivalents. See this Cloudbees post for the GC impact of the old streams. This change should have no impact on your code. If you find yourself having to recompile your code to work with this change, please let us know on the mailing list, as this is meant to be a purely internal change.liftVanilla
provider of JavaScript functionality on the client with an eye towards removing the Lift jQuery dependency; unfortunately, that provider was somewhat incomplete. Amongst other things, loading it still required having jQuery loaded, or at least defined. We've removed this dependency now, and continue to work to make liftVanilla
a fully functional replacement for the jquery-dependent functionality needed for core Lift operations.Class
instance we use for a particular type hint instead of invoking a class lookup each time.fixHtmlFunc
. JsExp
s that handle HTML go through fixHtmlFunc
, which is charged with preprocessing any embedded JS so it can be served correctly for client interpretation. Unfortunately, the interaction between this preprocessing and event extraction led to some broken and unexpected behavior. We're reasoning through a deeper fix, but in the meantime even when LiftRules.extractInlineJavaScript
is enabled, fixHtmlFunc
will not do event extraction.buildDeferredFunction
.Sometimes S.req
returns a Req
without a servlet HTTPRequest
inside. Ergo, when code would call HttpRequest.snapshot
in Req.snapshot
, we would get a NullPointerException
. To fix this, we modify currentReq
in both definitions of buildDeferredFunction
so that they filter out null requests. Shout out to first-time contributor @arigoldx!UnavailableException
in boot. This code adds special handling for javax.servlet.UnavailableException
. Previously, if this exception was thrown during boot, we'd swallow it because we swallowed all exceptions during boot. However, this exception is an idiomatic way to signal a full abort to the Java Application Server running the application. From now on, we will log and re-throw this exception if we see it.collect
or collectAll
would cause the overall future to hang forever. We now properly fail the overall future if any contained future fails.