Releases: lift/framework
Lift Framework 3.3.0-M2
The Lift Committers are pleased to announce the release of Lift 3.3.0-M2 on April 14th, 2018. This release is the second of three milestone releases for Lift 3.3.0. The next milestone release is tentatively scheduled for June 1st, 2018. As always, you can follow along with our progress in the GitHub Milestone View.
Please read below for the changes in this milestone.
Changes
BREAKING CHANGES
It is rare for Lift to decide to ship what amounts to a breaking change in a minor point release. However, during this release cycle we discovered a bug in the implementation of LAFuture
that resulted in the aborted_?
check method not working as users expect. Unbeknownst to us, the aborted_?
check method was looking at the satisfied
internal state setting instead of the aborted
internal state setting. This meant that satisfied_?
and aborted_?
always returned the same result even though they were not the same internal state.
With a lot of consideration, we decided to correct the behavior in Lift 3.3.0 in Pull Request #1940, because it never worked as advertised and the expected impact to user code is that it starts working as the user intended. We are not going to backport this change to avoid user code behavior changing on a patch release.
New Features
(#1933) Configurable asset path for Lift-specific assets
By default, Lift will attempt to load an AJAX Spinner gif when doing certain server-to-client operations. Some folks turn this off, but it remains one of the niceties that folks can lean on when waiting on the server and the client to finish talking to each other. Historically, Lift has insisted that for this feature to work the ajax gif must be located at /images/ajax-loader.gif
, however not everyone wants to lay out their application in that fashion.
There is a new lift rule located at LiftRules.assetRootPath
that makes the location of your assets configurable. Its default value is /
, which preserves the existing behavior. You can, however, make it whatever you like.
You could put your AJAX loader at /assets/images/ajax-loader.gif
. You could put it between two slices of bread. You could put it on Amazon S3, instead. You'll be amazed at the places you can put this gif, if you only use your head.
Many thanks to @heharkon!
(#1939) Customizable Service Timers
Many folks using Lift are familiar with the classic timer log messages that appear by default to tell you how long each request in Lift is taking. By default they tend to look like this:
INFO net.liftweb.util.TimeHelpers - Service request (GET) / returned 200, took 455 Milliseconds
Lift now provides the ability to implement custom timing methods through the implementation of the ServiceRequestTimer
trait. Using a ServiceRequestTimer
you can:
- Control how messages are timed.
- Control where that timing information gets reported.
You could, for example, report all request timings to a metrics aggregator and graph the various percentiles of response times as a part of your monitoring. You could only time a subset of requests (those testing newer functionality, for example).
These changes provide a new LiftRules.installServiceRequestTimer
function to install the timer of your choice. net.liftweb.http.StandardServiceTimer
implements the current behavior. Further, the LiftRules.logServiceRequestTiming
is now deprecated and will be removed in Lift 4 in favor of installServiceRequestTimer
.
Many thanks to @andreak!
Improvements
- (#1846) @Shadowfiend's much anticipated in-repo getting started tutorial is now in
master
! Check it out - (#1940) Correction to
LAFuture.isAborted_?
and a variable allocation cleanup. Thank you to @zhongsigang - (#1942, #1945) Deprecated our internal BCrypt implementation in lift-util in favor of using the publicly-available jBCrypt library.
net.liftweb.util.BCrypt
was just a copy/paste of version 0.3 of jBCrypt. It is now officially deprecated and is now simply a proxy class toorg.mindrot.jbcrypt.BCrypt
.net.liftweb.util.BCrypt
will be removed in Lift 4.0. (h/t @eltimn) - (#1943) Upgraded the Mongo driver to 3.6.3 (h/t @eltimn)
- (#1944) Some code gardening courtesy of @eltimn!
About Lift
The Lift Framework is a mature, advanced framework for the modern software engineer. There are Seven Things that set Lift apart from the other frameworks out there today: it's secure-by-default, developer-centric, scalable, capable of rich interactive behavior, modular, and designer-friendly. If you're new to Lift or interested in checking out what these things mean, we recommend checking out Simply Lift and The Lift Cookbook.
The Lift Mailing List is also a good resource for anyone to ask questions or just meet other Lift users. The Lift README is a good resource for figuring out how to use Lift in your project.
Lift Framework 3.3.0-M1
The Lift Committers are pleased to announce the release of Lift 3.3.0-M1 on February 7th, 2018. This release is the first of three milestone releases for Lift 3.3.0. The next milestone release is tentatively scheduled for April 1st, 2018. As always, you can follow along with our progress in the GitHub Milestone View.
Please read below for the changes in this milestone.
Changes
Improvements
- (#1931) Some readme improvements courtesy of @kohrVid
- (#1935, #1936) Various performance improvements to lift-json courtesy of @chriswebster
- (#1938) Fixed issues with building the project in IntelliJ courtesy of @andreak
About Lift
The Lift Framework is a mature, advanced framework for the modern software engineer. There are Seven Things that set Lift apart from the other frameworks out there today: it's secure-by-default, developer-centric, scalable, capable of rich interactive behavior, modular, and designer-friendly. If you're new to Lift or interested in checking out what these things mean, we recommend checking out Simply Lift and The Lift Cookbook.
The Lift Mailing List is also a good resource for anyone to ask questions or just meet other Lift users. The Lift README is a good resource for figuring out how to use Lift in your project.
Lift Framework 3.2.0
The Lift Committers are pleased to announce the release of Lift 3.2.0 on January 27th, 2018. This release continues our new release cadence. This release has no code changes from the 3.2.0-RC1 release.
The Lift 3.2.0 release makes many notable improvements, but the biggest single theme throughout all the changes is that of improvement of Lift's failover and clustering story. This release, coupled with @joescii's lift-cluster module represents a giant leap forward in Lift's scalability story.
About Lift
The Lift Framework is a mature, advanced framework for the modern software engineer. There are Seven Things that set Lift apart from the other frameworks out there today: it's secure-by-default, developer-centric, scalable, capable of rich interactive behavior, modular, and designer-friendly. If you're new to Lift or interested in checking out what these things mean, we recommend checking out Simply Lift and The Lift Cookbook.
The Lift Mailing List is also a good resource for anyone to ask questions or just meet other Lift users. The Lift README is a good resource for figuring out how to use Lift in your project.
Changes
This release of Lift is composed of the following component releases:
Below is a list of changes since Lift 3.1 organized by the type of change and sorted by the PR number.
New Features
(#1770) Comet Rehydration
Since Comets were first introduced in Lift, it's been the case that if the Lift app server got restarted in the middle of a user's session and comets were involved then the user would need to refresh their entire page to reconnect to the server and have their comets start working again. By default, Lift is kind enough to do this page refresh for the users. However, this is a less than ideal experience for obvious reasons.
Now, after over a year's worth of work, @joescii has delivered Comet Rehydration to the Lift Framework.
Comet Rehydration is an optional feature that, when enabled, allows a user's browser to seamlessly reconnect to the comets on the server without needing to reload the page in many circumstances. In cases where significant changes have been delivered to an application, reloading the entire page may still be desirable. However, when deploying small bug fixes to users Comet Rehydration is a useful tool to do so without interrupting their experience in your application.
There are a couple of prerequisites to use rehydration effectively. Specifically,
- The
CometActor
s in your application should have a mechanism for reconstructing their intended state from cookies or by invoking methods on the client viaparitalUpdate
that will cause the client to transmit its current state to a new Comet. - If there is a significant amount of client-side JavaScript interacting with the comet, it would be advisable to version the RPC calls between the client and server so that the client knows when a full page reload is required. Such versions could be incremented to indicate changes in the protocol between the Comet and the browser or indicate that the browser needs to reload the page to fetch new JavaScript that the comet depends on (for example, a new version of jQuery).
We encourage all Lift developers to take a closer look at Comet Rehydration. We believe it will significantly improve the user experience for end-users of Lift applications when implemented with the prerequisites described above.
To start using rehydration, add the following to your Boot.boot
implementation:
LiftRules.enableCometRehydration()
(#1864) Add transform and flip methods to Box
Our Box
data type has learned a few new tricks.
The new transform
method allows callers to take a Box
and, via PartialFunction
, turn it into any other Box. If the PartialFunction
fails, the original Box is returned.
Some examples:
// Returns Full("alternative") because the partial function covers the case.
Full("error") transform {
case Full("error") => Full("alternative")
}
// Returns Full(1), this Full box unchanged, because the partial function doesn't cover the case.
Full(1) transform {
case Full(2) => Failure("error")
}
// Returns this Failure("another-error") unchanged because the partial function doesn't cover the case.
Failure("another-error") transform {
case Failure("error", Empty, Empty) => Full("alternative")
}
// Returns Full("alternative") for an Empty box since `partialFn` is defined for Empty
Empty transform {
case Empty => Full("alternative")
}
// Returns Empty because the partial function is not defined for Empty
Empty transform {
case Failure("error", Empty, Empty) => Full("alternative")
}
The new flip
method allows callers to take a Box
and, if it is an EmptyBox
(which is an Empty
or any sort of Failure
), flip it into a Full
with a specific type. If it is a Full
, an Empty
is returned.
Many thanks to @Bhashit for this contribution!
(#1866) New Optional Mongo Fields
@Bhashit made a number of additions to the optional mongo fields as a part of mongodb-record. Some fun additions that your code might benefit from include:
OptionalCaseClassField
OptionalJObjectField
OptionalUUIDRefField
OptionalObjectIdField
... and more! We've also deprecated some legacy field names and parameter names (e.g. rec
is now owner
) so you'll probably see some deprecation warnings crop up if you're using any of those.
(#1874) Support for HTTP patch method in RestHelper.
We now support the Patch
verb when using RestHelper
to build APIs. Also, as you would expect, there are XmlPatch
and JsonPatch
variants as there are with Get
, Post
, etc.
(#1893) ContainerVar serialization for anything Serializable
Lift has provided ContainerVar
for awhile for storing values in the underlying container session. (This is as opposed to the SessionVar
that stores things in Lift's session.) However, to use a ContainerVar
you need to provide some sort of ContainerSerializer
for the type that you're trying to serialize. Even though Lift has provided a handful of implementations for awhile, none of them would handle something as simple as Box[String]
.
@joescii was kind enough to add a ContainerSerializer
that works for anything extending Serializable
. This should give Lift developers using ContainerVar
a much more "batteries included" experience.
(#1906) Snippet Timers
Page loading slowly and you're not sure what code to blame? Want to just report all snippet timings to a metrics system for monitoring? Snippet Timers are for you! Snippet Timers enable global, per-request, or per-session timing of Snippet execution throughout your Lift application. By default, we package a LoggingSnippetTimer
that spits out these timings to the log system, but anything implementing the SnippetTimer
interface can be provided.
To get started you'll need to invoke LiftRules.installSnippetTimer
in Boot
to enable the feature. For example, to enable the logging snippet timer globally, just add the following line:
LiftRules.installSnippetTimer(LoggingSnippetTimer)
If you're only interested in logging in certain sessions or requests, you'll still need to invoke installSnippetTimer
at boot with the NoOpSnippetTimer
to enable the feature. Then, to enable logging snippet timing at some point in a request invoke:
LiftRules.snippetTimer.get.map(_.request(LoggingSnippetTimer))
The logging snippet timer will be enabled for the duration of the request. You can also do the same for a session.
LiftRules.snippetTimer.get.map(_.session(LoggingSnippetTimer))
Improvements
- During this release cycle, we also formalized our support policy.
- (#1865) Ensure the server/port combo of the original request is preserved. This resolves bug #1794, wherein our snapshotting of the underlying request object during some async operations was incomplete. This periodically caused misbehavior that broke the ability to retrieve the host and path of the request being handled by the async operations.
- (#1868) @Bhashit contributed some very nice documentation about Dependency Injection in Lift.
- (#1871) Bumped our logback version. This shouldn't affect applications using Lift directly, since we treat the logback dependency as something the application using Lift will provide. However, we do recommend that, if you haven't, you also upgrade to 1.2.3 or higher to resolve a security issue.
- (#1888, #1881) Various lift-json performance improvements.
- (#1889) Implementation of LiftRulesGuardedSetting. This type will eventually replace everything in
LiftRules
declared as avar
. The idea here is that we want to avoid folks from changing things inLiftRules
at runtime. We do that in a bit of an ad-hoc way now, in the sense that some settings will blow up in your face if you attempt to do so, but moving forward the `...
Lift Framework 3.2.0-RC1
The Lift Committers are pleased to announce the release of Lift 3.2.0-RC1 on December 16th, 2017. This release is the first (and hopefully last) release candidate for Lift 3.2.0. We encourage all Lift Framework users to bump their applications to this version as quickly as possible, and to give us feedback on how it works for you.
Please read below for the changes in this milestone.
Changes
New Features
(#1770) Comet Rehydration
Since Comets were first introduced in Lift, it's been the case that if the Lift app server got restarted in the middle of a user's session and comets were involved then the user would need to refresh their entire page to reconnect to the server and have their comets start working again. By default, Lift is kind enough to do this page refresh for the users. However, this is a less than ideal experience for obvious reasons.
Now, after over a year's worth of work, @joescii has delivered Comet Rehydration to the Lift Framework.
Comet Rehydration is an optional feature that, when enabled, allows a user's browser to seamlessly reconnect to the comets on the server without needing to reload the page in many circumstances. In cases where significant changes have been delivered to an application, reloading the entire page may still be desirable. However, when deploying small bug fixes to users Comet Rehydration is a useful tool to do so without interrupting their experience in your application.
There are a couple of prerequisites to use rehydration effectively. Specifically,
- The
CometActor
s in your application should have a mechanism for reconstructing their intended state from cookies or by invoking methods on the client viaparitalUpdate
that will cause the client to transmit its current state to a new Comet. - If there is a significant amount of client-side JavaScript interacting with the comet, it would be advisable to version the RPC calls between the client and server so that the client knows when a full page reload is required. Such versions could be incremented to indicate changes in the protocol between the Comet and the browser or indicate that the browser needs to reload the page to fetch new JavaScript that the comet depends on (for example, a new version of jQuery).
We encourage all Lift developers to take a closer look at Comet Rehydration. We believe it will significantly improve the user experience for end-users of Lift applications when implemented with the prerequisites described above.
To start using rehydration, add the following to your Boot.boot
implementation:
LiftRules.enableCometRehydration()
Bug Fixes
- (#1924) Correctly override list item markup in lift-markdown. This resolves an issue (#1810) where
InlineParser
would ignore custom decorators for list items. Thanks @ricsirigu for the fix! - (#1930) Added a null guard to address tests that touch stateful features. Resoles an issue (#1929) where an alarming, but harmless
NullPointerException
would occur in tests that destroy aLiftSession
. Hat tip to @joescii for spotting it and delivering the fix. - (#1928) Add a configurable
maxIdLength
to mongo-record's string primary keys. Previously this was hard-coded to 12.
Improvements
N/A
About Lift
The Lift Framework is a mature, advanced framework for the modern software engineer. There are Seven Things that set Lift apart from the other frameworks out there today: it's secure-by-default, developer-centric, scalable, capable of rich interactive behavior, modular, and designer-friendly. If you're new to Lift or interested in checking out what these things mean, we recommend checking out Simply Lift and The Lift Cookbook.
The Lift Mailing List is also a good resource for anyone to ask questions or just meet other Lift users. The Lift README is a good resource for figuring out how to use Lift in your project.
Lift Framework 3.2.0-M3
The Lift Committers are pleased to announce the release of Lift 3.2.0-M3 on November 16th, 2017. This release is the third of three milestone releases for Lift 3.2.0. The first release candidate is tentatively scheduled for December 15th, 2017 with plans to finalize Lift 3.2 around the end of the year. As always, you can follow along with our progress in the GitHub Milestone View.
Please read below for the changes in this milestone.
Changes
New Features
(#1864) Add transform and flip methods to Box
Our Box
data type has learned a few new tricks.
The new transform
method allows callers to take a Box
and, via PartialFunction
, turn it into any other Box. If the PartialFunction
fails, the original Box is returned.
Some examples:
// Returns Full("alternative") because the partial function covers the case.
Full("error") transform {
case Full("error") => Full("alternative")
}
// Returns Full(1), this Full box unchanged, because the partial function doesn't cover the case.
Full(1) transform {
case Full(2) => Failure("error")
}
// Returns this Failure("another-error") unchanged because the partial function doesn't cover the case.
Failure("another-error") transform {
case Failure("error", Empty, Empty) => Full("alternative")
}
// Returns Full("alternative") for an Empty box since `partialFn` is defined for Empty
Empty transform {
case Empty => Full("alternative")
}
// Returns Empty because the partial function is not defined for Empty
Empty transform {
case Failure("error", Empty, Empty) => Full("alternative")
}
The new flip
method allows callers to take a Box
and, if it is an EmptyBox
(which is an Empty
or any sort of Failure
), flip it into a Full
with a specific type. If it is a Full
, an Empty
is returned.
Many thanks to @Bhashit for this contribution!
Bug Fixes
- (#1923) Validate that no-arg comet constructor doesn't exist before attempting backup constructor. This fixes a long-standing bug in Lift regarding Comet instantiation. Previously, if you had a comet that threw an exception in it's no-argument constructor we would unintentionally swallow that exception and attempt the backup, comet info constructor. Then we'd complain to the developer that the comet info constructor didn't exist. We're now a bit smarter about how we handle those errors, and check the Exception that the no-arg instantiation returns. If it's anything other than a "no such method" Exception, we'll re-throw immediately instead of trying the comet info constructor.
Improvements
- (#1921) @joescii shipped some minor tweaks to support session serialization with lift-cluster.
- (#1908)
MetaProtoExtendedSession
cookies can now be restricted to the context path of your application. Or, really, any path you want - though we're skeptical restricting your cookies to/bananas
if your application isn't hosted at/bananas
would really be that useful.
About Lift
The Lift Framework is a mature, advanced framework for the modern software engineer. There are Seven Things that set Lift apart from the other frameworks out there today: it's secure-by-default, developer-centric, scalable, capable of rich interactive behavior, modular, and designer-friendly. If you're new to Lift or interested in checking out what these things mean, we recommend checking out Simply Lift and The Lift Cookbook.
The Lift Mailing List is also a good resource for anyone to ask questions or just meet other Lift users. The Lift README is a good resource for figuring out how to use Lift in your project.
Lift Framework 3.1.1
This is a bugfix release to Lift 3.1.0 to fix a few bugs that were introduced in the 3.0.0 release and discovered only recently. The bug fixes we've shipped are described below. Please let us know if on the Mailing List if you have any issues.
Fixes
- (#1917) Consider
LiftRules.cometCreation
when building comets. ThisLiftRule
became ignored by accident during the great comet upgrade of the 3.0 release. We've added the line back that was missing, and plan to back-port this fix to the 3.0 and the 3.1 series. - (#1915) Provide context path to session reload handler. There was a subtle change in behavior in Lift 3.0 that caused bad things to happen when a Lift application was deployed under a context path in an application server (so, somewhere other than
/
) and that Lift application detected that the comet session had disappeared. In previous versions of Lift this would just reload the page. In Lift 3.0, we changed that behavior to take you to the root of your application. However,/
is not always the root of the application. Now, we'll properly consider the context path when detecting what URL to send you to. This is, as always, customizable withLiftRules.noCometSessionCmd
.
Lift Framework 3.0.2
This is a bugfix release to Lift 3.0.1 to fix a few bugs that were introduced in the 3.0.0 release and discovered only recently. The bug fixes we've shipped are described below. Please let us know if on the Mailing List if you have any issues.
Fixes
- (#1916) Consider
LiftRules.cometCreation
when building comets. ThisLiftRule
became ignored by accident during the great comet upgrade of the 3.0 release. We've added the line back that was missing, and plan to back-port this fix to the 3.0 and the 3.1 series. - (#1914) Provide context path to session reload handler. There was a subtle change in behavior in Lift 3.0 that caused bad things to happen when a Lift application was deployed under a context path in an application server (so, somewhere other than
/
) and that Lift application detected that the comet session had disappeared. In previous versions of Lift this would just reload the page. In Lift 3.0, we changed that behavior to take you to the root of your application. However,/
is not always the root of the application. Now, we'll properly consider the context path when detecting what URL to send you to. This is, as always, customizable withLiftRules.noCometSessionCmd
.
Lift Framework 3.2.0-M2
The Lift Committers are pleased to announce the release of Lift 3.2.0-M2 on September 15th, 2017. This release is the second of three milestone releases for Lift 3.2.0. The next milestone release is tentatively scheduled for November 15th, 2017 with plans to finalize Lift 3.2 around the end of the year. As always, you can follow along with our progress in the GitHub Milestone View.
Please read below for the changes in this milestone.
Changes
New Features
(#1906) Snippet Timers
Page loading slowly and you're not sure what code to blame? Want to just report all snippet timings to a metrics system for monitoring? Snippet Timers are for you! Snippet Timers enable global, per-request, or per-session timing of Snippet execution throughout your Lift application. By default, we package a LoggingSnippetTimer
that spits out these timings to the log system, but anything implementing the SnippetTimer
interface can be provided.
To get started you'll need to invoke LiftRules.installSnippetTimer
in Boot
to enable the feature. For example, to enable the logging snippet timer globally, just add the following line:
LiftRules.installSnippetTimer(LoggingSnippetTimer)
If you're only interested in logging in certain sessions or requests, you'll still need to invoke installSnippetTimer
at boot with the NoOpSnippetTimer
to enable the feature. Then, to enable logging snippet timing at some point in a request invoke:
LiftRules.snippetTimer.get.map(_.request(LoggingSnippetTimer))
The logging snippet timer will be enabled for the duration of the request. You can also do the same for a session.
LiftRules.snippetTimer.get.map(_.session(LoggingSnippetTimer))
(#1893) ContainerVar serialization for anything Serializable
Lift has provided ContainerVar
for awhile for storing values in the underlying container session. (This is as opposed to the SessionVar
that stores things in Lift's session.) However, to use a ContainerVar
you need to provide some sort of ContainerSerializer
for the type that you're trying to serialize. Even though Lift has provided a handful of implementations for awhile, none of them would handle something as simple as Box[String]
.
@joescii was kind enough to add a ContainerSerializer
that works for anything extending Serializable
. This should give Lift developers using ContainerVar
a much more "batteries included" experience.
(#1866) New Optional Mongo Fields
@Bhashit made a number of additions to the optional mongo fields as a part of mongodb-record. Some fun additions that your code might benefit from include:
OptionalCaseClassField
OptionalJObjectField
OptionalUUIDRefField
OptionalObjectIdField
... and more! We've also deprecated some legacy field names and parameter names (e.g. rec
is now owner
) so you'll probably see some deprecation warnings crop up if you're using any of those.
Documentation
- (#1868) @Bhashit contributed some very nice documentation about Dependency Injection in Lift.
- During this release cycle, we also formalized our support policy.
Bug Fixes
- (#1911) Consider
LiftRules.cometCreation
when building comets. ThisLiftRule
became ignored by accident during the great comet upgrade of the 3.0 release. We've added the line back that was missing, and plan to back-port this fix to the 3.0 and the 3.1 series. - (#1903) Provide context path to session reload handler. There was a subtle change in behavior in Lift 3.0 that caused bad things to happen when a Lift application was deployed under a context path in an application server (so, somewhere other than
/
) and that Lift application detected that the comet session had disappeared. In previous versions of Lift this would just reload the page. In Lift 3.0, we changed that behavior to take you to the root of your application. However,/
is not always the root of the application. Now, we'll properly consider the context path when detecting what URL to send you to. This is, as always, customizable withLiftRules.noCometSessionCmd
.
Improvements
- (#1918) Logging improvements for various exceptions. @andreak had located a few spots that weren't properly printing the exception stack trace when exceptions were hit, and delivered a Quick Fix™ to that.
- (#1910) Clarification of LAPinger documentation.
- (#1909) Move template cache defaulting to
LiftRules
. This change addresses some confusing behavior in how Lift creates the default template cache. Previously, if you were running in production mode and thetemplateCache
was set toEmpty
we would auto-magically create anInMemoryCache
and use that instead. Due to the way this was written, this effectively meant that turning off template caching in production was impossible. With this change we moved where the default gets calculated so it's actually possible to turn off the template cache in production mode if you would like to do that. - (#1907) Addition of
onShutdown
tobuildRoundtrip
. Previously, users ofbuildRoundtrip
had no way to get notified that the underlying comet actor had been shut down. This meant that they had no way to really know if they could free resources that might be associated with that connection in their application level code. To address this, we've added anonShutdown
argument to thebuildRoundtrip
function so developers can pass a handler when the underlying comet is actually shut down. - (#1895) Make the servlet session ID configurable. Previously, Lift's servlet session identifier was hard-coded. This worked fine for a long time. However, recently we discovered that it doesn't play nice when used in conjunction with Jetty's Mongo persisted sessions plugin because of the
$
s in it. To resolve that, we've made it configurable throughLiftRules.servletSessionIdentifier
. - (#1889) Implementation of LiftRulesGuardedSetting. This type will eventually replace everything in
LiftRules
declared as avar
. The idea here is that we want to avoid folks from changing things inLiftRules
at runtime. We do that in a bit of an ad-hoc way now, in the sense that some settings will blow up in your face if you attempt to do so, but moving forward theLiftRulesGuardedSetting
is the way we're planning to standardize that behavior and make it more consistent. - (#1888, #1881) Various lift-json performance improvements.
About Lift
The Lift Framework is a mature, advanced framework for the modern software engineer. There are Seven Things that set Lift apart from the other frameworks out there today: it's secure-by-default, developer-centric, scalable, capable of rich interactive behavior, modular, and designer-friendly. If you're new to Lift or interested in checking out what these things mean, we recommend checking out Simply Lift and The Lift Cookbook.
The Lift Mailing List is also a good resource for anyone to ask questions or just meet other Lift users. The Lift README is a good resource for figuring out how to use Lift in your project.
Lift Framework 3.2.0-M1
The Lift Committers are pleased to announce the release of Lift 3.2.0-M1 on July 23rd, 2017. This release is the first of three milestone releases for Lift 3.2.0. The next milestone release is tentatively scheduled for September 15th, 2017 with plans to finalize Lift 3.2 around the end of the year. As always, you can follow along with our progress in the GitHub Milestone View.
Please read below for the changes in this milestone.
Changes
- (#1874) Support for HTTP patch method in RestHelper. This PR adds support for a
Patch
verb when usingRestHelper
to build APIs. Examples on how to use this can be found in the Scaladocs for the new matcher. Also, as you would expect, there areXmlPatch
andJsonPatch
variants as there are withGet
,Post
, etc. - (#1865) Ensure the server/port combo of the original request is preserved. This resolves bug #1794, wherein our snapshotting of the underlying request object during some async operations was incomplete. This periodically caused misbehavior that broke the ability to retrieve the host and path of the request being handled by the async operations.
- (#1871) Bumped our logback version. This shouldn't affect applications using Lift directly, since we treat the logback dependency as something the application using Lift will provide. However, we do recommend that, if you haven't, you also upgrade to 1.2.3 or higher to resolve a security issue.
About Lift
The Lift Framework is a mature, advanced framework for the modern software engineer. There are Seven Things that set Lift apart from the other frameworks out there today: it's secure-by-default, developer-centric, scalable, capable of rich interactive behavior, modular, and designer-friendly. If you're new to Lift or interested in checking out what these things mean, we recommend checking out Simply Lift and The Lift Cookbook.
The Lift Mailing List is also a good resource for anyone to ask questions or just meet other Lift users. The Lift README is a good resource for figuring out how to use Lift in your project.
Lift Framework 3.1.0
The Lift Committers are pleased to announce the release of Lift 3.1.0 on July 2nd, 2017. This release continues our new release cadence and marks the first final release in our new cadence. This release has no code changes from the 3.1.0-RC1 release.
About Lift
The Lift Framework is a mature, advanced framework for the modern software engineer. There are Seven Things that set Lift apart from the other frameworks out there today: it's secure-by-default, developer-centric, scalable, capable of rich interactive behavior, modular, and designer-friendly. If you're new to Lift or interested in checking out what these things mean, we recommend checking out Simply Lift and The Lift Cookbook.
The Lift Mailing List is also a good resource for anyone to ask questions or just meet other Lift users. The Lift README is a good resource for figuring out how to use Lift in your project.
Changes
This release of Lift is composed of the following component releases:
Below is a list of changes since Lift 3.0 organized by the type of change and sorted by the PR number.
New Features
- (#1768) Improved handling of tuples in lift-json. Tuples can now be serialized and deserialized as heterogenous arrays in JSON instead of as objects. This feature is disabled by default to ensure we're not changing default behavior in Lift 3.1, but can be enabled by providing a
Formats
object withtuplesAsArrays
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 ofInt
). 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. - (#1813, #1824) Session-aware Lift and Scala Futures. Especially with Lift 3's enhanced support for futures in CSS bindings and
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 asS.sessionFuture
, which can be used to create anLAFuture
task that has access to the session. There is a similar helper,FutureWithSession.withCurrentSession
, that will spawn a task as a ScalaFuture
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'sFuture
in Scala 2.12, as well. - (#1845) Custom rendering of special Double values. Prior to M3, lift-json always serialized
NaN
,PositiveInfinity
, andNegativeInfinity
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 iseval
ing JSON as JavaScript directly---but this is a very unsafe practice. As of M3, we default to rendering these asnull
instead, and provide a newRenderSettings
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 withtryo
to produce aFailure
in these cases). - (#1857) Addition of the
BoxLogging
helpers. The newBoxLogging
helper provides functions for logging boxes and then continuing to operate on the box, allowing logging to become a fluent part of theBox
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.
Improvements
- @n4to4 was kind enough to fix some broken links in our readme.
- (#1791) Event return normalization. If handlers to
liftVanilla.onEvent
returned false, we'd just return that value. Now, we now check for the existence ofevent.preventDefault
and trigger it andstopPropagation
if the handler returnedfalse
. We also return that return thatfalse
value for older browsers to work with. - (#1812, #1815, #1823) Full compatibility with Scala 2.12. Lift 3.0.1 was released with Scala 2.12 support, but there were still some pieces to put in place for proper continuous integration and release building before we could consider that complete. This is now done. Thanks to @SethTisue and @farmdawgnation for putting in some contortions to get this all in order.
- (#1817, #1822)
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. - (#1819) The mongo Java driver has been updated to version 3.4.0.
- (#1829) The MongoDB Record module now supports the MongoDB Async API calls. Now, there are a handful of
*Async
methods on the MongoDB record implementation that will returnFuture
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. - (#1837, #1854) Removed
FileInputStream
andFileOutputStream
usage. @eltimn moved much of Lift's internal usage ofFileInputStream
andFileOutputStream
to their more GC-friendlyjava.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. - (#1838) Removed some deprecated rendering methods in lift-json.
- (#1839) Closer to jQuery independence. Lift 3.0.0 debuted a new
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 makeliftVanilla
a fully functional replacement for the jquery-dependent functionality needed for core Lift operations. - (#1853) Added Class caching for type hints in lift-json. This change should improve performance when the same type hint is seen multiple times by caching the
Class
instance we use for a particular type hint instead of invoking a class lookup each time. - (#1862) Improve error messages when we can't find a correct implicit conversion for CSS transforms. When things went wrong while trying to resolve implicit conversions to make a working CSS transform, the compiler error generated was pretty opaque. With this change, we've improved that error message to be more friendly to people without a ton of Lift experience.
Bug Fixes
- (#1832) Fixed snippet class cache. Resolved a bug in how we cache snippet class instances that caused a performance hit when using the same snippet multiple times.
- (#1841) Fixed event extraction for page fragments. When event extraction was introduced in Lift 3, it did not take into account the possibility that a page fragment might be processed---for example, as a response to an AJAX request. As a result, in these cases, the events were extracted… But they were not re-transmitted through a separate channel. Instead, they were lost entirely. We now fix that, and page fragments with extracted events will properly reference the detached event handler code that will set those handlers up properly on the client.
- (#1842) Disabled event extraction for
fixHtmlFunc
.JsExp
s that handle HTML go throughfixHtmlFunc
, 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 whenLiftRules.extractInlineJavaScript
is enabled,fixHtmlFunc
will not do event extraction. - (#1844) Properly handle missing servlet http requests in
buildDeferredFunction
. SometimesS.req
returns aReq
without a servletHTTPRequest
inside. Ergo, when code would callHttpRequest.snapshot
inReq.snapshot
, we would get aNullPointerException
. To fix this, we modifycurrentReq
in both definitions ofbuildDeferredFunction
so that they filter out null requests. Shout out to first-time contributor @arigoldx! - (#1852) **Always suspend...