Platform
Breaking Changes
-
The structure of storing references to entities in Entity Log, Entity Snapshots and Dynamic Attributes has been changed. If you have accessed internals of these mechanisms from your application code, you may need to change it accordingly. PL-8461.
-
Now we use default behavior of Vaadin’s Valo theme (PL-8267) :
-
HBox
andVBox
useoverflow: auto
CSS mode. If aHBox
orVBox
has a child with 0 height then the layout will have non-zero height. -
Font size is inherited using normal CSS rules instead of explicit setting for components.
-
-
The
fileExists()
method ofFileStorageAPI
now declaresFileStorageException
. If you invoke this method, add acatch
block. PL-8866. -
Validation for input parameters of
UniqueNumbersAPI
methods has been added. A sequence name can contain only alphanumeric characters and underscores, otherwiseIllegalArgumentException
is thrown. PL-8724. -
Due to cluster improvements explained below, pay attention to the following:
-
If you don’t use Studio migration procedure, edit
spring.xml
files of all client modules used in your project, find thexyz_proxyCreator
bean definitions and replace:<property name="clusterInvocationSupport" ref="cuba_clusterInvocationSupport"/>
with
<property name="serverSelector" ref="cuba_ServerSelector"/>
-
jgroups.xml
has been split into two files:jgroups.xml
(UDP stack) andjgroups_tcp.xml
(TCP stack). Usecuba.cluster.jgroupsConfig
application property to select the stack.
-
-
Due to improvements in
FieldGroup
component explained below:-
Class
FieldGroup.FieldConfig
has been refactored to interface. Now you cannot createFieldConfig
instance using constructor as it became a Java interface. UseFieldGroup.createField(id)
instead. -
FieldConfig.setDatasource()
now does not trigger creation ofField
components. Use an additionalFieldGroup.bind()
call.
-
-
Option dialogs opened with
showOptionDialog()
method of screen controllers are always closed after selecting an option, even if an exception occurs inactionPerform()
. PL-8610. -
Microsoft’s JDBC driver is now used instead of jTDS if the project uses Microsoft SQLServer database. Studio performs automatic migration when upgrading the project to platform 6.5. PL-8826.
-
Reporting. If no screens are specified for a report, it is not shown on pop-up window of screen reporting actions. PL-8618.
-
Charts and Maps. Chart API has been reworked, see below. PL-7754.
-
Charts and Maps. The
GoogleMapViewer
interface has been deprecated, use theMapViewer
component directly. PL-8787.
Uber JAR
CUBA applications can now be deployed as executable JAR files containing the application code, all dependencies and embedded HTTP server. See UberJAR Deployment for details.
Cluster Improvements
- Middleware Load Balancing
-
Previously, the web client blocks did not perform balancing when worked with multiple middleware blocks. They chose a middleware server from the list specified in the
cuba.connectionUrlList
at startup and didn’t change it until it became unavailable. So the load balancing was possible only between multiple web blocks (and ifcuba.randomServerPriority
was set to true): first web block works with first middleware, second web with another middleware and so on. Ifcuba.randomServerPriority
was set to false, each client block selected a middleware block that was first in itscuba.connectionUrlList
.Now the balancing is much more granular - on the user session level. A middleware server is randomly determined on the first remote connection for a user session, and it is fixed for the whole session life time ("sticky session"). Requests from anonymous session and without session do not stick to a server and go to random servers.
The algorithm of selecting a middleware server is provided by the
cuba_ServerSorter
bean which is by default implemented by theRandomServerSorter
class. You can provide your own implementation in the project or useNoopServerSorter
to revert to the old behavior when client always selects the first available server from itscuba.connectionUrlList
.
- Coordination Using ZooKeeper
-
Application blocks interact in a cluster in two ways: middleware blocks interact with each other, web blocks send requests to middleware. These channels of communication are based on different mechanisms (JGroups for inter-middleware interaction, Spring HTTPInvoker for requesting middleware from clients), however they both require discovering of current cluster topology - what middleware servers are up now and how to connect to them. By default, the following approaches are used:
-
For communication between middleware blocks you set up UDP or TCP stack with some discovery methods. In case of UDP stack the discovery can be automatic as it is based on broadcasting UDP messages. However, broadcasting is often disabled in production environments, so the only reliable method of discovery is to specify the list of server addresses for TCPPING protocol in
jgroups.xml
. It means that the topology is static - you have to know it in advance when starting a middleware server. -
For requesting middleware from client blocks, you have to specify addresses of the middleware blocks in the
cuba.connectionUrlList
application property. It also makes the configuration static - you have to know addresses of the middleware servers when starting a client block.
Now we provide an application component that enables dynamic discovery of middleware servers for both communication channels. It is based on integration with Apache ZooKeeper - a centralized service for maintaining configuration information. When this component is included in your project, you need to specify only one static address when running your application blocks - the address of ZooKeeper. Middleware servers will advertise themselves by publishing their addresses on the ZooKeeper directory and discovery mechanisms will request ZooKeeper for addresses of available servers. If a middleware server goes down, it will be automatically removed from the directory immediately or after a timeout.
-
REST API Improvements
- Model Versioning
-
REST API v2 now contains a mechanism that allows you to change your data model but keep compatibility with existing REST clients. If a request from a client contains the
modelVersion
parameter, REST will apply a set of JSON transformations defined in a special XML configuration file. There are predefined transformations like removing or replacing an attribute, and you can provide custom classes for arbitrary transformations of schema and values. See documentation for details.
- Persistent Token Store
-
By default, REST API v2 OAuth tokens are stored in memory only, which means clients need to re-login if the middleware server is restarted. Now you can turn on persistent storage for authentication tokens: see documentation for details. You may also want to increase token expiration timeout using the
cuba.rest.client.tokenExpirationTimeSec
application property, which is 12 hours by default.
FileLoader Interface
The new FileLoader
interface allows you to work with files contained in File Storage uniformly from the client and middle tier using input/output streams. It’s a managed bean that can be injected or obtained via AppBeans
class and it provides openStream()
and saveStream()
methods to load and save files. Both client and middleware implementations of the interface do not keep the whole file in memory, so you can pass files of any size without the risk of reaching memory limits.
FieldGroup API
We have reworked API of the FieldGroup
component, deprecated old procedural methods and added support for dynamic change of the set of fields.
- Breaking changes
-
Class
FieldGroup.FieldConfig
has been refactored to interface. Now you cannot createFieldConfig
instance using constructor as it became a Java interface. UseFieldGroup.createField(id)
instead.FieldConfig.setDatasource()
now does not trigger creation ofField
components. Use an additionalFieldGroup.bind()
call. - Deprecated
-
All methods
setField<Something>(fieldId, value)
andset<Something>(fieldId, value)
have been deprecated. UseFieldConfig
APIs instead:fieldGroup.getFieldNN("login").setVisible(false);
Method
FieldGroup.addCustomField
has been deprecated. Now, it is recommended to obtainFieldConfig
and callsetComponent(Component)
:LookupField languageLookup = factory.createComponent(LookupField.class); ... fieldGroupRight.getFieldNN("language").setComponent(languageLookup);
- New features
-
You can specify separate
property
XML attribute for data binding:<fieldGroup id="fieldGroup" datasource="userDs" width="AUTO"> <field id="position1x" property="position"/> </fieldGroup>
We have introduced the
FieldGroupFieldFactory
bean that can be replaced globally or for a certainFieldGroup
instance usingfieldFactoryBean
XML attribute orFieldGroup.setFieldFactory()
method.Now you can add/remove fields on the fly using methods:
addField(FieldConfig)
,addField(FieldConfig, colIndex)
,addField(FieldConfig, colIndex, rowIndex)
,removeField(fieldId)
.
See PL-8776 for more details.
DataGrid
We have introduced inline editor for DataGrid
component. DataGrid
supports line-based editing, where double-clicking (or using Enter key) a row opens the row editor. In the editor, the input fields can be edited, as well as navigated with Tab and Shift+Tab keys. If validation fails, an error is displayed and the user can correct the inputs. It allows a user to edit rows inside of DataGrid
using a special editable representation of a row.

