Eclipse Scout Migration Guide
About This Document
This document describes all relevant changes from Eclipse Scout 25.1 to Eclipse Scout 25.2. If existing code has to be migrated, instructions are provided here.
The here described functionality has not yet been released and is part of an upcoming release. |
Obtaining the Latest Version
Scout Runtime for Java
Scout Runtime artifacts for Java are distributed using Maven Central:
-
25.1.0-beta.5 on Maven Central
-
25.1.0-beta.5 on mvnrepository.com
Usage example in the parent POM of your Scout application:
<dependency>
<groupId>org.eclipse.scout.rt</groupId>
<artifactId>org.eclipse.scout.rt</artifactId>
<version>25.1.0-beta.5</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": "25.1.0-beta.5",
"@eclipse-scout/releng": "^25.1.0"
},
"dependencies": {
"@eclipse-scout/core": "25.1.0-beta.5",
"jquery": "3.7.1"
}
}
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
Table: column.sortActive Can Be Removed if sortIndex Is Set (Scout JS)
For Scout JS tables, sortActive
is now automatically set to true if sortIndex
is >= 0.
This means you can remove sortActive: true
from your model files if you set a valid sortIndex
.
{
objectType: Column,
sortActive: true,
sortIndex: 0
}
{
objectType: Column,
sortIndex: 0
}
Deprecation of GzipServletFilter
and LegacyGzipServletFilter
org.eclipse.scout.rt.server.commons.servlet.filter.gzip.GzipServletFilter
and
org.eclipse.scout.rt.server.commons.servlet.filter.gzip.LegacyGzipServletFilter
have been deprecated and should not be used anymore.
Among other things these filters do not support async requests which are used in some parts of the application.
If an applications keeps using the deprecated filters a warning will be logged during initialization of these classes.
Instead of these filters the Jetty built-in org.eclipse.jetty.server.handler.gzip.GzipHandler
should be used.
This handler has been added to the main class org.eclipse.scout.rt.app.Application
and is enabled by default.
It may be configured and also disabled using several new configuration properties:
-
scout.app.gzip.enabled
: Boolean (default: true); specifies whether theGzipHandler
is used -
scout.app.gzip.excluded.inflate.paths
: List of String; excluded inflate paths forGzipHandler
(respected only if at least one is set otherwise Jetty default is used) -
scout.app.gzip.excluded.methods
: List of String; excluded methods forGzipHandler
(respected only if at least one is set otherwise Jetty default is used) -
scout.app.gzip.excluded.mimeTypes
: List of String; excluded MIME types forGzipHandler
(respected only if at least one is set otherwise Jetty default is used) -
scout.app.gzip.excluded.paths
: List of String; excluded paths forGzipHandler
(respected only if at least one is set otherwise Jetty default is used) -
scout.app.gzip.included.inflate.paths
: List of String; included inflate paths forGzipHandler
(respected only if at least one is set otherwise Jetty default is used) -
scout.app.gzip.included.methods
: List of String; included methods forGzipHandler
(respected only if at least one is set otherwise Jetty default is used) -
scout.app.gzip.included.mimeTypes
: List of String; included MIME types forGzipHandler
(respected only if at least one is set otherwise Jetty default is used) -
scout.app.gzip.included.paths
: List of String; included paths forGzipHandler
(respected only if at least one is set otherwise Jetty default is used) -
scout.app.gzip.minSize
: Positive integer; minimum size to trigger compression forGzipHandler
(respected only if at value is set otherwise Jetty default is used) -
scout.app.gzip.syncFlush
: Boolean (default: true); enables sync flush forGzipHandler
If the application is not run using the recommended main class org.eclipse.scout.rt.app.Application
, e.g. for .war deployments the GzipHandler
is not registered automatically.
For example for a Jetty .war deployment it may be registered by activating the gzip
Jetty module.
Switch to the New Data Object API
Please read the DO documentation for Scout JS for more details and the advantages of the new API. An example implementation can be found in the REST HowTo which might be helpful to understand the new concepts.
Follow these steps to switch to the new API:
-
Convert existing DOs (typically declared as TypeScript interfaces extending
DoEntity
) to classes. ThetypeName
must be declared as Decorator (like Java Annotations but first character lowercase):import {BaseDoEntity, typeName} from '@eclipse-scout/core'; @typeName('mynamespace.MyEntity') (1) export class MyEntityDo extends BaseDoEntity { (2) entityId: string; timestamp: Date; items: Record<string, MyOtherDo>; descriptions: Map<string, DescriptionDo>; attachments: AttachmentDo[]; }
1 | Declare the typeName of the Data Object as decorator. Typically, this is the class name without the Do suffix and must match the @TypeName annotation of the matching Java Data Object class. |
2 | Convert to a class extending BaseDoEntity .
|
Important: If the spread operator is not the first statement, you need to convert the DO to a Pojo first (.toPojo()
), otherwise undefined values from the DO may override actual values.
Therefore, it is recommended to always use the original Data Object as the first spread statement.
. To create a deep copy of a Data Object use the clone
function:
+
const deepCopy = originalEntityDo.clone({
additionalPropertyForTheCopy: 'DeepCopyWillHaveThisAdditionalValue'
});
Important: In the (optional) extra model passed to the clone
function only primitives and pojos are copied deeply.
Complex objects like Date
or Map
in this extra model are copied by value!
. When using the HybridManager
or the JsForm
: It uses the Data Object class and deserializes to these classes (instead of a Pojo as before) as soon as a class having a matching @typeName
decorator is found in TypeScript.
So to use the new API for HybridManager
or JsForm
, just create the necessary Data Object classes. But keep in mind that as soon it is converted, these instances will be returned instead of a Pojo.
So this might require some more code migrations on your side (see above).
Generic Type Parameter for putIf()
Method
The putIf
method on IDoEntity and DoEntityBuilder has been updated to use a generic type parameter for the value
and predicate
arguments.
This ties the predicate to the type of the value, making it easier to use and reducing the need for type casting.
// Before
result.putIf("name", myName, o -> StringUtility.hasText((String) o));
// After
result.putIf("name", myName, StringUtility::hasText);
Migration: Check usages in your code and remove now-redundant type casts.
Hybrid actions
All IHybridAction
are now using a namespace and typed data objects instead of IDoEntity
.
If you are calling some of the provided IHybridAction
, please check if you need to enhance the actionType
or send typed data objects.
disposeWidgets(widgetIds: string[]) {
HybridManager.get(this.session).callAction('scout.DisposeWidgets', scout.create(DisposeWidgetsHybridActionDo, {
ids: widgetIds
}));
}
The DisposeWidgetsHybridAction
in this example belongs to the namespace scout and the data passed to it needs to be a DisposeWidgetsHybridActionDo
.
The changed IHybridAction
are:
-
DisposeWidgetsHybridAction
: namespace was added-
action type was changed from
DisposeWidgets
toscout.DisposeWidgets
-
-
AbstractFormHybridAction
: namespace was added-
action types were changed from
openForm
andcreateForm
toscout.openForm
andscout.createForm
-
Table default row action
The Table
now supports a defaultRowAction
(see Release Notes).
Therefore, it is no longer necessary to listen on rowAction
events in order to execute a Menu
rowAction
event in order to execute MyMenu
table.on('rowAction', e => table.widget('MyMenu').doAction());
defaultRowAction
property in the TableModel
defaultRowAction: 'MyMenu',
menus: [{
id: 'MyMenu',
objectType: Menu
}]
With the changes made for this feature the method Table._triggerRowAction
was removed.
Classes overriding this method in order to execute additional logic or prevent the rowAction
events from being triggered can simply listen on rowAction
and execute the logic in an event handler or prevent the default.