- 1.2.56
- 1.2.55
- 1.2.54
- 1.2.53
- 1.2.52
- 1.2.51
- 1.2.50
- 1.2.49
- 1.2.48
- 1.2.47
- 1.2.46
- 1.2.45
- 1.2.44
- 1.2.43
- 1.2.42
- 1.2.41
- 1.2.40
- 1.2.39
- 1.2.38
- 1.2.37
- 1.2.36
- 1.2.35
- 1.2.34
- 1.2.33
- 1.2.32
- 1.2.31
- 1.2.30
- 1.2.29
- 1.2.28
- 1.2.27
- 1.2.26
- 1.2.25
- 1.2.24
- 1.2.23
- 1.2.22
- 1.2.21
- 1.2.20
- 1.2.19
- 1.2.18
- 1.2.17
- 1.2.16
- 1.2.15
- 1.2.14
- 1.2.13
- 1.2.12
- 1.2.11
- 1.2.10
- 1.2.9
- 1.2.8
- 1.2.7
- 1.2.6
- 1.2.5
- 1.2.4
- 1.2.3
- 1.2.2
- 1.2.1
- 1.2.0
Overview of Ballerina 2201.2.0 (Swan Lake)
2201.2.0 (Swan Lake) is the second major release of 2022, and it includes a new set of features and significant improvements to the compiler, runtime, standard library, and developer tooling. It is based on the 2022R3 version of the Language Specification.
Update Ballerina
If you are already using Ballerina 2201.0.0 (Swan Lake), run either of the commands below to directly update to 2201.2.0 using the Ballerina Update Tool.
bal dist update
(or bal dist pull 2201.2.0
)
If you are using a version below 2201.0.0 (Swan Lake), run the commands below to update to 2201.2.0.
-
Run
bal update
to get the latest version of the Update Tool. -
Run
bal dist update
( orbal dist pull 2201.2.0
) to update your Ballerina version to 2201.2.0.
However, if you are using a version below 2201.0.0 (Swan Lake) and if you already ran bal dist update
(or bal dist pull 2201.2.0
) before bal update
, see Troubleshooting to recover your installation.
Install Ballerina
If you have not installed Ballerina, then download the installers to install.
Migrate from Swan Lake Beta releases
Info: If you have been using Swan Lake Beta releases, delete the
Dependencies.toml
files in your Ballerina packages when migrating to Ballerina 2201.2.0 (Swan Lake).
A few backward-incompatible changes have been introduced during the Swan Lake Beta program, and thereby, some of your existing packages may not compile with Ballerina 2201.2.0 (Swan Lake). Therefore, you need to delete the Dependencies.toml
file to force the dependency resolver to use the latest versions of your dependencies.
Language Updates
New features
Support for resource methods in client objects
Client objects can now contain resource
methods. These resource
methods can only be accessed by client resource access actions. With this feature, resource
methods are also allowed in object-type descriptors.
import ballerina/io; type ClientObjectType client object { resource function get greeting/[string name]() returns string; }; ClientObjectType clientObj = client object { resource function get greeting/[string name]() returns string { return "Hello, " + name; } }; public function main() { string result = clientObj->/greeting/James; // Will print `Hello, James` io:println(result); }
In the above example, the greeting/[string name]
resource in clientObj
is accessed with the ->/
call syntax. This notation signifies that it is a resource access action on a client object.
The greeting/James
resource access path segments after ->/
specify the target resource to access on the clientObj
. The default resource method name will beget
if it is not specified in the client resource access action.
Support for creating maps with query expressions
Maps can now be constructed using query expressions. A query expression that constructs a map must start with the map
keyword. Further, the type of the select
expression must be a tuple [string, T]
. Then the query expression will create a value of type map<T>
. Duplicate keys will be handled similarly to a query expression constructing a table.
import ballerina/io; public function main() { [string, int][] arr = [["A", 0], ["B", 1], ["C", 2], ["D", 3], ["A", 4]]; map<int>|error mapA = map from var element in arr select [element[0], element[1]]; io:println(mapA); // {"A":4,"B":1,"C":2,"D":3} map<int>|error mapB = map from var element in arr select [element[0], element[1]] on conflict error("Duplicate Key"); io:println(mapB); // error("Duplicate Key") }
Support for running new strands safely on separate threads
The isolated
feature has been extended to identify cases where strands created by a start
action or a named worker can be run safely on separate threads.
A start
action is isolated if the function or method it calls has a type that is isolated and the expression for every argument is an isolated expression. The object whose method is called by the method call or remote method call is treated as an argument. An isolated start
action is allowed in an isolated
function and the strand created by the start
action will run in a separate thread from the current thread.
import ballerina/io; isolated function f1(int[] arr) returns int[] { return arr.sort(); } isolated function f2() { future<int[]> f = start f1([4, 2, 8, 6]); // Now allowed } function f3(int[] arr) returns int[] { return arr.sort(); } function f4() { future<int[]> f = start f3([4, 2, 8, 6]); } public function main() { io:println(f3 is isolated function (int[]) returns int[]); // true, f3 is inferred to be isolated io:println(f4 is isolated function ()); // true, f4 is inferred to be isolated }
The strand created by a named worker can run on a separate thread from the default worker if the body of the worker satisfies the requirements for an isolated function.
import ballerina/io; final int[] & readonly intArr = [4, 2, 8, 6]; isolated function f1(int[] arr) returns int[] { return arr.sort(); } isolated function f2() { worker A { // Now allowed int[] f = f1(intArr); } } function f3(int[] arr) returns int[] { return arr.sort(); } function f4() { worker A { int[] f = f3(intArr); } } public function main() { io:println(f3 is isolated function (int[]) returns int[]); // true, f3 is inferred to be isolated io:println(f4 is isolated function ()); // true, f4 is inferred to be isolated }
Improvements
Use xml
as the contextually-expected type for interpolations in XML template expressions
The contextually-expected type for interpolations in XML template expressions has been changed to xml
. This ensures that a query expression as an interpolation works as expected. However, it is not an error for the static type to not be a subtype of the contextually-expected type.
import ballerina/io; public function main() { var x1 = xml `<doc>${from int i in 0 ..< 2 select xml `<num>${i}</num>`}</doc>`; io:println(x1); // <doc><num>0</num><num>1</num></doc> xml:Element x2 = xml `<doc>${from int i in 0 ..< 2 select xml `<num>${i}</num>`}</doc>`; io:println(x2); // <doc><num>0</num><num>1</num></doc> int n = 1; var x3 = xml `<num>${n}</num>`; // no error, although the static type is not a subtype of xml io:println(x3); // <num>1</num> }
Allow query expressions with readonly
contextually-expected types
Query expressions are now allowed with readonly
contextually-expected types. Such query expressions create immutable structural values.
import ballerina/io; type T1 readonly & record { string[] arr; }; type T2 record { int id; string name; }; public function main() { T1 t = {arr: from var s in ["A", "C"] select s}; io:println(t); // {"arr":["A","C"]} io:println(isImmutable(t)); // true var arr = [["A", 0], ["B", 1], ["C", 2], ["D", 3]]; map<int> & readonly|error mp = map from var element in arr select [element[0], element[1]]; io:println(isImmutable(mp)); // true table<T2> & readonly tbl = table key(id) from var item in [[1, "John"], [2, "Jane"]] select { id: item[0], name: item[1] }; io:println(isImmutable(tbl)); // true } function isImmutable(any|error value) returns boolean => value is readonly;
Make the variable declaration in the on-fail clause optional
Previously, a variable needed to be declared in the on-fail clause (e.g., on fail error err
). It has now been made optional.
import ballerina/io; function parseInts(string[] strs) returns [int[], int] { int[] ints = []; int errCount = 0; foreach string strVal in strs { do { int intVal = check int:fromString(strVal); ints.push(intVal); } on fail { errCount += 1; } } return [ints, errCount]; } public function main() { [int[], int] [ints, errCount] = parseInts(["1", "b7a", "2"]); io:println(ints); // [1,2] io:println(errCount); // 1 }
Allow actions inside queries
The grammar now allows an action such as a remote method call to occur inside a query.
import ballerina/io; public function main() { var obj = client object { remote function f1() returns (int|string)[] { return [1, "2", "3", 4]; } remote function f2() returns int { return 10; } remote function f3(int i, int j) returns int { return i * j; } }; int[] arr = from var i in obj->f1() let int j = obj->f2() where i is int select obj->f3(i, j); io:println(arr); // [10,40] }
Add the call
langlib function to dynamically call a function
The lang.function:call()
langlib function is introduced to call a function dynamically, passing a function value and optionally argument(s) .
import ballerina/io; public function main() { io:println(function:call(getSum)); // 30 io:println(function:call(getSum, 10)); // 40 io:println(function:call(getSum, 10, 15)); // 45 io:println(function:call(getSum, 10, 15, 25)); // 50 } function getSum(int a = 0, int b = 10, int c = 20) returns int { return a + b + c; }
If the arguments do not match the parameters expected by the function, the function call results in a panic.
import ballerina/io; public function main() { callFn(getSum); // The `function:call` call results in a panic. } function callFn(function fn) { any|error value = function:call(fn, 10); io:println(value); } function getSum(int a, int b, int c) returns int { return a + b + c; }
Backward incompatible changes
- A bug that resulted in allowing access to non-public error intersection types outside the module has been fixed.
public type E1 distinct error; public type E2 distinct error; type E3 distinct error; type E4 distinct error; type E5 E1 & E2; // not allowed to access outside the module type E6 E3 & E4; // not allowed to access outside the module
- Fixed a bug that resulted in a compilation error not being logged for invalid usage of an on-conflict clause in a query with inner queries.
type Token record {| readonly int idx; string value; |}; type TokenTable table<Token> key(idx); public function main() { Token[] tbl = from Token i in (table key(idx) from var j in [1, 2] select { idx: j, value: "A" }) select { idx: i.idx, value: "A" } on conflict error("Duplicate Key"); // Now an error }
- A bug that resulted in a compilation error not being logged when a spread field is used in a table member to specify a field that is part of the key sequence has been fixed. For every field name in the key sequence of a table, a mapping constructor member must have a specific field corresponding to the field.
type Employee record { readonly int id; string name; string dept; }; public function main() { Employee employee = { id: 1234, name: "Amy Wilson", dept: "legal" }; table<Employee> key(id) employees = table [ // Results in an error now. {...employee} ]; }
Bug fixes
To view bug fixes, see the GitHub milestone for 2201.2.0 (Swan Lake).
Runtime updates
New features
Strand dump
Allows getting the status of strands and strand groups during the execution of a Ballerina program.
This can be used to troubleshoot runtime errors. The Ballerina runtime will emit the strand dump to the standard output stream in the text format if it receives a SIGTRAP
signal (SIGTRAP
is not available on Windows).
E.g., if the PID of the running Ballerina program is $PID
, you can get the strand dump by executing either kill -SIGTRAP $PID
or kill -5 $PID
command.
StopHandler
Object
Allows registering a function that will be called during a graceful shutdown.
A call to onGracefulStop
will result in one call to the handler function that was passed as an argument; the handler functions will be called after calling gracefulStop
on all registered listeners, in the reverse order of the corresponding calls to onGracefulStop
.
E.g., a foo
function can be called during the graceful shutdown by registering it as follows.
runtime:onGracefulStop(foo);
Improvements
Type-reference type support at runtime
When a type is defined referring to another type, it will now be passed to the runtime as a BTypeReferenceType
instance.
For example, the following code contains the Integer
and Student
type reference types.
type Integer int; type Person record {| string name; Integer age; |}; type Student Person;
Modified existing runtime APIs
The following runtime Java APIs are now supported to return the BTypeReferenceType
instances.
// from the `ArrayType`. Type getElementType(); // from the `FunctionType`. Parameter[] getParameters(); Type[] getParameterTypes(); // from the `Field`. Type getFieldType(); // from the `BTypedesc`. Type getDescribingType();
New runtime Java API
The following new runtime APIs are added to provide the referred type of a type reference type.
TypeUtils.getReferredType()
getReferredType()
inReferenceType
type Integer int; type Quantity Integer;
In the above example of the Quantity
type,
the TypeUtils.getReferredType()
call will return the int
type instance.
The getReferredType()
call on the ReferenceType
will return another BTypeReferenceType
instance with the Integer
name.
Bug fixes
To view bug fixes, see the GitHub milestone for 2201.2.0 (Swan Lake).
Standard library updates
New features
io
package
- Added support for data mapping between Ballerina Records and CSV in CSV read/write APIs.
constraint
package
- Introduced the
constraint
standard library package, which provides features to validate the values that have been assigned to Ballerina types
http
package
- Implemented the
immediateStop()
function for the HTTP listener - Added the initial support for HATEOAS
- Added support for client resource methods in the HTTP client
- Added IP addresses to both local and remote addresses
- Added proxy support for the HTTP2 client
- Added constraint validation to HTTP payload binding
websocket
package
- Added constraint validation to WebSocket payload binding
graphql
package
- Added the support for deprecation of fields and enum values
- Added the support for GraphQL interceptors
serdes
package
- Introduced the
serdes
standard library package for serializing and deserializing Ballerinaanydata
subtypes - Proto3 is the underlying technology used by this package to achieve serialization and deserialization
os
Package
- Introduced the
exec()
function to support OS command execution in Ballerina
xmldata
package
- Introduced new APIs such as
fromXml
andtoXml
to perform conversions betweenXML
andmap<anydata>
. ThetoRecord
API is being deprecated by introducing thisfromXml
API - Introduced a new config named
rootTag
in theJsonOptions
to configure the name of the XML root element tag
sql
Package
- Added schema client abstraction to support metadata retrieval from SQL databases. The implementation for the connectors will be added soon
grpc
Package
- Introduced message-level annotations for the proto descriptor instead of a centralized proto descriptor
- Introduced packaging support
- Added stub generation support for nested directories
kafka
Package
- Added constraint validation support for payload binding
rabbitmq
Package
- Added constraint validation support for payload binding
nats
Package
- Added constraint validation support for payload binding
Improvements
http
package
- Made HTTP2 the default transport for the
http
package - Updated the default response status as
HTTP 201
for POST resources
random
Package
- Updated the
createDecimal()
function to be cryptographically secure
grpc
Package
- Added sample client calls with dummy values to generated client files
- Removed caller client object when generating code in client mode
- Added a new
grpc:Descriptor
annotation for services as a replacement for the currentgrpc:ServiceDescriptor
. Both annotations are supported now to maintain backward compatibility. Thegrpc:ServiceDescriptor
will be removed in the future. (Please update the service annotation if stub files are regenerated for the existing gRPC services)
Bug Fixes
To view bug fixes, see the GitHub milestone for 2201.2.0 (Swan Lake).
Code to Cloud updates
Improvements
The base image was updated to ballerina/jvm-runtime:1.0
based on Alpine 3.15 with the necessary libraries.
Bug fixes
To view bug fixes, see the GitHub milestone for 2201.2.0 (Swan Lake).
Developer tools updates
New features
Language Server
- Added API docs reference support on hover. Now when you hover over a construct (class, type, function), the hover documentation will include a link to view the API docs specific to that construct
- Added new code actions to extract anonymous records into records and to generate undefined record types
- Introduced new source actions to generate getters and setters for class-level variables
- Added a new code action to make annotation declarations with the
source
attach point(s) constant - Moved the
Optimize imports
code action toSource action
and it no longer appears under the code action bulb. Source actions are displayed underSource action
in the context menu
OpenAPI Tool
Added support for generating client resource methods in the client generation command. The preferred client method type can be chosen using the --client-methods=<remote(default)|resource>
option.
$ bal openapi -i <OpenAPI contract> --client-methods=resource
$ bal openapi -i <OpenAPI contract> --mode client --client-methods=resource
SemVer validator CLI tool (Experimental)
Introduced the bal semver
CLI command, which attempts to validate Semantic Versioning compatibility of the local package changes against any previously published version(s) in Ballerina Central. Currently, the tool can be used to:
- list down the source code differences (along with its compatibility impact) between the local and any published versions in Ballerina central
- suggest the new package version based on the compatibility impact of source code changes
Refer to the examples below which demonstrate a few key functionalities of the SemVer CLI tool.
- version suggestions
$bal semver checking for the latest compatible release version available in central... current version: 1.2.2-SNAPSHOT compatibility impact (compared with the release version '1.2.1'): backward-incompatible changes detected suggested version: 2.0.0
- version suggestions with the list of source code changes
$bal semver --show-diff checking for the latest compatible release version available in central... ========================================================================= Comparing version '1.2.2-SNAPSHOT'(local) with version '1.2.1'(central) ========================================================================= [+-] package 'io' is modified [version impact: MAJOR] [+-] module 'io' is modified [version impact: MAJOR] [++] function 'printlnNew' is added [version impact: MINOR] [+-] function 'println' is modified [version impact: MAJOR] [+-] documentation is modified [version impact: PATCH] [--] 'isolated' qualifier is removed [version impact: AMBIGUOUS] [++] 'transactional' qualifier is added [version impact: AMBIGUOUS] [++] new required parameter 'a' is added [version impact: MAJOR] [++] new defaultable parameter 'b' is added [version impact: MINOR] [+-] parameter type changed from 'Printable' to 'string' [version impact: AMBIGUOUS] [+-] function body is modified [version impact: PATCH] current version: 1.2.2-SNAPSHOT compatibility impact (compared with the release version '1.2.1'): backward-incompatible changes detected suggested version: 2.0.0
CLI
Introduced the bal graph
CLI command, which resolves the dependencies of the current package and prints the dependency graph in the console. This produces the textual representation of the dependency graph using the DOT graph description language.
$ bal graph digraph "org/package:0.1.0" { node [shape=record] "org/package" [label="<0.1.0> org/package:0.1.0"]; "ballerina/io" [label="<1.2.2> ballerina/io:1.2.2"]; // Edges "org/package":"0.1.0" -> "ballerina/io":"1.2.2"; }
Compiler API
- Introduced a set of builders in the Types API, which are used to construct complex types that have varying components
Ballerina Update Tool
Improvements
Language Server
- Improved the
Create variable
code action in theasync send
action - Added completion support for the resource access action context
OpenAPI Tool
Added support for OpenAPI schema constraint properties in client/service generation. With this improvement, the OpenAPI constraints will be applied as ballerina/constraint
standard library package annotations when generating Ballerina clients and services from the OpenAPI definition.
The following OpenAPI properties are currently supported in the Ballerina OpenAPI generation tool.
minimum
,maximum
,exclusiveMinimum
, andexclusiveMaximum
forinteger
andnumber
typesminLength
andmaxLength
forstring
typeminItems
andmaxItems
forarray
type
To view bug fixes, see the GitHub milestone for 2201.2.0 (Swan Lake) of the repositories below.
JSON to record converter
Improved JSON value to Ballerina record conversion logic, to enhance the conversion experience of Paste JSON as record
feature in Ballerina VSCode extension.
Handling of array of elements/objects
Instead of looking at the first object of the array, all elements/objects would be looked at to generate the record field.
[ { "id": "5001", "index": "15" }, { "id": "5002", "index": 16 } ]
type ArrayItem record { string id; (int|string) index; };
Handling optional fields
If an element is present in a JSON object and not in another (in an array of objects), that field would be treated as an optional field.
[ { "id": "5001", "index": "15" }, { "id": "5002" } ]
type ArrayItem record { string id; string index?; };
Handling null
values
JSON null
fields would be treated as required fields with the anydata
type.
{ "name": "Joe", "phoneNumber": null }
type NewRecord record { string name; anydata phoneNumber; };
Note: The entire JSON value to Ballerina record conversion logic is rewritten to enhance the conversion experience. The above-mentioned scenarios are a few noticeable, important changes.
Compiler API
- Added semantic API support for the client resource access action
Ballerina packages updates
New features
Introduced an include
field under the [package]
table in Ballerina.toml
. It accepts a string array of paths to any additional files and directories, which need to be packed in the BALA file. The path should be relative to the package root directory.
[package] org = "samjs" name = "winery" version = "0.1.0" include = [documents/”, "images/sample.png"]