SuggestionPickerField
The visual components library now contains a true autocomplete field with background loading of options: SuggestionPickerField. It is designed to search for entity instances according to a string entered by a user. It differs from SearchPickerField
in that it refreshes the list of options on each entered symbol without the need to press Enter. The list of options is loaded in background according to the logic defined by the application developer on the server side.

Managed TabSheet
New cuba.web.mainTabSheetMode
application property defines which component will be used for Tabbed mode of main window:
-
Default
TabSheet
component. -
Managed
TabSheet
component that doesn’t unload tab content from the browser when a user selects another tab.
This property can have one of the two string values: DEFAULT
or MANAGED
.
MANAGED
option is useful when you integrate some thirdparty web UI to your application as HTML iframe
using the Embedded
component. In case of DEFAULT
mode content of a tab and embedded iframe
will be completely reloaded on each selected tab switch. If you use MANAGED
option then content of a tab remains in a browser memory and will not be reloaded when user switches tabs.
See PL-8464 for more details.
Charts
Charts API has been simplified:
-
Introduced separate component interfaces for all charts: AngularGaugeChart, FunnelChart, GanttChart, PieChart, RadarChart, SerialChart, XYChart. They contain methods that are relevant for a concrete chart implementation.
-
Improved data binding. Now you can simply call
addData()
method to add items to a chart.
Note: charts XML markup fully compatible with the previous version.
New API usage example:
public class OrderBrowse extends AbstractLookup {
@Inject
private PieChart pieChart; // we can inject typed Chart interface
@Override
public void init(Map<String, Object> params) {
super.init(params);
// no need to obtain configuration object and cast it to PieChart
pieChart.setDepth3D(15)
.setAngle(15)
.setBalloon(
new Balloon()
.setColor(Color.AQUA)
);
// just add data, no need to create and set ListDataProvider
pieChart.addData(MapDataItem.of("name", "Some String",
"value", 75));
pieChart.addData(MapDataItem.of("name", "Another String",
"value", 12));
}
}
- Removed
-
-
Chart.setConfiguration()
- now you have to use concrete Chart interface inheritor. -
Chart.isByDate()
andChart.setByDate()
- now you have to use SeriesBasedChart interface and assign value toCategoryAxis.parseDates
property.
-
- Moved
-
-
Chart.add<SomeEvent>Listener
methods now are available only for concrete Chart interfaces. -
Methods
zoomOut
,zoomToIndexes
,zoomToDates
have been moved to SeriesBasedChart interface. -
Methods
zoomOutValueAxes
,zoomOutValueAxis
,zoomOutValueAxis
,zoomValueAxisToValues
,zoomValueAxisToValues
have been moved to CoordinateChart interface.
-
- Deprecated
-
-
Constant
Chart.NAME
no more corresponds to concrete Component class. -
Chart.getConfiguration()
- now you can use concrete Chart inheritor instead, but you still can configure chart using old code based on configuration object.
-
If you declare charts in XML then concrete chart components will be created and you can inject them to your controller:
@Inject
private SerialChart columnChart;
@Inject
private GanttChart ganttChart;
To migrate old code that uses event listeners you have to add type casts (or use the new chart interface):
@Inject
private Chart pieChart;
...
((PieChart) pieChart).addSliceClickListener(event -> {
});
- Simplified data binding API
-
-
Added convenient constructors to MapDataItem
-
New
addData
method is available from any Chart interface
pieChart.addData(MapDataItem.of("name", "Some String", "value", 75)); pieChart.addData(MapDataItem.of("name:", "Another String", "value", 12));
-
See PL-7754 for more details.
Polymer UI
Polymer templates have been adopted to use CUBA Studio’s snippets mechanism. All templates use the same snippets for entity -list
and -edit
components generation. Also properties and methods of -list
and -edit
components were extracted to the corresponding behaviors: CubaEntityEditViewBehavior
and CubaEntityListViewBehavior
which are available in cuba-ui
package.
- Routing
-
'Entity CRUD actions' templates were merged to a single 'Entity management' template however you still can choose between cards/simple list representation. The component generated by this template contains routing logic for switching between list and editor state. The state is bound to the URL using
app-route
components so it is possible to navigate directly to a particular entity editor.
- Lookup Approach
-
cuba-lookup
component provides an ability to specify entity-list
component in order to select an entity instance for a reference attribute. The list component should be marked with.lookup-screen
class.<link rel="demo-manufacturers-by-country.html"> <cuba-lookup picked-entity="{{entity.manufacturer}}"> <div class="dropdown"> ... <!-- dropdown--> </div> <demo-manufacturers-by-country class="lookup-screen"></demo-manufacturers-by-country> </cuba-lookup>
- File Upload Field
-
cuba-file-field
element provides an ability to upload file to the server. Uploaded file will be shown as clickable link.<cuba-file-field file-descriptor="{{entity.photo}}"></cuba-file-field>
Studio
Known Issues
-
There is a bug in the Studio release 6.5.5 shell script that prevents launching if current directory is not
studio/bin
that contains the script. In order to start Studio on Linux, open your terminal,cd
to thebin
folder and executestudio
from it.
Breaking Changes
Polymer Templates
Templates which are used for Polymer UI scaffolding were changed to support routing improvements. In order to adopt those changes and use new templates you have to perform manual upgrade on your Polymer client source code. The changes are listed below.
-
Add
cuba-ui
dependency to thebower.json
:{ ... "dependencies": { ... "cuba-ui": "cuba-elements/cuba-ui#^0.1.0", ... } ... }
-
Add
cuba-ui
import to the{namespace}-shell.html
:<link rel="import" href="../bower_components/cuba-ui/cuba-ui.html">
-
Make the following changes in
{namespace}-shell.html
:-
add
tail
property binding in theapp-route
component:<app-route route="{{route}}" pattern="/:page" data="{{routeData}}" tail="{{routeTail}}">
-
set
selected-attribute="active"
in theiron-lazy-pages
component:<iron-lazy-pages selected="[[_computeSelectedPage(routeData.page)]]" attr-for-selected="data-route" selected-attribute="active" class="content fit">
-
add the following listener and handler:
Polymer({ is: 'namespace-shell', ... listeners: { 'navigate': '_onNavigate' }, ... _onNavigate: function(event, detail) { this.set("route.path", detail); } });
-
Screen Templates
The API of screen templates has been reworked, so if you have created your own templates, they most probably won’t work in Studio 6.5.
The following API methods have been removed: getEditorNestedDatasourceProperties()
, getEditorNestedCollectionDatasourceProperties()
, generateDescriptorFileName()
, generateFiledGroupXml()
, getEditorCollectionAttributesTablesXml()
, getBrowseColumns()
, generateControllerNameByDescriptorName()
.
The removed methods are replaced with two new methods: processSnippet()
and evaluateScript()
, and a number of "snippets" and "scripts". These reusable parts of templates are located in the snippet
subdirectory of the templates folder. As a result, all the logic previously hidden inside Studio API is now available in the form of micro-templates.
See Studio context help on the templates editing page for details.
Bintray Repository
All binary artifacts of CUBA platform and Premium Add-ons are now published also on Bintray. Currently we are considering the usage of Bintray as experimental, but if you have any trouble accessing our repo.cuba-platform.com
repository, you can easily switch to Bintray by selecting it in the Studio Server window:
https://dl.bintray.com/cuba-platform/main
Authentication for this repository is not needed. After reopening your project, Studio will automatically update the buildscript.repositories
section of your build.gradle
. There will be separate declarations of all needed repositories, such as mavenCentral
, jcenter
, etc.
If you use Premium Add-ons, build.gradle
will contain additional repository:
maven { url 'https://cuba-platform.bintray.com/premium' credentials { username(rootProject.hasProperty('premiumRepoUser') ? rootProject['premiumRepoUser'] : System.getenv('CUBA_PREMIUM_USER')) password(rootProject.hasProperty('premiumRepoPass') ? rootProject['premiumRepoPass'] : System.getenv('CUBA_PREMIUM_PASSWORD')) } }
Studio provides credentials automatically from your subscription information.
When you build your project with Bintray from the command line, there is a distinction from repo.cuba-platform.com
repository in how to specify credentials. For Bintray, you should add @cuba-platform
suffix to the user name, for example:
gradlew assemble -PpremiumRepoUser=123456123456@cuba-platform -PpremiumRepoPass=abcdefabcdef
Support for Bean Validation
Studio now contains UI for setting field-level bean validation annotations. It is available on the entity attribute panel, for example:

Please note that you should enter annotation values exactly as they appear in Java code. This is especially important in regular expressions where you should escape \ symbols, for example:

Groovy-based Entity Listeners
If you have selected Groovy support on the Project properties > Advanced tab,

you can select Groovy when creating an entity listener:

Localized Messages in UI Designer
Studio screen layout designer now displays localized messages (in default locale) instead of message keys. In the example below, the button has its caption
attribute set to msg://myButton
, but the layout display My Button caption that is set in a message pack for this key:
