Eclipse Scout Migration Guide

This document is referring to a past Scout release. Please click here for the recent version.

About This Document

This document describes all relevant changes from Eclipse Scout 23.1 to Eclipse Scout 23.2. If existing code has to be migrated, instructions are provided here.

Obtaining the Latest Version

Scout Runtime for Java

Scout Runtime artifacts for Java are distributed using Maven Central:

Usage example in the parent POM of your Scout application:

<dependency>
    <groupId>org.eclipse.scout.rt</groupId>
    <artifactId>org.eclipse.scout.rt</artifactId>
    <version>23.2.15</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

Scout Runtime for JavaScript

Scout Runtime artifacts for JavaScript are distributed using npm:

Usage example in your package.json:

{
  "name": "my-module",
  "version": "1.0.0",
  "devDependencies": {
    "@eclipse-scout/cli": "23.2.15",
    "@eclipse-scout/releng": "^22.0.0"
  },
  "dependencies": {
    "@eclipse-scout/core": "23.2.15",
    "jquery": "3.6.0"
  }
}

The pre-built Scout JavaScript assets are also available using a CDN (e.g. to be directly included in a html document): https://www.jsdelivr.com/package/npm/@eclipse-scout/core?path=dist

IDE Tooling (Scout SDK)

Scout officially supports IntelliJ IDEA and Eclipse for Scout Developers.

IntelliJ IDEA

You can download the Scout plugin for IntelliJ IDEA from the JetBrains Plugin Repository or you can use the plugins client built into IntelliJ IDEA. Please refer to the IntelliJ Help on how to install and manage plugins.

Eclipse

You can download the complete Eclipse IDE with Scout SDK included here:
Eclipse for Scout Developers

To install the Scout SDK into your existing Eclipse IDE, use this P2 update site:
https://download.eclipse.org/scout/releases

New 3rd Party requirements

To update your application the following steps might be required:

  • Update the version of the maven_rt_plugin_config-master in your pom.xml files to the newest 23.2.x release. See Maven central for a list of versions available.

  • Update the Scout versions (package.json and pom.xml) as shown in Obtaining the Latest Version.

  • If you are using Eclipse and web-service providers, update the .factorypath files as shown in JAX-WS Appendix.

Utilities

DateUtility: New Default Date Time Format

Since this version, the method DateUtility#formatDateTime returns the date formatted with the DateFormat.DEFAULT and no longer with the DateFormat.SHORT. Now, both methods, DateUtility#formatDate and DateUtility#formatDateTime, are formatting the date identically. To apply the old formatting, use DateUtility#formatDateTimeShort.

New ExceptionUtility

A set of utility methods dealing with Exception and Throwable were moved and added to the new ExceptionUtility.

Change invocations of org.eclipse.scout.rt.platform.exception.ExceptionHandler.getRootCause() to the new utility method org.eclipse.scout.rt.platform.util.ExceptionUtility.getRootCause().

Adapted REST ErrorDoRestClientExceptionTransformer

The transformation logic for exceptions which occur while invoking a REST client was slightly adapted. For HTTP error codes 502 (bad gateway), 503 (service unavailable) and 504 (gateway timeout) the adapted ErrorDoRestClientExceptionTransformer returns a org.eclipse.scout.rt.platform.exception.RemoteSystemUnavailableException instead of the former generic org.eclipse.scout.rt.platform.exception.ProcessingException.

Removed Deprecated Code

The following functions were deprecated in a previous release and are now removed completely.

  • TabBox.ts: selectTabById, replaced by setSelectedTab

  • JQueryMouseWheelEvent: instead of using DOMMouseScroll mousewheel events use wheel and JQueryWheelEvent type

  • Menu.ts: addChildActions, replaced by insertChildActions

  • Widget.ts: _isRemovalPending, replaced by isRemovalPending

  • CompositeFieldUtility.java: moveFieldTo, third parameter removed

  • AbstractExtensionChain.java: callChain, vararg removed

  • AbstractDataModelOperatorField.java: setAttribute, second parameter is not optional anymore

  • FocusManager.ts: requestFocus does not accept a boolean anymore as third parameter

Removal of Public Holiday Calendar Support

A few classes used to read public holidays from an XML file and providing them to the calendar were removed without replacement:

  • org.eclipse.scout.rt.client.ui.basic.calendar.provider.AbstractHolidayItemProvider

  • org.eclipse.scout.rt.shared.services.common.calendar.IHolidayCalendarService

  • org.eclipse.scout.rt.server.services.common.calendar.HolidayCalendarService

  • org.eclipse.scout.rt.shared.services.common.calendar.HolidayItem

  • org.eclipse.scout.rt.shared.services.common.calendar.HolidayCalendarItemParser

Health Check Servlet

The logic of executing health checks was extracted from org.eclipse.scout.rt.server.commons.healthcheck.AbstractHealthCheckServlet and moved to an own org.eclipse.scout.rt.server.commons.healthcheck.HealthCheckService.

The AbstractHealthCheckServlet is no longer abstract, was renamed to HealthCheckServlet and may be used without further individualization.

To update to the new servlet, the following changes in your web.xml are necessary:

  • UI Server: Replace org.eclipse.scout.rt.ui.html.admin.healthcheck.UiHealthCheckServlet with org.eclipse.scout.rt.server.commons.healthcheck.HealthCheckServlet in your web.xml

  • Backend Server: Replace org.eclipse.scout.rt.server.admin.healthcheck.ServerHealthCheckServlet with org.eclipse.scout.rt.server.commons.healthcheck.HealthCheckServlet in your web.xml

Removed unused NLS texts

The following NLS texts were unused within the Scout framework and removed:

  • ButtonDeselectAll

  • ButtonSelectAll

  • ErrorTextLogin

  • ErrorTextSecurity

  • ErrorTitleLogin

  • FileNotFoundMessage

  • FormIncompleteIntro

  • IOErrorInfo

  • IOErrorText

  • IOErrorTitle

  • LogicTimeIsInGEHours

  • LogicTimeIsInGEMinutes

  • LogicTimeIsInHours

  • LogicTimeIsInLEHours

  • LogicTimeIsInLEMinutes

  • LogicTimeIsInMinutes

  • LogicTimeIsNotNow

  • LogicTimeIsNow

  • NetErrorInfo

  • NetErrorText

  • NoSorting

  • OriginalErrorMessageIs

  • VetoErrorText

  • WeekShort

  • Without

  • searchingProposals

Adapt Planner properties

Planner.selectionMode is removed. The properties Planner.rangeSelectable and Planner.multiSelect should be used instead. To get the same behavior as before, the modes should be translated as follows:

  • SELECTION_MODE_NONE → Planner.rangeSelectable = false and Planner.multiSelect = false

  • SELECTION_MODE_SINGLE_RANGE → Planner.rangeSelectable = true and Planner.multiSelect = false

  • SELECTION_MODE_MULTI_RANGE → Planner.rangeSelectable = true and Planner.multiSelect = true

With Planner.rangeSelectable = false and Planner.multiSelect = true its now possible to select multiple rows even if no range is selectable. In addition, if multiple rows are selectable, the selected rows no longer have to be next to each other.

.properties Files using UTF-8 instead of ISO-8859-1 (Latin-1)

.properties files, including, but not limited to

  • Text properties (NLS)

  • Config properties

  • User preferences via FileSystemUserPreferencesStorageService

are now using UTF-8 instead of ISO-8859-1 encoding.

Existing files need to be converted, e.g. using the native2ascii tool, which is available e.g. in OpenJDK 8. Execute the following command in your workspace directory in a Bash (also works e.g. in Git Bash or on WSL):

find . -name "*.properties" -exec native2ascii -reverse -encoding utf8 {} {} \;

It’s recommended to check calls to

  • Properties#load

  • Properties#store

and make sure that the Reader/Writer overload is used instead of the one with InputStream/OutputStream and that UTF-8 encoding is used for the reader/writer. Example:

try (InputStream stream = getClass().getResourceAsStream(filename); Reader reader = new InputStreamReader(stream, StandardCharsets.UTF_8)) {
  Properties properties = new Properties();
  properties.load(reader);
  // ...
}

Additionally, configure your IDE to use UTF-8 for .properties files too.

Eclipse: Window/Preferences/General/Content Types

  • Text/Java Properties File

  • Default encoding: UTF-8 & press Update

IntelliJ: File/Settings/Editor/File Encodings:

  • Project Encoding: UTF-8

  • Properties Files (*.properties)

    • Default encoding for properties files: UTF-8

    • Transparent native-to-ascii conversion: unchecked

In .editorconfig, remove the section for *.properties, e.g. remove

[*.properties]
charset = latin1 # latin1 = ISO-8859-1

Charset for [*] should already be set to charset = utf-8.

CssClasses interface

The interface org.eclipse.scout.rt.client.ui.CssClasses was moved to org.eclipse.scout.rt.shared.CssClasses. The old interface was left and marked @Deprecated for release 23/2 and will be removed in a future release. Change your imports to the moved interface in order to avoid deprecation warnings.

Use DataObjectHelper#cloneLenient within IDoValueMigrationHandler#migrate

DataObjectMigrator uses ILenientDataObjectMapper to create a typed representation of the given data object after structure migration and before calling value migrations. For any implementation of a value migration working on a data object, most likely DataObjectHelper#clone is currently used to get a copy of the provided input argument. DataObjectHelper#cloneLenient must be used instead. There might be structural inconsistencies that are migrated by later value migrations. DataObjectHelper#clone would fail in such scenarios, DataObjectHelper#cloneLenient won’t.

Update logback.xml

Due to third-party dependency update of slf4j/logback and an additional improvement regarding MDC handling, the logback.xml files were slightly adjusted. Compare with the ones generate for a new Scout project to update yours accordingly.

Scout JS

Multi Dimension Support

Since some properties on Widget and Column are now computed based on their dimensions, they must always be set using the corresponding setter. Even though it was already bad practise to set a value without using the setter, it may have worked for your case if you didn’t need a property change event or the property to be rendered. If you do so now, you will replace the computed value instead of setting the default dimension, which may result in unexpected behavior.

Please check in your code, if you set the following properties directly and replace them with the corresponding setter.

Widget.visible = value -> Widget.setVisible(value)
Widget.enabled = value -> Widget.setEnabled(value)
Column.visible = value -> Column.setVisible(value)
Column.displayable = value -> Column.setDisplayable(value)

Furthermore, Widget.isVisible() and Column.isVisible() have been deprecated because the visible properties are now computed and there is no need for having isVisible() anymore. Therefore, please use the property visible directly instead of calling isVisible().

Widget.isVisible -> Widget.visible
Column.isVisible -> Column.visible

Table: Enabled State of Menus Depends on Selected Rows

Menus on a table with menu type SingleSelection or MultiSelection are now disabled if some of the selected rows are disabled. This makes it consistent with the existing Scout Classic behavior. If you need these menus to always be enabled, you can set the property inheritAccessibility to false.

Tree: Insert Order Changed

Tree.insertNodes now adds new nodes (without an explicit childNodeIndex) at the bottom of the existing nodes instead of the top. This is already the case for the Scout Classic tree, and also for other widgets like table and tile grid.

To insert the nodes at the beginning or any other position, you can use the new parameter index.

Form

The default value for the modal property has been changed for forms with displayStyle = Form.DisplaStyle.VIEW, see Release Notes.

Form Validation

The text to display when the Form validation failed has been moved from Lifecycle to Form:

  • Lifecycle.validationFailedTextKey to Form.validationFailedText and use the ${textKey:TextKey} notation to specify a text key

  • Lifecycle.validationFailedText to Form.validationFailedText

The code to display a message box when the Form validation failed has been moved from Lifecycle to Form:

  • Lifecycle._showStatusMessageBox to Form._showFormInvalidMessageBox

  • Lifecycle._createStatusMessageBox to Form._createStatusMessageBox

