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
Scout JS now supports DataObjects to be written as classes in TypeScript.
A new serialization mechanisms takes care of recursively (de)serializing such DataObjects in a way compatible with the Scout Java backends.
It supports base types like number
, string
, boolean
, but also more complex types like Array
, Date
, Map
, Set
or nested Data Objects.
Also, TypeScript specific types like Record
or string literal types are supported.
It is recommended to switch to the new API where possible by following these steps:
-
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 theDo
suffix and must match the@TypeName
annotation of the matching Java Data Object class.2 Convert to a class extending BaseDoEntity
. -
If sending or receiving Data Objects to/from the Scout backend migrate the ajax calls to the newly provided convenience methods for Data Objects:
-
ajax.getDataObject
:GET
request receiving a Data Object. -
ajax.postDataObject
:POST
request sending and receiving a Data Object. -
ajax.putDataObject
:PUT
request sending and receiving a Data Object. -
ajax.removeDataObject
:DELETE
request sending and receiving a Data Object.
-
-
The new (de)serialization mechanism converts most of the data types automatically between its
json
format and the Data Object class. Therefore, manual conversions (e.g. forDate
) can be removed. This includes the use of utilities likeJsonValueMapper
,objects.parseJson
orobjects.stringifyJson
. Accordingly, these functions have been removed. If custom data types need to be converted, try implementing aDoNodeSerializer
in TypeScript and register your new converter indataObjects.serializers
. -
As Data Objects are classes now, they can no longer be created as object literals (Pojo). Instead,
scout.create
should be used:import {scout} from '@eclipse-scout/core'; const entityDo = scout.create(MyEntityDo, { entityId: '12345', ... });
-
To create a shallow copy of a Data Object a new instance must be created as well:
import {scout} from '@eclipse-scout/core'; const shallowCopy = scout.create(MyEntityDo, { ...originalEntityDo, additionalPropertyForTheCopy: 'ShallowCopyWillHaveThisAdditionalValue' });
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 likeDate
orMap
in this extra model are copied by value! -
When using the
HybridManager
or theJsForm
: 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 forHybridManager
orJsForm
, 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).
An example implementation can be found in the REST HowTo.