Form Error Handling

The load, postLoad and save operations of a Scout JS Form include automatic error handling now. Custom logic to handle errors (e.g. from REST calls) are in most cases no longer necessary and can therefore be removed.

If the default error handling does not suit your needs override one of the following methods:

  • _handleError: to handle all phases (load, postLost, save)

  • _handleLoadError: load errors only

  • _handlePostLoadError: postLoad errors only

  • _handleSaveError: save errors only

To customize the error handling from outside the form suppress the default handling using an event listener and apply your own logic in the catch:

form.on('error', event => {
    if (event.phase === 'load') {
      event.preventDefault(); // disable default error handling for 'load' only
    }
});
form.open().catch(error => {
  // add your custom error handling logic here
});

As part of the new error handling the following methods changed its signature:

  • Form.validate and Lifecycle.validate: Now return Promise<Status> instead of Promise<boolean>. The former boolean value can be obtained by calling isValid() on the new Status object.

  • Lifecycle.handle now only takes a function returning Promise<void>. There is no need to return a Status anymore.

  • Form._onLifecycleLoad, Form._onLifecycleSave, Form._save, Form.save and Lifecycle._save: now return Promise<void>. There is no need to return a Status anymore. A load/save failure should return a rejected Promise and a successful load/save should return a resolved promise. In case of an error the Promise might be rejected with any error or a Status describing the error.

  • Form._handleLoadError: Returns Promise<void> which indicates that the error was handled. A rejected promise means the error could not be handled. In such a case no fallback is applied! It is therefore the developers responsibility to ensure the error was handled as desired.

FormField

Rename requiresSave to saveNeeded

The property requiresSave and the function updateRequiresSave on the FormField have been renamed to saveNeeded resp. updateSaveNeeded. This makes it consistent with the property saveNeededVisible on the Form and also with Scout Classic.

To migrate it is best to search for requiresSave resp. RequiresSave in your JS/TS code base and replace the occurrences accordingly.

VisitFields Now Visits Deeper

The visiting is not limited to composite fields anymore which means more fields may be visited, see Release Notes. If you need the old behavior, you can use the option limitToSameFieldTree in the options parameter of the visitFields method.

Touched not Affected by Value Change Anymore

A form field has a property touched which can be set by using touch(). A touched form field needs to be saved. Until now, a value change (by the user or by using setValue) set this property to true. This has been changed so that a value change does not change the property anymore, it can only be modified using touch() resp. markAsSaved(). This has the benefit that touched can be completely controlled by the developer.

In order to check if a value has been changed or a field touched you can use the property saveNeeded.

Busy handling

The busy handling has been simplified for Scout JS (see Release Notes).

The Form.load and Form.save methods now automatically include a busy indicator. Custom busy indicators for these two operations (e.g. when performing a Rest call) can therefore be removed.

The method Session.setBusy was moved to Desktop.setBusy. So instead of calling session.setBusy(…​) use session.desktop.setBusy(…​).

The MenuType constants and types were renamed from MenuTypes to MenuType:

Constants:

  • Calendar.MenuTypesCalendar.MenuType

  • ImageField.MenuTypesImageField.MenuType

  • Planner.MenuTypesPlanner.MenuType

  • TabBox.MenuTypesTabBox.MenuType

  • Table.MenuTypesTable.MenuType

  • TileGrid.MenuTypesTileGrid.MenuType

  • Tree.MenuTypesTree.MenuType

  • ValueField.MenuTypesValueField.MenuType

Types:

  • CalendarMenuTypesCalendarMenuType

  • ImageFieldMenuTypesImageFieldMenuType

  • PlannerMenuTypesPlannerMenuType

  • TabBoxMenuTypesTabBoxMenuType

  • TableMenuTypesTableMenuType

  • TileGridMenuTypesTileGridMenuType

  • TreeMenuTypesTreeMenuType

  • ValueFieldMenuTypesValueFieldMenuType