diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c7b184c1334..c2baa5c0347 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -2,9 +2,9 @@ name: CI
on:
push:
- branches: [ "releases/26.1" ]
+ branches: [ "releases/26.2" ]
pull_request:
- branches: [ "releases/26.1" ]
+ branches: [ "releases/26.2" ]
jobs:
build:
diff --git a/README.md b/README.md
index eecb8fcc5cf..c4d402aede7 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ This repository contains the source code of the runtime components, the actual f
If you are completely new and wondering what Eclipse Scout is, please visit our [website](https://eclipse.dev/scout/).
-To get started with Scout, follow our [Get Started Guide](https://eclipsescout.github.io/scout-docs/26.1/getstarted/getstarted.html).
+To get started with Scout, follow our [Get Started Guide](https://eclipsescout.github.io/scout-docs/26.2/getstarted/getstarted.html).
## Documentation
diff --git a/eclipse-scout-chart/README.md b/eclipse-scout-chart/README.md
index 7bd7f50d650..60e9b4fb474 100644
--- a/eclipse-scout-chart/README.md
+++ b/eclipse-scout-chart/README.md
@@ -3,8 +3,8 @@
-
-
+
+
@@ -22,7 +22,7 @@ This module contains the web runtime components running in the browser.
If you are completely new and wondering what Eclipse Scout is, please visit our [website](https://eclipse.dev/scout/).
-To get started with Scout, follow our [Get Started Guide](https://eclipsescout.github.io/scout-docs/26.1/getstarted/getstarted.html).
+To get started with Scout, follow our [Get Started Guide](https://eclipsescout.github.io/scout-docs/26.2/getstarted/getstarted.html).
## Documentation
diff --git a/eclipse-scout-core/package.json b/eclipse-scout-core/package.json
index 0976f61257c..4010bee24fa 100644
--- a/eclipse-scout-core/package.json
+++ b/eclipse-scout-core/package.json
@@ -1,6 +1,6 @@
{
"name": "@eclipse-scout/core",
- "version": "26.1.0-snapshot",
+ "version": "26.2.0-snapshot",
"description": "Eclipse Scout runtime",
"author": "BSI Business Systems Integration AG",
"homepage": "https://eclipse.dev/scout/",
@@ -63,7 +63,7 @@
"version:release": "releng-scripts version:release"
},
"devDependencies": {
- "@eclipse-scout/cli": ">=26.1.0-snapshot <26.1.0",
+ "@eclipse-scout/cli": ">=26.2.0-snapshot <26.2.0",
"@eclipse-scout/releng": "^26.1.0",
"jasmine-core": "5.13.0",
"jasmine-ajax": "4.0.0",
diff --git a/eclipse-scout-core/pom.xml b/eclipse-scout-core/pom.xml
index 131d9db8f9a..39af30ec336 100644
--- a/eclipse-scout-core/pom.xml
+++ b/eclipse-scout-core/pom.xml
@@ -16,7 +16,7 @@
org.eclipse.scout.rtorg.eclipse.scout.rt
- 26.1-SNAPSHOT
+ 26.2-SNAPSHOT../org.eclipse.scout.rt
diff --git a/eclipse-scout-core/src/bookmark/BookmarkDoBuilder.ts b/eclipse-scout-core/src/bookmark/BookmarkDoBuilder.ts
index 8c95cbfd707..af8dff46b0d 100644
--- a/eclipse-scout-core/src/bookmark/BookmarkDoBuilder.ts
+++ b/eclipse-scout-core/src/bookmark/BookmarkDoBuilder.ts
@@ -8,9 +8,8 @@
* SPDX-License-Identifier: EPL-2.0
*/
import {
- arrays, BaseDoEntity, BookmarkDo, BookmarkDoBuilderModel, BookmarkSupport, BookmarkTableRowIdentifierDo, ChartTableControlConfigHelper, Desktop, Form, IBookmarkDefinitionDo, IBookmarkDo, IBookmarkPageDo, IChartTableControlConfigDo,
- InitModelOf, NodeBookmarkPageDo, objects, ObjectWithType, OutlineBookmarkDefinitionDo, Page, PageBookmarkDefinitionDo, PageWithTable, scout, Session, strings, TableBookmarkPageDo, TableClientUiPreferencesDo, TableUiPreferences,
- tableUiPreferences
+ arrays, BookmarkDo, BookmarkDoBuilderModel, BookmarkSupport, BookmarkTableRowIdentifierDo, ChartTableControlConfigHelper, Desktop, Form, IBookmarkDefinitionDo, IBookmarkDo, IBookmarkPageDo, IChartTableControlConfigDo, InitModelOf,
+ NodeBookmarkPageDo, ObjectWithType, OutlineBookmarkDefinitionDo, Page, PageBookmarkDefinitionDo, PageWithTable, scout, Session, strings, TableBookmarkPageDo, TableClientUiPreferencesDo, TableUiPreferences, tableUiPreferences
} from '../index';
export class BookmarkDoBuilder implements ObjectWithType, BookmarkDoBuilderModel {
@@ -36,6 +35,9 @@ export class BookmarkDoBuilder implements ObjectWithType, BookmarkDoBuilderModel
createTablePreferences: boolean;
createTableRowSelections: boolean;
+ // Map to store texts computed by _tablePageToTableBookmarkPage() for later use in _createBookmarkDescription()
+ protected _searchFilterTexts = new Map();
+
// --------------------------------------
constructor() {
@@ -163,7 +165,7 @@ export class BookmarkDoBuilder implements ObjectWithType, BookmarkDoBuilderModel
throw BookmarkDoBuilder.ERROR_MISSING_ROW_BOOKMARK_IDENTIFIER;
}
- return scout.create(TableBookmarkPageDo, {
+ let bookmarkPage = scout.create(TableBookmarkPageDo, {
pageParam: page.pageParam,
displayText: page.getDisplayText(),
expandedChildRow: expandedChildRowIdentifier,
@@ -173,6 +175,16 @@ export class BookmarkDoBuilder implements ObjectWithType, BookmarkDoBuilderModel
tablePreferences: tablePreferences,
chartTableControlConfig: chartTableControlConfig
});
+
+ // Compute search filter text and put it into a map for later use in _createBookmarkDescription()
+ if (this.createDescription && searchData) {
+ let searchFilterText = await page.getSearchFilterText();
+ if (searchFilterText) {
+ this._searchFilterTexts.set(bookmarkPage, searchFilterText);
+ }
+ }
+
+ return bookmarkPage;
}
protected _createExpandedTableRowIdentifier(page: PageWithTable, childPage: Page): BookmarkTableRowIdentifierDo {
@@ -275,18 +287,19 @@ export class BookmarkDoBuilder implements ObjectWithType, BookmarkDoBuilderModel
let lines = [];
pagePath.forEach((bookmarkPage, index) => {
- let prefix = strings.repeat(' ', index);
+ let indent = ' ';
+ let prefix = strings.repeat(indent, index);
let displayText = bookmarkPage.displayText || this.session.text('Node');
lines.push(prefix + displayText);
- if (bookmarkPage instanceof TableBookmarkPageDo && bookmarkPage.searchData) {
- let searchData = bookmarkPage.searchData instanceof BaseDoEntity ? bookmarkPage.searchData.toPojo() : bookmarkPage.searchData;
- Object.keys(searchData)
- .filter(key => !strings.startsWith(key, '_'))
- .filter(key => !objects.isNullOrUndefinedOrEmpty(searchData[key]))
- .map(key => key + ': ' + JSON.stringify((searchData)[key]))
- .forEach(searchLine => lines.push(prefix + ' ' + searchLine));
+ if (bookmarkPage instanceof TableBookmarkPageDo) {
+ // Get search filter text added by _tablePageToTableBookmarkPage()
+ let searchFilterText = this._searchFilterTexts.get(bookmarkPage);
+ // Split search filter text into lines and add them to the description (with additional indentation)
+ if (searchFilterText) {
+ lines.push(...searchFilterText.split('\n').map(s => prefix + indent + s));
+ }
}
});
return lines.join('\n');
diff --git a/eclipse-scout-core/src/form/Form.ts b/eclipse-scout-core/src/form/Form.ts
index a88b6660d84..b46331c7a9a 100644
--- a/eclipse-scout-core/src/form/Form.ts
+++ b/eclipse-scout-core/src/form/Form.ts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2026 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -8,10 +8,10 @@
* SPDX-License-Identifier: EPL-2.0
*/
import {
- AbortKeyStroke, App, aria, AriaLabelledByInsertPosition, arrays, BusyIndicatorOptions, Button, ButtonSystemType, DialogLayout, DisabledStyle, DisplayParent, DisplayViewId, EnumObject, ErrorHandler, Event, EventHandler, FileChooser,
- FileChooserController, FocusRule, FormController, FormEventMap, FormGrid, FormInvalidEvent, FormLayout, FormLifecycle, FormModel, FormRevealInvalidFieldEvent, GlassPaneRenderer, GroupBox, HtmlComponent, InitModelOf, KeyStroke,
- KeyStrokeContext, MessageBox, MessageBoxController, MessageBoxes, NotificationBadgeStatus, ObjectOrChildModel, objects, Point, PopupWindow, PropertyChangeEvent, Rectangle, scout, Status, StatusOrModel, strings, tooltips, TreeVisitResult,
- ValidationResult, webstorage, Widget, WrappedFormField
+ AbortKeyStroke, App, aria, AriaLabelledByInsertPosition, arrays, BusyIndicatorOptions, Button, ButtonSystemType, ChildModelOf, DialogLayout, DisabledStyle, DisplayParent, DisplayViewId, EnumObject, ErrorHandler, Event, EventHandler,
+ FileChooser, FileChooserController, FocusRule, FormController, FormEventMap, FormGrid, FormInvalidEvent, FormLayout, FormLifecycle, FormModel, FormRevealInvalidFieldEvent, GlassPaneRenderer, GroupBox, HtmlComponent, InitModelOf,
+ KeyStroke, KeyStrokeContext, MessageBox, MessageBoxController, MessageBoxes, ModelOf, NotificationBadgeStatus, ObjectOrChildModel, objects, Point, PopupWindow, PropertyChangeEvent, Rectangle, scout, Status, StatusOrModel, strings,
+ tooltips, TreeVisitResult, ValidationResult, webstorage, Widget, WrappedFormField
} from '../index';
import $ from 'jquery';
@@ -321,13 +321,40 @@ export class Form extends Widget implements FormModel, DisplayParent {
}
protected _createLifecycle(): FormLifecycle {
- return scout.create(FormLifecycle, {
- widget: this,
+ // already created
+ if (this.lifecycle instanceof FormLifecycle) {
+ return this.lifecycle;
+ }
+
+ const defaultModel: ModelOf = {
askIfNeedSave: this.askIfNeedSave,
+ askIfNeedSaveText: this.askIfNeedSaveText,
emptyMandatoryElementsText: this.emptyMandatoryElementsText,
invalidElementsErrorText: this.invalidElementsErrorText,
- invalidElementsWarningText: this.invalidElementsWarningText,
- askIfNeedSaveText: this.askIfNeedSaveText
+ invalidElementsWarningText: this.invalidElementsWarningText
+ };
+
+ // object type
+ if (typeof this.lifecycle === 'string' || typeof this.lifecycle === 'function') {
+ return scout.create(this.lifecycle, {
+ ...defaultModel,
+ widget: this
+ });
+ }
+
+ // child model
+ if (objects.isPojo(this.lifecycle)) {
+ return scout.create({
+ objectType: FormLifecycle,
+ ...defaultModel,
+ ...this.lifecycle as ChildModelOf,
+ widget: this
+ }) as FormLifecycle;
+ }
+
+ return scout.create(FormLifecycle, {
+ ...defaultModel,
+ widget: this
});
}
diff --git a/eclipse-scout-core/src/form/FormModel.ts b/eclipse-scout-core/src/form/FormModel.ts
index c479487d88f..1e6336807c9 100644
--- a/eclipse-scout-core/src/form/FormModel.ts
+++ b/eclipse-scout-core/src/form/FormModel.ts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2024 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2026 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -7,7 +7,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-import {DisplayHint, DisplayParent, DisplayParentModel, DisplayViewId, Form, FormValidator, GroupBox, ObjectOrChildModel, StatusOrModel, Widget, WidgetModel} from '../index';
+import {ChildModelOf, DisplayHint, DisplayParent, DisplayParentModel, DisplayViewId, Form, FormLifecycle, FormValidator, GroupBox, ObjectOrChildModel, ObjectType, StatusOrModel, Widget, WidgetModel} from '../index';
export interface FormModel extends WidgetModel, DisplayParentModel {
/**
@@ -230,4 +230,8 @@ export interface FormModel extends WidgetModel, DisplayParentModel {
* By default, the list is empty.
*/
validators?: FormValidator[];
+ /**
+ * Defines the {@link FormLifecycle} for this form.
+ */
+ lifecycle?: ObjectType | ChildModelOf;
}
diff --git a/eclipse-scout-core/src/status/NotificationBadgeStatus.ts b/eclipse-scout-core/src/status/NotificationBadgeStatus.ts
index 176fe470c95..8178d4dc43b 100644
--- a/eclipse-scout-core/src/status/NotificationBadgeStatus.ts
+++ b/eclipse-scout-core/src/status/NotificationBadgeStatus.ts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2024 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2026 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -19,19 +19,4 @@ export class NotificationBadgeStatus extends Status {
override cssClass(): string {
return strings.join(' ', Status.cssClassForSeverity(this.severity), 'notification-badge');
}
-
- /**
- * @returns {NotificationBadgeStatus} a clone of this Status instance.
- */
- override clone(): Status {
- let modelClone = $.extend({}, this);
- return new NotificationBadgeStatus(modelClone);
- }
-
- override equals(o: any): boolean {
- if (!(o instanceof NotificationBadgeStatus)) {
- return false;
- }
- return super.equals(o);
- }
}
diff --git a/eclipse-scout-core/src/status/Status.ts b/eclipse-scout-core/src/status/Status.ts
index 55fc5ca0d8d..8a8b1a02618 100644
--- a/eclipse-scout-core/src/status/Status.ts
+++ b/eclipse-scout-core/src/status/Status.ts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2026 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -7,7 +7,9 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-import {arrays, DefaultStatus, EnumObject, FullModelOf, InitModelOf, NotificationBadgeStatus, ObjectOrModel, objects, ObjectWithType, ParsingFailedStatus, Predicate, scout, StatusModel, strings, ValidationFailedStatus} from '../index';
+import {
+ arrays, Constructor, DefaultStatus, EnumObject, FullModelOf, InitModelOf, NotificationBadgeStatus, ObjectOrModel, objects, ObjectWithType, ParsingFailedStatus, Predicate, scout, StatusModel, strings, ValidationFailedStatus
+} from '../index';
import $ from 'jquery';
export class Status implements StatusModel, ObjectWithType {
@@ -87,21 +89,20 @@ export class Status implements StatusModel, ObjectWithType {
}
/**
- * @returns a clone of this Status instance.
+ * @returns a deep clone of this Status instance.
*/
- clone(): Status {
- let modelClone = $.extend({}, this);
- return new Status(modelClone);
+ clone(): this {
+ return objects.copyPropertiesRecursive(this, new (this.constructor as Constructor)());
}
equals(o: any): boolean {
- if (!(o instanceof Status)) {
+ if (this.constructor !== o?.constructor) {
return false;
}
if (!objects.equalsRecursive(this.children, o.children)) {
return false;
}
- return objects.propertiesEquals(this, o, ['severity', 'message', 'invalidDate', 'invalidTime']);
+ return objects.propertiesEquals(this, o, ['severity', 'message', 'invalidDate'/* used by DateField */, 'invalidTime'/* used by DateField */]);
}
/**
diff --git a/eclipse-scout-core/src/table/TableHeader.ts b/eclipse-scout-core/src/table/TableHeader.ts
index d78ff759fad..87f9e8f8bca 100644
--- a/eclipse-scout-core/src/table/TableHeader.ts
+++ b/eclipse-scout-core/src/table/TableHeader.ts
@@ -670,6 +670,7 @@ export class TableHeader extends Widget implements TableHeaderModel {
if (scout.isOneOf(event.which, keys.ENTER, keys.SPACE)) {
this._doHeaderItemAction($(event.currentTarget));
event.stopPropagation();
+ event.preventDefault(); // Don't scroll when pressing space
}
}
diff --git a/eclipse-scout-core/src/tile/fields/tablefield/TileTableField.less b/eclipse-scout-core/src/tile/fields/tablefield/TileTableField.less
index 19c53bd2a4d..dbaa956f8ce 100644
--- a/eclipse-scout-core/src/tile/fields/tablefield/TileTableField.less
+++ b/eclipse-scout-core/src/tile/fields/tablefield/TileTableField.less
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2024 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2026 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -42,9 +42,8 @@
border-radius: 0;
background-color: transparent;
- &:focus,
- &.focused {
- box-shadow: none;
+ &:has(.table-data:is(:focus, .focused)) {
+ box-shadow: none !important;
}
& > .table-header {
@@ -86,21 +85,21 @@
}
}
- &:not(:focus):not(.focused) > .table-data > .table-row.selected {
- /* No selection color for non-focused table tiles */
- background-color: transparent;
-
- &::after {
- border: 0;
- }
- }
-
& > .table-data {
& + .scroll-shadow {
.scroll-shadow.gradient();
--scroll-shadow-color: var(--tile-background-color);
}
+ &:not(:is(:focus, .focused)) > .table-row.selected {
+ /* No selection color for non-focused table tiles */
+ background-color: transparent;
+
+ &::after {
+ border: 0;
+ }
+ }
+
& > .table-row {
& > .table-cell,
& > .table-cell > .font-icon {
diff --git a/eclipse-scout-core/src/tile/fields/tablefield/TileTableField.ts b/eclipse-scout-core/src/tile/fields/tablefield/TileTableField.ts
index ea9a8930fcc..6e7f1dad97f 100644
--- a/eclipse-scout-core/src/tile/fields/tablefield/TileTableField.ts
+++ b/eclipse-scout-core/src/tile/fields/tablefield/TileTableField.ts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2026 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -7,29 +7,35 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-import {EventHandler, FormFieldTile, MenuBar, PropertyChangeEvent, TableField} from '../../../index';
+import {EventHandler, focusUtils, FormFieldTile, MenuBar, PropertyChangeEvent, TableField} from '../../../index';
import $ from 'jquery';
export class TileTableField extends TableField {
- protected _tableBlurHandler: (event: JQuery.BlurEvent) => void;
- protected _tableFocusHandler: (event: JQuery.FocusEvent) => void;
protected _menuBarPropertyChangeHandler: EventHandler>;
protected _documentMouseDownHandler: (event: MouseEvent) => void;
constructor() {
super();
- this._tableBlurHandler = this._onTableBlur.bind(this);
- this._tableFocusHandler = this._onTableFocus.bind(this);
this._menuBarPropertyChangeHandler = this._onMenuBarPropertyChange.bind(this);
this._documentMouseDownHandler = this._onDocumentMouseDown.bind(this);
}
protected override _render() {
super._render();
+ if ((this.parent as FormFieldTile).displayStyle !== FormFieldTile.DisplayStyle.DASHBOARD) {
+ return;
+ }
+
if (!this.session.focusManager.restrictedFocusGain) {
this.$container.document(true).addEventListener('mousedown', this._documentMouseDownHandler, true);
}
+ this.$container
+ .on('focusout', this._onTileFocusOut.bind(this))
+ .on('focusin', this._onTileFocusIn.bind(this));
+ if (!focusUtils.isOrHasActiveElement(this.$container)) {
+ this._hideMenuBar(true);
+ }
}
protected override _remove() {
@@ -43,14 +49,8 @@ export class TileTableField extends TableField {
return;
}
if (this.table) {
- this.table.$container
- .on('blur', this._tableBlurHandler)
- .on('focus', this._tableFocusHandler);
this.table.menuBar.on('propertyChange', this._menuBarPropertyChangeHandler);
this._toggleHasMenuBar();
- if (document.activeElement !== this.table.$container[0]) {
- this._hideMenuBar(true);
- }
}
}
@@ -59,28 +59,39 @@ export class TileTableField extends TableField {
return;
}
if (this.table) {
- this.table.$container
- .off('blur', this._tableBlurHandler)
- .off('focus', this._tableFocusHandler);
this.table.menuBar.off('propertyChange', this._menuBarPropertyChangeHandler);
}
super._removeTable();
}
- protected _onTableBlur(event: JQuery.BlurEvent) {
+ protected _onTileFocusOut(event: JQuery.FocusOutEvent) {
+ if (this.$container.isOrHas(event.relatedTarget as Element)) {
+ // If focus stays in tile, don't remove menubar
+ return;
+ }
let popup = $('.popup').data('widget');
- // hide menu bar if context menu popup is not attached to TileTableField
- if (!this.has(popup)) {
- this._hideMenuBar(true);
- }
+ // Hide menu bar when focus leaves tile, but only if there is no popup open that belongs to the table (e.g. context menu or table header popup)
+ // If a popup is open, the focus is on the popup but the menubar should still be visible
+ requestAnimationFrame(() => {
+ if (!this.rendered) {
+ return;
+ }
+
+ if (!this.has(popup)) {
+ this._hideMenuBar(true);
+ }
+ });
}
- protected _onTableFocus(event: JQuery.FocusEvent) {
+ protected _onTileFocusIn(event: JQuery.FocusInEvent) {
this._hideMenuBar(false);
}
protected _hideMenuBar(hiddenByUi: boolean) {
+ if (!this.table) {
+ return;
+ }
this.table.menuBar.hiddenByUi = hiddenByUi;
this.table.menuBar.updateVisibility();
}
diff --git a/eclipse-scout-core/src/util/objects.ts b/eclipse-scout-core/src/util/objects.ts
index 8f6c70caaf0..709358e3637 100644
--- a/eclipse-scout-core/src/util/objects.ts
+++ b/eclipse-scout-core/src/util/objects.ts
@@ -217,6 +217,7 @@ export const objects = {
* * All objects (except Widget) having a `clone` function (expected to create a deep clone without taking any arguments). These are classes like `BaseDoEntity`, `Dimension`, `GridData`, `Insets`, `Point`, `Status`, `URL`, ...
* @param val The value to deep clone.
* @returns The deep clone if supported, the input value otherwise.
+ * @throws Error if the given value cannot be cloned.
*/
valueCopy(val: T): T {
if (objects.isPojo(val)) {
@@ -225,6 +226,9 @@ export const objects = {
if (objects.isArray(val)) {
return val.map(e => objects.valueCopy(e)) as T;
}
+ if (!objects.isObject(val)) {
+ return val; // primitives, null, undefined
+ }
return deepCloneClass(val); // handles all class types
},
@@ -234,6 +238,7 @@ export const objects = {
* All properties are recursively cloned using {@link objects#valueCopy}. Therefore, only properties of types supported by {@link objects#valueCopy} must be present.
* @param source Where to get the properties to copy.
* @param destination Where to store the cloned properties.
+ * @throws Error if a property cannot be cloned (see {@link objects#valueCopy} for details).
*/
copyPropertiesRecursive(source: T, destination: T): T {
for (const [k, v] of Object.entries(source)) {
@@ -900,7 +905,7 @@ function deepCloneClass(val: any): any {
}
}
- return val;
+ throw new Error(val.constructor + ' is not cloneable'); // clone not supported: a widget or no 'clone' function available
}
function equalsImpl(objA: any, objB: any, useEqualsFunc = true): boolean | null {
diff --git a/eclipse-scout-core/src/util/strings.ts b/eclipse-scout-core/src/util/strings.ts
index 891b5083401..ef80cf7bf29 100644
--- a/eclipse-scout-core/src/util/strings.ts
+++ b/eclipse-scout-core/src/util/strings.ts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2026 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -128,9 +128,11 @@ export const strings = {
},
/**
- * Returns the HTML encoded text. Example: 'Foo Bar' returns 'Foo<br>Bar'.
- * If the argument is or undefined, the same value is returned.
- * @param text plain text to encode
+ * Returns the HTML encoded text. If the text is falsy, the input value is returned.
+ *
+ * Example: 'Foo<br>Bar' returns 'Foo<br>Bar'.
+ *
+ * @param text text to encode
* @returns HTML encoded text
*/
encode(text: string): string {
diff --git a/eclipse-scout-core/src/widget/WidgetModel.ts b/eclipse-scout-core/src/widget/WidgetModel.ts
index c437574085d..4bfceb08925 100644
--- a/eclipse-scout-core/src/widget/WidgetModel.ts
+++ b/eclipse-scout-core/src/widget/WidgetModel.ts
@@ -20,7 +20,7 @@ export interface WidgetModel extends ObjectModelWithUuid, ObjectModelWit
* *Example*: {@link ViewMenuPopup} uses the {@link ViewButton}s as menu items. These view buttons are owned by the desktop and must therefore not be destroyed
* when the popup closes, otherwise they could not be reused the second time the popup opens.
*
- * @see https://eclipsescout.github.io/scout-docs/26.1/technical-guide/user-interface/widget.html#parent-and-owner
+ * @see https://eclipsescout.github.io/scout-docs/26.2/technical-guide/user-interface/widget.html#parent-and-owner
*/
parent?: Widget;
/**
@@ -29,7 +29,7 @@ export interface WidgetModel extends ObjectModelWithUuid, ObjectModelWit
*
* By default, the owner is derived from the {@link parent}, so it does not need to be set explicitly.
*
- * @see https://eclipsescout.github.io/scout-docs/26.1/technical-guide/user-interface/widget.html#parent-and-owner
+ * @see https://eclipsescout.github.io/scout-docs/26.2/technical-guide/user-interface/widget.html#parent-and-owner
*/
owner?: Widget;
/**
diff --git a/eclipse-scout-core/test/bookmark/BookmarkSupportSpec.ts b/eclipse-scout-core/test/bookmark/BookmarkSupportSpec.ts
index 02a63c481cd..ea79dc69c69 100644
--- a/eclipse-scout-core/test/bookmark/BookmarkSupportSpec.ts
+++ b/eclipse-scout-core/test/bookmark/BookmarkSupportSpec.ts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2026 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -9,7 +9,7 @@
*/
import {
- ActivateBookmarkPathParam, BaseDoEntity, BookmarkDo, BookmarkDoBuilder, BookmarkSupport, BookmarkTableRowIdentifierDo, BookmarkTableRowIdentifierStringComponentDo, BooleanColumn, Column, Desktop, NodeBookmarkPageDo, NumberColumn,
+ ActivateBookmarkPathParam, BaseDoEntity, BookmarkDo, BookmarkDoBuilder, BookmarkSupport, BookmarkTableRowIdentifierDo, BookmarkTableRowIdentifierStringComponentDo, BooleanColumn, Column, dates, Desktop, NodeBookmarkPageDo, NumberColumn,
NumberColumnUserFilter, NumberColumnUserFilterStateDo, Outline, OutlineBookmarkDefinitionDo, PageBookmarkDefinitionDo, PageIdDummyPageParamDo, ResetMenu, scout, SearchMenu, Table, TableBookmarkPageDo, TableClientUiPreferenceProfileDo,
TableClientUiPreferencesDo, TableColumnClientUiPreferenceDo, TableTextUserFilter, TableTextUserFilterStateDo, TableUiPreferences, UuidPool
} from '../../src/index';
@@ -33,6 +33,9 @@ describe('BookmarkSupport', () => {
});
desktop = session.desktop;
bookmarkSupport = BookmarkSupport.get(session);
+
+ session.textMap.add('Yes', 'Yes');
+ session.textMap.add('No', 'No');
});
// ---------------------------------------------------------------
@@ -187,7 +190,7 @@ describe('BookmarkSupport', () => {
expect(bookmark).toBeInstanceOf(BookmarkDo);
expect(bookmark.id).toBeUndefined();
expect(bookmark.title).toBe('Outline 1 - Table Page 3');
- expect(bookmark.description).toBe('Table Page 3\n text: "n"');
+ expect(bookmark.description).toBe('Table Page 3\n Text: n\n Show hidden values: No');
expect(bookmark.definition).toBeInstanceOf(OutlineBookmarkDefinitionDo);
let bookmarkDefinition = bookmark.definition as OutlineBookmarkDefinitionDo;
expect(bookmarkDefinition.outlineId).toBe(SPEC_OUTLINE_1_UUID);
@@ -198,7 +201,9 @@ describe('BookmarkSupport', () => {
expect(bookmarkedPage.pageParam).toBeInstanceOf(PageIdDummyPageParamDo);
expect((bookmarkedPage.pageParam as PageIdDummyPageParamDo).pageId).toBe(SPEC_TABLE_PAGE_3_UUID);
expect(bookmarkedPage.searchData).toBeInstanceOf(BaseDoEntity);
- expect((bookmarkedPage.searchData as BaseDoEntity).toPojo()).toEqual(scout.create(SpecSearchDo, {text: 'n'}).toPojo());
+ expect((bookmarkedPage.searchData as BaseDoEntity).toPojo()).toEqual(scout.create(SpecSearchDo, {
+ text: 'n', showHiddenValues: false, languages: [], creationDate: null
+ }).toPojo());
expect(bookmarkedPage.tablePreferences).toBeTruthy();
expect(bookmarkedPage.tablePreferences.tableId).toBe(`${SPEC_TABLE_PAGE_3_TABLE_UUID}|${SPEC_TABLE_PAGE_3_UUID}`);
@@ -322,7 +327,7 @@ describe('BookmarkSupport', () => {
outline.drillDown(page2);
await page2.ensureLoadChildren();
expect(page2.detailTable.rows.length).toBe(5);
- page2.setSearchFilter(scout.create(SpecSearchDo, {text: 'i'})); // Matches 'Pineapple' and 'Kiwi'
+ page2.setSearchFilter(scout.create(SpecSearchDo, {text: 'i', showHiddenValues: true})); // Matches 'Pineapple' and 'Kiwi'
page2.reloadPage();
await page2.ensureLoadChildren();
expect(page2.detailTable.rows.length).toBe(2);
@@ -355,7 +360,10 @@ describe('BookmarkSupport', () => {
outline.drillDown(page4);
await page4.ensureLoadChildren();
expect(page4.detailTable.rows.length).toBe(5);
- page4.setSearchFilter(scout.create(SpecSearchDo, {text: 'n'})); // Matches 'Banana', 'Pineapple' and 'Lemon'
+ jasmine.clock().install();
+ page4.setSearchFilter(scout.create(SpecSearchDo, {text: 'n', languages: [100, 300], creationDate: dates.create('1999-12-31')})); // Matches 'Banana', 'Pineapple' and 'Lemon'
+ jasmine.clock().tick(300); // wait for list box update the display text
+ jasmine.clock().uninstall();
page4.reloadPage();
await page4.ensureLoadChildren();
expect(page4.detailTable.rows.length).toBe(3);
@@ -372,7 +380,17 @@ describe('BookmarkSupport', () => {
expect(bookmark).toBeInstanceOf(BookmarkDo);
expect(bookmark.id).toBeUndefined();
expect(bookmark.title).toBe('Outline 2 - Node Page 3 - Table Page 2 - Kiwi - Table Page 2');
- expect(bookmark.description).toBe('Node Page 3\n Table Page 2\n text: "i"\n Kiwi\n Table Page 2\n text: "n"');
+ expect(bookmark.description).toBe('' +
+ 'Node Page 3\n' +
+ ' Table Page 2\n' +
+ ' Text: i\n' +
+ ' Show hidden values: Yes\n' +
+ ' Kiwi\n' +
+ ' Table Page 2\n' +
+ ' Text: n\n' +
+ ' Show hidden values: No\n' +
+ ' Languages: English, Italian\n' +
+ ' Creation date: 31.12.1999');
expect(bookmark.definition).toBeInstanceOf(OutlineBookmarkDefinitionDo);
let bookmarkDefinition = bookmark.definition as OutlineBookmarkDefinitionDo;
expect(bookmarkDefinition.outlineId).toBe(SPEC_OUTLINE_2_UUID);
@@ -390,7 +408,9 @@ describe('BookmarkSupport', () => {
expect((pagePathElement2.pageParam as PageIdDummyPageParamDo).pageId).toBe(SPEC_TABLE_PAGE_2_UUID);
expect(pagePathElement2.searchFilterComplete).toBe(true);
expect(pagePathElement2.searchData).toBeInstanceOf(BaseDoEntity);
- expect((pagePathElement2.searchData as BaseDoEntity).toPojo()).toEqual(scout.create(SpecSearchDo, {text: 'i'}).toPojo());
+ expect((pagePathElement2.searchData as BaseDoEntity).toPojo()).toEqual(scout.create(SpecSearchDo, {
+ text: 'i', showHiddenValues: true, languages: [], creationDate: null
+ }).toPojo());
expect(pagePathElement2.expandedChildRow).toBeInstanceOf(BookmarkTableRowIdentifierDo);
expect(pagePathElement2.expandedChildRow.toPojo()).toEqual(scout.create(BookmarkTableRowIdentifierDo, {
keyComponents: [scout.create(BookmarkTableRowIdentifierStringComponentDo, {key: FRUIT_5_KEY})]
@@ -408,7 +428,9 @@ describe('BookmarkSupport', () => {
expect(bookmarkedPage.pageParam).toBeInstanceOf(PageIdDummyPageParamDo);
expect((bookmarkedPage.pageParam as PageIdDummyPageParamDo).pageId).toBe(SPEC_TABLE_PAGE_2_UUID);
expect(bookmarkedPage.searchData).toBeInstanceOf(BaseDoEntity);
- expect((bookmarkedPage.searchData as BaseDoEntity).toPojo()).toEqual(scout.create(SpecSearchDo, {text: 'n'}).toPojo());
+ expect((bookmarkedPage.searchData as BaseDoEntity).toPojo()).toEqual(scout.create(SpecSearchDo, {
+ text: 'n', showHiddenValues: false, languages: [100, 300], creationDate: dates.create('1999-12-31')
+ }).toPojo());
expect(bookmarkedPage.expandedChildRow).toBe(null);
expect(bookmarkedPage.selectedChildRows.length).toBe(0); // selected rows are not exported by default
});
@@ -482,7 +504,7 @@ describe('BookmarkSupport', () => {
expect(bookmark).toBeInstanceOf(BookmarkDo);
expect(bookmark.id).toBeUndefined();
expect(bookmark.title).toBe('Outline 3 - Table Page 2 - Kiwi');
- expect(bookmark.description).toBe('Table Page 2\n text: "i"\n Kiwi');
+ expect(bookmark.description).toBe('Table Page 2\n Text: i\n Show hidden values: No\n Kiwi');
expect(bookmark.definition).toBeInstanceOf(OutlineBookmarkDefinitionDo);
let bookmarkDefinition = bookmark.definition as OutlineBookmarkDefinitionDo;
expect(bookmarkDefinition.outlineId).toBe(SPEC_OUTLINE_3_UUID);
@@ -495,7 +517,9 @@ describe('BookmarkSupport', () => {
expect((pagePathElement1.pageParam as PageIdDummyPageParamDo).pageId).toBe(SPEC_TABLE_PAGE_2_UUID);
expect(pagePathElement1.searchFilterComplete).toBe(true);
expect(pagePathElement1.searchData).toBeInstanceOf(BaseDoEntity);
- expect((pagePathElement1.searchData as BaseDoEntity).toPojo()).toEqual(scout.create(SpecSearchDo, {text: 'i'}).toPojo());
+ expect((pagePathElement1.searchData as BaseDoEntity).toPojo()).toEqual(scout.create(SpecSearchDo, {
+ text: 'i', showHiddenValues: false, languages: [], creationDate: null
+ }).toPojo());
expect(pagePathElement1.expandedChildRow).toBeInstanceOf(BookmarkTableRowIdentifierDo);
expect(pagePathElement1.expandedChildRow.toPojo()).toEqual(scout.create(BookmarkTableRowIdentifierDo, {
keyComponents: [scout.create(BookmarkTableRowIdentifierStringComponentDo, {key: FRUIT_5_KEY})]
diff --git a/eclipse-scout-core/test/bookmark/bookmark-fixtures.ts b/eclipse-scout-core/test/bookmark/bookmark-fixtures.ts
index 0f93877bd2a..7c3292998dd 100644
--- a/eclipse-scout-core/test/bookmark/bookmark-fixtures.ts
+++ b/eclipse-scout-core/test/bookmark/bookmark-fixtures.ts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2026 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -8,9 +8,10 @@
* SPDX-License-Identifier: EPL-2.0
*/
import {
- BaseDoEntity, BooleanColumn, Column, Desktop, DesktopModel, Form, FormModel, GroupBox, NumberColumn, ObjectOrModel, Outline, OutlineViewButton, Page, PageParamDo, PageWithNodes, PageWithTable, ResetMenu, scout, SearchFormTableControl,
- SearchMenu, StringField, strings, Table, TableRow, Tree, typeName
+ BaseDoEntity, BooleanColumn, CheckBoxField, Column, DateField, Desktop, DesktopModel, Form, FormModel, GroupBox, ListBox, NumberColumn, ObjectOrModel, Outline, OutlineViewButton, Page, PageParamDo, PageWithNodes, PageWithTable, ResetMenu,
+ scout, SearchFormTableControl, SearchMenu, StringField, strings, Table, TableRow, Tree, typeName
} from '../../src';
+import {LanguageDummyLookupCall} from '../../src/testing';
// ---------------------------------------------------------------
//
@@ -146,6 +147,9 @@ export class SpecPageParamDo extends PageParamDo {
@typeName('SpecSearch')
export class SpecSearchDo extends BaseDoEntity {
text: string;
+ showHiddenValues: boolean;
+ languages: number[];
+ creationDate: Date;
}
export class SpecNodePage1 extends PageWithNodes {
@@ -422,6 +426,9 @@ export class SpecSearchForm extends Form {
declare data: SpecSearchDo;
declare widgetMap: {
'TextField': StringField;
+ 'ShowHiddenValuesField': CheckBoxField;
+ 'LanguagesField': ListBox;
+ 'CreationDateField': DateField;
'SearchMenu': SearchMenu;
'ResetMenu': ResetMenu;
};
@@ -435,6 +442,19 @@ export class SpecSearchForm extends Form {
id: 'TextField',
objectType: StringField,
label: 'Text'
+ }, {
+ id: 'ShowHiddenValuesField',
+ objectType: CheckBoxField,
+ label: 'Show hidden values'
+ }, {
+ id: 'LanguagesField',
+ objectType: ListBox,
+ label: 'Languages',
+ lookupCall: LanguageDummyLookupCall
+ }, {
+ id: 'CreationDateField',
+ objectType: DateField,
+ label: 'Creation date'
}],
menus: [{
id: 'SearchMenu',
@@ -452,11 +472,17 @@ export class SpecSearchForm extends Form {
return;
}
this.widget('TextField').setValue(this.data.text);
+ this.widget('ShowHiddenValuesField').setValue(this.data.showHiddenValues);
+ this.widget('LanguagesField').setValue(this.data.languages);
+ this.widget('CreationDateField').setValue(this.data.creationDate);
}
override exportData(): any {
return scout.create(SpecSearchDo, {
- text: this.widget('TextField').value
+ text: this.widget('TextField').value,
+ showHiddenValues: this.widget('ShowHiddenValuesField').value,
+ languages: this.widget('LanguagesField').value,
+ creationDate: this.widget('CreationDateField').value
});
}
}
diff --git a/eclipse-scout-core/test/form/FormSpec.ts b/eclipse-scout-core/test/form/FormSpec.ts
index a74e0dea4d6..c2914a3ac52 100644
--- a/eclipse-scout-core/test/form/FormSpec.ts
+++ b/eclipse-scout-core/test/form/FormSpec.ts
@@ -9,8 +9,8 @@
*/
import {FormSpecHelper, OutlineSpecHelper, SpecForm} from '../../src/testing/index';
import {
- App, CancelMenu, CloseMenu, Dimension, fields, FileChooser, Form, FormFieldMenu, FormModel, InitModelOf, MessageBox, NotificationBadgeStatus, NullWidget, NumberField, ObjectFactory, OkMenu, Outline, Page, Popup, PopupBlockerHandler,
- Rectangle, ResetMenu, SaveMenu, scout, SearchMenu, SequenceBox, Session, SplitBox, Status, StringField, strings, TabBox, TabItem, webstorage, WidgetModel, WrappedFormField
+ App, CancelMenu, CloseMenu, Dimension, fields, FileChooser, Form, FormFieldMenu, FormLifecycle, FormModel, InitModelOf, MessageBox, NotificationBadgeStatus, NullWidget, NumberField, ObjectFactory, OkMenu, Outline, Page, Popup,
+ PopupBlockerHandler, Rectangle, ResetMenu, SaveMenu, scout, SearchMenu, SequenceBox, Session, SplitBox, Status, StringField, strings, TabBox, TabItem, webstorage, WidgetModel, WrappedFormField
} from '../../src/index';
import {DateField, GroupBox} from '../../src';
@@ -32,6 +32,10 @@ describe('Form', () => {
helper = new FormSpecHelper(session);
outlineHelper = new OutlineSpecHelper(session);
uninstallUnloadHandlers(session);
+ session.textMap.add('FormSaveChangesQuestion', 'Do you want to save the changes?');
+ session.textMap.add('FormEmptyMandatoryFieldsMessage', 'The following fields must be filled in:');
+ session.textMap.add('FormInvalidFieldsMessage', 'The following fields are invalid:');
+ session.textMap.add('FormInvalidFieldsWarningMessage', 'The following fields have a warning:');
});
afterEach(() => {
@@ -2519,4 +2523,109 @@ describe('Form', () => {
expect(numberField.value).toBe(null);
});
});
+
+ describe('lifecycle', () => {
+
+ it('is a FormLifecycle by default', () => {
+ let form = scout.create(Form, {parent: session.desktop});
+
+ expect(form.lifecycle).toBeInstanceOf(FormLifecycle);
+ expect(form.lifecycle.widget).toBe(form);
+ expect(form.lifecycle.askIfNeedSave).toBeTrue();
+ expect(form.lifecycle.askIfNeedSaveText).toBe('Do you want to save the changes?');
+ expect(form.lifecycle.emptyMandatoryElementsText).toBe('The following fields must be filled in:');
+ expect(form.lifecycle.invalidElementsErrorText).toBe('The following fields are invalid:');
+ expect(form.lifecycle.invalidElementsWarningText).toBe('The following fields have a warning:');
+
+ form = scout.create(Form, {
+ parent: session.desktop,
+ askIfNeedSave: false,
+ askIfNeedSaveText: 'lorem',
+ emptyMandatoryElementsText: 'ipsum',
+ invalidElementsErrorText: 'dolor',
+ invalidElementsWarningText: 'sit'
+ });
+
+ expect(form.lifecycle).toBeInstanceOf(FormLifecycle);
+ expect(form.lifecycle.widget).toBe(form);
+ expect(form.lifecycle.askIfNeedSave).toBeFalse();
+ expect(form.lifecycle.askIfNeedSaveText).toBe('lorem');
+ expect(form.lifecycle.emptyMandatoryElementsText).toBe('ipsum');
+ expect(form.lifecycle.invalidElementsErrorText).toBe('dolor');
+ expect(form.lifecycle.invalidElementsWarningText).toBe('sit');
+ });
+
+ it('can be passed in model as objectType', () => {
+ let form = scout.create(Form, {
+ parent: session.desktop,
+ lifecycle: SpecLifecycle
+ });
+
+ expect(form.lifecycle).toBeInstanceOf(SpecLifecycle);
+ expect(form.lifecycle.widget).toBe(form);
+ expect(form.lifecycle.askIfNeedSave).toBeTrue();
+ expect(form.lifecycle.askIfNeedSaveText).toBe('Do you want to save the changes?');
+ expect(form.lifecycle.emptyMandatoryElementsText).toBe('The following fields must be filled in:');
+ expect(form.lifecycle.invalidElementsErrorText).toBe('The following fields are invalid:');
+ expect(form.lifecycle.invalidElementsWarningText).toBe('The following fields have a warning:');
+
+ form = scout.create(Form, {
+ parent: session.desktop,
+ lifecycle: SpecLifecycle,
+ askIfNeedSave: false,
+ askIfNeedSaveText: 'lorem',
+ emptyMandatoryElementsText: 'ipsum',
+ invalidElementsErrorText: 'dolor',
+ invalidElementsWarningText: 'sit'
+ });
+
+ expect(form.lifecycle).toBeInstanceOf(SpecLifecycle);
+ expect(form.lifecycle.widget).toBe(form);
+ expect(form.lifecycle.askIfNeedSave).toBeFalse();
+ expect(form.lifecycle.askIfNeedSaveText).toBe('lorem');
+ expect(form.lifecycle.emptyMandatoryElementsText).toBe('ipsum');
+ expect(form.lifecycle.invalidElementsErrorText).toBe('dolor');
+ expect(form.lifecycle.invalidElementsWarningText).toBe('sit');
+ });
+
+ it('can be passed in model as child model', () => {
+ let form = scout.create(Form, {
+ parent: session.desktop,
+ lifecycle: {
+ objectType: SpecLifecycle
+ }
+ });
+
+ expect(form.lifecycle).toBeInstanceOf(SpecLifecycle);
+ expect(form.lifecycle.widget).toBe(form);
+ expect(form.lifecycle.askIfNeedSave).toBeTrue();
+ expect(form.lifecycle.askIfNeedSaveText).toBe('Do you want to save the changes?');
+ expect(form.lifecycle.emptyMandatoryElementsText).toBe('The following fields must be filled in:');
+ expect(form.lifecycle.invalidElementsErrorText).toBe('The following fields are invalid:');
+ expect(form.lifecycle.invalidElementsWarningText).toBe('The following fields have a warning:');
+
+ form = scout.create(Form, {
+ parent: session.desktop,
+ lifecycle: {
+ objectType: SpecLifecycle,
+ askIfNeedSave: false,
+ askIfNeedSaveText: 'lorem',
+ emptyMandatoryElementsText: 'ipsum',
+ invalidElementsErrorText: 'dolor',
+ invalidElementsWarningText: 'sit'
+ }
+ });
+
+ expect(form.lifecycle).toBeInstanceOf(SpecLifecycle);
+ expect(form.lifecycle.widget).toBe(form);
+ expect(form.lifecycle.askIfNeedSave).toBeFalse();
+ expect(form.lifecycle.askIfNeedSaveText).toBe('lorem');
+ expect(form.lifecycle.emptyMandatoryElementsText).toBe('ipsum');
+ expect(form.lifecycle.invalidElementsErrorText).toBe('dolor');
+ expect(form.lifecycle.invalidElementsWarningText).toBe('sit');
+ });
+ });
+
+ class SpecLifecycle extends FormLifecycle {
+ }
});
diff --git a/eclipse-scout-core/test/util/StatusSpec.ts b/eclipse-scout-core/test/util/StatusSpec.ts
index 82f446c2b8e..12622f5e5a4 100644
--- a/eclipse-scout-core/test/util/StatusSpec.ts
+++ b/eclipse-scout-core/test/util/StatusSpec.ts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2024 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2026 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -7,10 +7,48 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-import {DefaultStatus, NotificationBadgeStatus, ParsingFailedStatus, Status} from '../../src/index';
+import {DefaultStatus, NotificationBadgeStatus, ParsingFailedStatus, scout, Status, ValidationFailedStatus} from '../../src/index';
describe('Status', () => {
+ describe('clone', () => {
+ it('creates the correct instance', () => {
+ const orig = scout.create(NotificationBadgeStatus, {
+ severity: Status.Severity.WARNING,
+ message: 'test'
+ });
+ const copy = orig.clone();
+ expect(copy).not.toBe(orig);
+ expect(copy).toBeInstanceOf(NotificationBadgeStatus);
+ expect(copy.severity).toEqual(Status.Severity.WARNING);
+ expect(copy.message).toEqual('test');
+ });
+
+ it('creates a deep copy', () => {
+ const orig = scout.create({
+ objectType: ValidationFailedStatus,
+ severity: Status.Severity.WARNING,
+ message: 'deep-test'
+ });
+ orig.children = [scout.create(ParsingFailedStatus, {severity: Status.Severity.INFO, message: 'nested-test'})];
+ expect(orig).toBeInstanceOf(ValidationFailedStatus);
+ expect(orig.children[0]).toBeInstanceOf(ParsingFailedStatus);
+
+ const copy = orig.clone();
+ expect(copy).not.toBe(orig);
+ expect(copy).toBeInstanceOf(ValidationFailedStatus);
+
+ const childCopy = copy.children[0];
+ expect(childCopy).toBeInstanceOf(ParsingFailedStatus);
+ expect(childCopy.severity).toBe(Status.Severity.INFO);
+ expect(childCopy.message).toBe('nested-test');
+
+ childCopy.severity = Status.Severity.WARNING;
+ expect(orig.children[0].severity).toBe(Status.Severity.INFO);
+ expect(copy.children[0].severity).toBe(Status.Severity.WARNING);
+ });
+ });
+
describe('convenience functions', () => {
it('create valid status objects', () => {
diff --git a/eclipse-scout-core/test/util/objectsSpec.ts b/eclipse-scout-core/test/util/objectsSpec.ts
index cc0d6e9646b..42178f43552 100644
--- a/eclipse-scout-core/test/util/objectsSpec.ts
+++ b/eclipse-scout-core/test/util/objectsSpec.ts
@@ -196,9 +196,8 @@ describe('objects', () => {
expect(objects.valueCopy(false)).toBeFalse();
});
- it('returns the input if class cannot be copied', () => {
- const toClone = new NullLayout();
- expect(objects.valueCopy(toClone)).toBe(toClone);
+ it('throws if class cannot be copied', () => {
+ expect(() => objects.valueCopy(new NullLayout())).toThrow();
});
it('deep copies arrays', () => {
diff --git a/eclipse-scout-migrate/README.md b/eclipse-scout-migrate/README.md
index 0f9534c92a6..d0ca63cdc72 100644
--- a/eclipse-scout-migrate/README.md
+++ b/eclipse-scout-migrate/README.md
@@ -3,8 +3,8 @@
-
-
+
+
@@ -29,7 +29,7 @@ To set up the tool, do the following:
```json
{
"devDependencies": {
- "@eclipse-scout/migrate": "~26.1.0"
+ "@eclipse-scout/migrate": "~26.2.0"
}
}
```
@@ -45,7 +45,7 @@ Some migrations require a `tsconfig.json`. You can add it as follows (do it only
```json
{
"devDependencies": {
- "@eclipse-scout/tsconfig": "~26.1.0"
+ "@eclipse-scout/tsconfig": "~26.2.0"
}
}
```
@@ -138,7 +138,7 @@ In order to run the TypeScript migration, do the following:
In your widget, implement the model interface and declare a model variable.
- To create the event maps, you can run the `event-maps` script from below and copy the result into a separate event maps file.
- If you use third party libraries, you may want to check if they provide types and add them to the `devDependencies` of your `package.json` (e.g. @types/jquery).
- See also [Project Setup for TypeScript](https://eclipsescout.github.io/scout-docs/26.1/technical-guide/user-interface/typescript.html#project-setup-for-typescript)
+ See also [Project Setup for TypeScript](https://eclipsescout.github.io/scout-docs/26.2/technical-guide/user-interface/typescript.html#project-setup-for-typescript)
- Remove the added `scripts`, `overrides` and dependency to `@eclipse-scout/migrate`.
```json
diff --git a/eclipse-scout-migrate/package.json b/eclipse-scout-migrate/package.json
index b9488806f8e..758747aeb51 100644
--- a/eclipse-scout-migrate/package.json
+++ b/eclipse-scout-migrate/package.json
@@ -1,6 +1,6 @@
{
"name": "@eclipse-scout/migrate",
- "version": "26.1.0-snapshot",
+ "version": "26.2.0-snapshot",
"description": "TypeScript migration module",
"author": "BSI Business Systems Integration AG",
"homepage": "https://eclipse.dev/scout/",
@@ -46,6 +46,6 @@
"jest": "30.2.0",
"@babel/preset-env": "7.28.5",
"@babel/core": "7.28.5",
- "@eclipse-scout/tsconfig": ">=26.1.0-snapshot <26.1.0"
+ "@eclipse-scout/tsconfig": ">=26.2.0-snapshot <26.2.0"
}
}
diff --git a/eclipse-scout-migrate/pom.xml b/eclipse-scout-migrate/pom.xml
index d64415da86c..865b9bd8205 100644
--- a/eclipse-scout-migrate/pom.xml
+++ b/eclipse-scout-migrate/pom.xml
@@ -16,7 +16,7 @@
org.eclipse.scout.rtorg.eclipse.scout.rt
- 26.1-SNAPSHOT
+ 26.2-SNAPSHOT../org.eclipse.scout.rt
diff --git a/eclipse-scout-releng/README.md b/eclipse-scout-releng/README.md
index 228d685218f..7f2999186c8 100644
--- a/eclipse-scout-releng/README.md
+++ b/eclipse-scout-releng/README.md
@@ -3,8 +3,8 @@
Each test-method is executed in a separate transaction - meaning that the transaction boundary starts before
+ * executing the first 'before-method', and ends after executing the last 'after-method'.
+ *
By default, server sessions are shared among same users. This can be changed by setting the
+ * {@link ServerSessionProvider} or a custom provider to {@link RunWithServerSession#provider()}.
+ *
'beforeClass' and 'afterClass' are executed in the same transaction.
+ *
+ * Note: Usually, all {@link Before}, the {@link Test}-annotated method and all {@link After} methods are invoked
+ * in a single transaction. But if the {@link Test}-annotated method uses the timeout feature (i.e.
+ * {@link Test#timeout()}), the three parts are executed in different transactions.
+ *
+ * @see RunWithServerSession
+ * @see RunWithSubject
+ * @since 5.1
+ */
+public class ServerSessionTestRunner extends PlatformTestRunner {
+
+ public ServerSessionTestRunner(final Class> clazz) throws InitializationError {
+ super(clazz);
+ }
+
+ @Override
+ protected Statement interceptClassLevelStatement(final Statement next, final Class> testClass) {
+ final Statement s1 = new ServerRunContextStatement(next, ReflectionUtility.getAnnotation(RunWithServerSession.class, testClass));
+
+ return s1;
+ }
+
+ protected boolean expectsException(final Test annotation) {
+ return annotation != null && annotation.expected() != None.class;
+ }
+
+ @Override
+ protected Statement interceptMethodLevelStatement(final Statement next, final Class> testClass, final Method testMethod) {
+ final Statement s1 = new ServerRunContextStatement(next, ReflectionUtility.getAnnotation(RunWithServerSession.class, testMethod, testClass));
+
+ return s1;
+ }
+
+ @Override
+ protected RunContext createJUnitRunContext() {
+ return ServerSessionRunContexts.empty();
+ }
+}
diff --git a/org.eclipse.scout.rt.server.test/src/main/java/org/eclipse/scout/rt/testing/server/runner/statement/ServerRunContextStatement.java b/org.eclipse.scout.rt.server.session.test/src/main/java/org/eclipse/scout/rt/testing/server/runner/statement/ServerRunContextStatement.java
similarity index 95%
rename from org.eclipse.scout.rt.server.test/src/main/java/org/eclipse/scout/rt/testing/server/runner/statement/ServerRunContextStatement.java
rename to org.eclipse.scout.rt.server.session.test/src/main/java/org/eclipse/scout/rt/testing/server/runner/statement/ServerRunContextStatement.java
index ba9bec17118..6762a82e268 100644
--- a/org.eclipse.scout.rt.server.test/src/main/java/org/eclipse/scout/rt/testing/server/runner/statement/ServerRunContextStatement.java
+++ b/org.eclipse.scout.rt.server.session.test/src/main/java/org/eclipse/scout/rt/testing/server/runner/statement/ServerRunContextStatement.java
@@ -18,6 +18,8 @@
import org.eclipse.scout.rt.security.IAccessControlService;
import org.eclipse.scout.rt.server.IServerSession;
import org.eclipse.scout.rt.server.context.ServerRunContexts;
+import org.eclipse.scout.rt.server.IServerSession;
+import org.eclipse.scout.rt.server.session.context.ServerSessionRunContexts;
import org.eclipse.scout.rt.shared.ISession;
import org.eclipse.scout.rt.shared.ui.UserAgent;
import org.eclipse.scout.rt.shared.ui.UserAgents;
@@ -84,7 +86,7 @@ protected void evaluateWithServerRunContext() throws Throwable {
// Run the test on behalf of a ServerRunContext.
final SafeStatementInvoker invoker = new SafeStatementInvoker(m_next);
- ServerRunContexts.copyCurrent()
+ ServerSessionRunContexts.copyCurrent()
.withSession(serverSession)
.withSubject(currentSubject) // set the test subject explicitly in case it is different to the session subject
.withThreadLocal(UserId.CURRENT, BEANS.get(IAccessControlService.class).getUserId(currentSubject))
diff --git a/org.eclipse.scout.rt.server.test/src/main/java/org/eclipse/scout/rt/testing/server/runner/statement/ServerRunContextStatementFactory.java b/org.eclipse.scout.rt.server.session.test/src/main/java/org/eclipse/scout/rt/testing/server/runner/statement/ServerRunContextStatementFactory.java
similarity index 100%
rename from org.eclipse.scout.rt.server.test/src/main/java/org/eclipse/scout/rt/testing/server/runner/statement/ServerRunContextStatementFactory.java
rename to org.eclipse.scout.rt.server.session.test/src/main/java/org/eclipse/scout/rt/testing/server/runner/statement/ServerRunContextStatementFactory.java
diff --git a/org.eclipse.scout.rt.server.session.test/src/main/resources/META-INF/scout.xml b/org.eclipse.scout.rt.server.session.test/src/main/resources/META-INF/scout.xml
new file mode 100644
index 00000000000..e17c07b8ff8
--- /dev/null
+++ b/org.eclipse.scout.rt.server.session.test/src/main/resources/META-INF/scout.xml
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/AbstractServerSessionTest.java b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/AbstractServerSessionTest.java
similarity index 93%
rename from org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/AbstractServerSessionTest.java
rename to org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/AbstractServerSessionTest.java
index dfd1f04711c..2d04b4476bd 100644
--- a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/AbstractServerSessionTest.java
+++ b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/AbstractServerSessionTest.java
@@ -7,7 +7,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.scout.rt.server;
+package org.eclipse.scout.rt.server.session;
import static org.junit.Assert.assertEquals;
@@ -16,6 +16,8 @@
import org.eclipse.scout.rt.platform.serialization.IObjectSerializer;
import org.eclipse.scout.rt.platform.serialization.SerializationUtility;
+import org.eclipse.scout.rt.server.AbstractServerSession;
+import org.eclipse.scout.rt.server.IServerSession;
import org.eclipse.scout.rt.testing.platform.runner.RunWithSubject;
import org.eclipse.scout.rt.testing.server.runner.RunWithServerSession;
import org.eclipse.scout.rt.testing.server.runner.ServerTestRunner;
diff --git a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/session/ServerSessionCacheTest.java b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/ServerSessionCacheTest.java
similarity index 99%
rename from org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/session/ServerSessionCacheTest.java
rename to org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/ServerSessionCacheTest.java
index a28e820b048..2902e448694 100644
--- a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/session/ServerSessionCacheTest.java
+++ b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/ServerSessionCacheTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
diff --git a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/ServerSessionListenerTest.java b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/ServerSessionListenerTest.java
similarity index 89%
rename from org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/ServerSessionListenerTest.java
rename to org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/ServerSessionListenerTest.java
index 6e968a1f5e4..e39d252bfdb 100644
--- a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/ServerSessionListenerTest.java
+++ b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/ServerSessionListenerTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -7,11 +7,13 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.scout.rt.server;
+package org.eclipse.scout.rt.server.session;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.*;
+import org.eclipse.scout.rt.server.AbstractServerSession;
+import org.eclipse.scout.rt.server.IServerSession;
import org.eclipse.scout.rt.shared.session.ISessionListener;
import org.eclipse.scout.rt.shared.session.SessionEvent;
import org.junit.After;
diff --git a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/session/ServerSessionProviderWithCacheTest.java b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/ServerSessionProviderWithCacheTest.java
similarity index 100%
rename from org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/session/ServerSessionProviderWithCacheTest.java
rename to org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/ServerSessionProviderWithCacheTest.java
diff --git a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/TestServerSession.java b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/TestServerSession.java
similarity index 83%
rename from org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/TestServerSession.java
rename to org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/TestServerSession.java
index 1c53eb462e9..f041bcb2a56 100644
--- a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/TestServerSession.java
+++ b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/TestServerSession.java
@@ -7,7 +7,9 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.scout.rt.server;
+package org.eclipse.scout.rt.server.session;
+
+import org.eclipse.scout.rt.server.AbstractServerSession;
public class TestServerSession extends AbstractServerSession {
private static final long serialVersionUID = 782294551137415747L;
diff --git a/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/context/HttpServerRunContextProducerTest.java b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/context/HttpServerRunContextProducerTest.java
new file mode 100644
index 00000000000..a21e56a2fbd
--- /dev/null
+++ b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/context/HttpServerRunContextProducerTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.eclipse.scout.rt.server.session.context;
+
+import org.eclipse.scout.rt.testing.platform.runner.PlatformTestRunner;
+import org.junit.runner.RunWith;
+
+// FIXME PBZ SESSION split into two tests
+@RunWith(PlatformTestRunner.class)
+public class HttpServerRunContextProducerTest {
+
+ // static final String TEST_USER_AGENT_STRING = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)";
+ //
+ // @Test
+ // public void testGetOrCreateScoutSessionWithCustomId() {
+ // HttpServerSessionRunContextProducer producer = new HttpServerSessionRunContextProducer();
+ // assertTrue(producer.hasSessionSupport());
+ //
+ // HttpServletRequest req = createRequestMock(null, null);
+ // HttpServletResponse resp = mock(HttpServletResponse.class);
+ //
+ // ServerRunContext serverRunContextForSessionStart = (ServerRunContext) producer.getInnerRunContextProducer().produce(req, resp);
+ // String sessionId = "testid";
+ // IServerSession session = producer.getOrCreateScoutSession(req, serverRunContextForSessionStart, sessionId);
+ // try {
+ // assertNotNull(session);
+ // assertEquals(sessionId, session.getId());
+ // }
+ // finally {
+ // session.stop();
+ // }
+ // }
+ //
+ // @Test
+ // public void testGetOrCreateScoutSessionWithRandomId() {
+ // HttpServerSessionRunContextProducer producer = new HttpServerSessionRunContextProducer();
+ // assertTrue(producer.hasSessionSupport());
+ //
+ // String clientSessionId = "testClientSessionId";
+ // HttpServletRequest req = createRequestMock(null, clientSessionId);
+ // HttpServletResponse resp = mock(HttpServletResponse.class);
+ //
+ // ServerSessionRunContext context = producer.produce(req, resp);
+ // IServerSession session = context.getSession();
+ // try {
+ // assertNotNull(session);
+ // assertNotNull(session.getId());
+ // assertEquals(clientSessionId, context.call(SessionId.CURRENT::get));
+ // }
+ // finally {
+ // session.stop();
+ // }
+ // }
+ //
+ // @Test
+ // public void testGetOrCreateScoutSessionWithExistingSessionIdOnHttpSession() {
+ // HttpServerSessionRunContextProducer producer = new HttpServerSessionRunContextProducer();
+ // assertTrue(producer.hasSessionSupport());
+ //
+ // String existingServerSessionId = "testServerSessionId";
+ // String clientSessionId = "testClientSessionId";
+ // HttpServletRequest req = createRequestMock(existingServerSessionId, clientSessionId);
+ // HttpServletResponse resp = mock(HttpServletResponse.class);
+ //
+ // ServerSessionRunContext context = producer.produce(req, resp);
+ // IServerSession session = context.getSession();
+ // try {
+ // assertNotNull(session);
+ // assertEquals(existingServerSessionId, session.getId());
+ // assertEquals(clientSessionId, context.call(SessionId.CURRENT::get));
+ // }
+ // finally {
+ // session.stop();
+ // }
+ // }
+ //
+ // protected HttpServletRequest createRequestMock(String serverSessionId, String clientSessionId) {
+ // HttpSession httpSession = mock(HttpSession.class);
+ // when(httpSession.getAttribute(eq(HttpServerRunContextProducer.SCOUT_SESSION_ID_KEY))).thenReturn(serverSessionId);
+ //
+ // HttpServletRequest req = mock(HttpServletRequest.class);
+ // when(req.getHeader(eq("User-Agent"))).thenReturn(TEST_USER_AGENT_STRING);
+ // when(req.getSession()).thenReturn(httpSession);
+ // when(req.getSession(anyBoolean())).thenReturn(httpSession);
+ // when(req.getHeader(SessionId.HTTP_HEADER_NAME)).thenReturn(clientSessionId);
+ // return req;
+ // }
+}
diff --git a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/job/filter/event/SessionJobEventFilterTest.java b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/job/filter/event/SessionJobEventFilterTest.java
similarity index 87%
rename from org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/job/filter/event/SessionJobEventFilterTest.java
rename to org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/job/filter/event/SessionJobEventFilterTest.java
index 56bd9b41016..4e718220851 100644
--- a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/job/filter/event/SessionJobEventFilterTest.java
+++ b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/job/filter/event/SessionJobEventFilterTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -7,7 +7,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.scout.rt.server.job.filter.event;
+package org.eclipse.scout.rt.server.session.job.filter.event;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
@@ -19,8 +19,9 @@
import org.eclipse.scout.rt.platform.job.listener.JobEventData;
import org.eclipse.scout.rt.platform.job.listener.JobEventType;
import org.eclipse.scout.rt.platform.util.concurrent.IRunnable;
-import org.eclipse.scout.rt.server.IServerSession;
import org.eclipse.scout.rt.server.context.ServerRunContexts;
+import org.eclipse.scout.rt.server.IServerSession;
+import org.eclipse.scout.rt.server.session.context.ServerSessionRunContexts;
import org.eclipse.scout.rt.shared.ISession;
import org.eclipse.scout.rt.shared.job.filter.event.SessionJobEventFilter;
import org.junit.Test;
@@ -56,12 +57,12 @@ public void test() {
// Tests JobEvent with job with ClientRunContext with correct session
event = new JobEvent(mock(IJobManager.class), JobEventType.JOB_STATE_CHANGED,
- new JobEventData().withFuture(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ServerRunContexts.empty().withSession(session1)))));
+ new JobEventData().withFuture(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ServerSessionRunContexts.empty().withSession(session1)))));
assertTrue(filter.test(event));
// Tests JobEvent with job with ClientRunContext with wrong session
event = new JobEvent(mock(IJobManager.class), JobEventType.JOB_STATE_CHANGED,
- new JobEventData().withFuture(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ServerRunContexts.empty().withSession(session2)))));
+ new JobEventData().withFuture(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ServerSessionRunContexts.empty().withSession(session2)))));
assertFalse(filter.test(event));
// Tests adaptable to the session
diff --git a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/job/filter/future/SessionFutureFilterTest.java b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/job/filter/future/SessionFutureFilterTest.java
similarity index 82%
rename from org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/job/filter/future/SessionFutureFilterTest.java
rename to org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/job/filter/future/SessionFutureFilterTest.java
index d71717f2d98..2964b9aa710 100644
--- a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/job/filter/future/SessionFutureFilterTest.java
+++ b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/job/filter/future/SessionFutureFilterTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -7,7 +7,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.scout.rt.server.job.filter.future;
+package org.eclipse.scout.rt.server.session.job.filter.future;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
@@ -15,8 +15,9 @@
import org.eclipse.scout.rt.platform.context.RunContexts;
import org.eclipse.scout.rt.platform.job.Jobs;
import org.eclipse.scout.rt.platform.util.concurrent.IRunnable;
-import org.eclipse.scout.rt.server.IServerSession;
import org.eclipse.scout.rt.server.context.ServerRunContexts;
+import org.eclipse.scout.rt.server.IServerSession;
+import org.eclipse.scout.rt.server.session.context.ServerSessionRunContexts;
import org.eclipse.scout.rt.shared.ISession;
import org.eclipse.scout.rt.shared.job.filter.future.SessionFutureFilter;
import org.junit.Test;
@@ -40,10 +41,10 @@ public void test() {
assertFalse(filter.test(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ServerRunContexts.empty()))));
// Tests a Future of a job with ClientRunContext with correct session
- assertTrue(filter.test(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ServerRunContexts.empty().withSession(session1)))));
+ assertTrue(filter.test(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ServerSessionRunContexts.empty().withSession(session1)))));
// Tests a Future of a job with ClientRunContext with wrong session
- assertFalse(filter.test(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ServerRunContexts.empty().withSession(session2)))));
+ assertFalse(filter.test(Jobs.schedule(mock(IRunnable.class), Jobs.newInput().withRunContext(ServerSessionRunContexts.empty().withSession(session2)))));
// Test adaptable to the session
assertSame(session1, filter.getAdapter(ISession.class));
diff --git a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunnerDifferentSessionTest.java b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/ServerTestRunnerDifferentSessionTest.java
similarity index 95%
rename from org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunnerDifferentSessionTest.java
rename to org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/ServerTestRunnerDifferentSessionTest.java
index 87877314e03..39b331abf59 100644
--- a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunnerDifferentSessionTest.java
+++ b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/ServerTestRunnerDifferentSessionTest.java
@@ -7,7 +7,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.scout.rt.testing.server.runner;
+package org.eclipse.scout.rt.server.session.runner;
import static org.junit.Assert.*;
@@ -19,10 +19,12 @@
import org.eclipse.scout.rt.server.AbstractServerSession;
import org.eclipse.scout.rt.server.IServerSession;
import org.eclipse.scout.rt.server.session.ServerSessionProvider;
+import org.eclipse.scout.rt.server.session.runner.ServerTestRunnerDifferentSessionTest.JUnitServerSession1;
import org.eclipse.scout.rt.shared.ISession;
import org.eclipse.scout.rt.shared.user.UserId;
import org.eclipse.scout.rt.testing.platform.runner.RunWithSubject;
-import org.eclipse.scout.rt.testing.server.runner.ServerTestRunnerDifferentSessionTest.JUnitServerSession1;
+import org.eclipse.scout.rt.testing.server.runner.RunWithServerSession;
+import org.eclipse.scout.rt.testing.server.runner.ServerTestRunner;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
diff --git a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunnerDifferentSubjectTest.java b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/ServerTestRunnerDifferentSubjectTest.java
similarity index 92%
rename from org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunnerDifferentSubjectTest.java
rename to org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/ServerTestRunnerDifferentSubjectTest.java
index 290a8a6637d..38e0bb723b5 100644
--- a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunnerDifferentSubjectTest.java
+++ b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/ServerTestRunnerDifferentSubjectTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -7,7 +7,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.scout.rt.testing.server.runner;
+package org.eclipse.scout.rt.server.session.runner;
import static org.junit.Assert.*;
@@ -21,7 +21,9 @@
import org.eclipse.scout.rt.shared.ISession;
import org.eclipse.scout.rt.shared.user.UserId;
import org.eclipse.scout.rt.testing.platform.runner.RunWithSubject;
-import org.eclipse.scout.rt.testing.server.runner.ServerTestRunnerDifferentSubjectTest.JUnitServerSession;
+import org.eclipse.scout.rt.server.session.runner.ServerTestRunnerDifferentSubjectTest.JUnitServerSession;
+import org.eclipse.scout.rt.testing.server.runner.RunWithServerSession;
+import org.eclipse.scout.rt.testing.server.runner.ServerTestRunner;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
diff --git a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunnerSameSessionTest.java b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/ServerTestRunnerSameSessionTest.java
similarity index 92%
rename from org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunnerSameSessionTest.java
rename to org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/ServerTestRunnerSameSessionTest.java
index 12585ca4060..396d0e3aeb3 100644
--- a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunnerSameSessionTest.java
+++ b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/ServerTestRunnerSameSessionTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -7,7 +7,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.scout.rt.testing.server.runner;
+package org.eclipse.scout.rt.server.session.runner;
import static org.junit.Assert.*;
@@ -18,10 +18,12 @@
import org.eclipse.scout.rt.platform.transaction.ITransaction;
import org.eclipse.scout.rt.server.AbstractServerSession;
import org.eclipse.scout.rt.server.IServerSession;
+import org.eclipse.scout.rt.server.session.runner.ServerTestRunnerSameSessionTest.JUnitServerSession;
import org.eclipse.scout.rt.shared.ISession;
import org.eclipse.scout.rt.shared.user.UserId;
import org.eclipse.scout.rt.testing.platform.runner.RunWithSubject;
-import org.eclipse.scout.rt.testing.server.runner.ServerTestRunnerSameSessionTest.JUnitServerSession;
+import org.eclipse.scout.rt.testing.server.runner.RunWithServerSession;
+import org.eclipse.scout.rt.testing.server.runner.ServerTestRunner;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
diff --git a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunnerTimeoutTest.java b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/ServerTestRunnerTimeoutTest.java
similarity index 93%
rename from org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunnerTimeoutTest.java
rename to org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/ServerTestRunnerTimeoutTest.java
index 12925d2de4c..a17dc95ca33 100644
--- a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunnerTimeoutTest.java
+++ b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/ServerTestRunnerTimeoutTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -7,12 +7,13 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.scout.rt.testing.server.runner;
+package org.eclipse.scout.rt.server.session.runner;
import static org.junit.Assert.*;
import java.util.Arrays;
+import org.eclipse.scout.rt.testing.server.runner.ServerTestRunner;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
diff --git a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunnerTimeoutTestFixture.java b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/ServerTestRunnerTimeoutTestFixture.java
similarity index 80%
rename from org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunnerTimeoutTestFixture.java
rename to org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/ServerTestRunnerTimeoutTestFixture.java
index b842f0bb9ff..c18ed4ed167 100644
--- a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunnerTimeoutTestFixture.java
+++ b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/ServerTestRunnerTimeoutTestFixture.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -7,10 +7,12 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.scout.rt.testing.server.runner;
+package org.eclipse.scout.rt.server.session.runner;
+import org.eclipse.scout.rt.server.session.runner.ServerTestRunnerSameSessionTest.JUnitServerSession;
import org.eclipse.scout.rt.testing.platform.runner.RunWithSubject;
-import org.eclipse.scout.rt.testing.server.runner.ServerTestRunnerSameSessionTest.JUnitServerSession;
+import org.eclipse.scout.rt.testing.server.runner.RunWithServerSession;
+import org.eclipse.scout.rt.testing.server.runner.ServerTestRunner;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunnerTimeoutTransactionTest.java b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/ServerTestRunnerTimeoutTransactionTest.java
similarity index 92%
rename from org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunnerTimeoutTransactionTest.java
rename to org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/ServerTestRunnerTimeoutTransactionTest.java
index c0b024559ec..9005850f4ad 100644
--- a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunnerTimeoutTransactionTest.java
+++ b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/ServerTestRunnerTimeoutTransactionTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -7,7 +7,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.scout.rt.testing.server.runner;
+package org.eclipse.scout.rt.server.session.runner;
import static org.junit.Assert.*;
@@ -18,8 +18,10 @@
import org.eclipse.scout.rt.platform.exception.PlatformException;
import org.eclipse.scout.rt.platform.transaction.ITransaction;
+import org.eclipse.scout.rt.server.session.runner.ServerTestRunnerSameSessionTest.JUnitServerSession;
import org.eclipse.scout.rt.testing.platform.runner.RunWithSubject;
-import org.eclipse.scout.rt.testing.server.runner.ServerTestRunnerSameSessionTest.JUnitServerSession;
+import org.eclipse.scout.rt.testing.server.runner.RunWithServerSession;
+import org.eclipse.scout.rt.testing.server.runner.ServerTestRunner;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
diff --git a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/parameterized/ParameterizedServerTestRunnerTimeoutTransactionTest.java b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/parametrized/ParameterizedServerTestRunnerTimeoutTransactionTest.java
similarity index 93%
rename from org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/parameterized/ParameterizedServerTestRunnerTimeoutTransactionTest.java
rename to org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/parametrized/ParameterizedServerTestRunnerTimeoutTransactionTest.java
index 2a072d6c4be..4f09e191701 100644
--- a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/testing/server/runner/parameterized/ParameterizedServerTestRunnerTimeoutTransactionTest.java
+++ b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/runner/parametrized/ParameterizedServerTestRunnerTimeoutTransactionTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -7,7 +7,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.scout.rt.testing.server.runner.parameterized;
+package org.eclipse.scout.rt.server.session.runner.parametrized;
import static org.junit.Assert.*;
@@ -20,11 +20,12 @@
import org.eclipse.scout.rt.platform.exception.PlatformException;
import org.eclipse.scout.rt.platform.transaction.ITransaction;
+import org.eclipse.scout.rt.server.session.runner.ServerTestRunnerSameSessionTest.JUnitServerSession;
import org.eclipse.scout.rt.testing.platform.runner.RunWithSubject;
import org.eclipse.scout.rt.testing.platform.runner.parameterized.AbstractScoutTestParameter;
import org.eclipse.scout.rt.testing.platform.runner.parameterized.IScoutTestParameter;
import org.eclipse.scout.rt.testing.server.runner.RunWithServerSession;
-import org.eclipse.scout.rt.testing.server.runner.ServerTestRunnerSameSessionTest.JUnitServerSession;
+import org.eclipse.scout.rt.testing.server.runner.parameterized.ParameterizedServerTestRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
diff --git a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/services/ServiceWithSessionInterceptorTest.java b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/services/ServiceWithSessionInterceptorTest.java
similarity index 79%
rename from org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/services/ServiceWithSessionInterceptorTest.java
rename to org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/services/ServiceWithSessionInterceptorTest.java
index 39f9299c658..5c33a01fd29 100644
--- a/org.eclipse.scout.rt.server.test/src/test/java/org/eclipse/scout/rt/server/services/ServiceWithSessionInterceptorTest.java
+++ b/org.eclipse.scout.rt.server.session.test/src/test/java/org/eclipse/scout/rt/server/session/services/ServiceWithSessionInterceptorTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -7,14 +7,15 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.scout.rt.server.services;
+package org.eclipse.scout.rt.server.session.services;
import org.eclipse.scout.rt.platform.ApplicationScoped;
import org.eclipse.scout.rt.platform.BEANS;
import org.eclipse.scout.rt.platform.Platform;
import org.eclipse.scout.rt.platform.service.IService;
-import org.eclipse.scout.rt.server.TestServerSession;
import org.eclipse.scout.rt.server.context.ServerRunContexts;
+import org.eclipse.scout.rt.server.session.TestServerSession;
+import org.eclipse.scout.rt.server.session.context.ServerSessionRunContexts;
import org.eclipse.scout.rt.testing.platform.runner.PlatformTestRunner;
import org.junit.AfterClass;
import org.junit.BeforeClass;
@@ -39,7 +40,7 @@ public static void tearDown() {
@Test
public void testService() {
- ServerRunContexts.empty().withSession(m_serverSession).run(() -> runInServerRunContext());
+ ServerSessionRunContexts.empty().withSession(m_serverSession).run(() -> runInServerRunContext());
}
protected void runInServerRunContext() {
diff --git a/org.eclipse.scout.rt.server.session.test/src/test/resources/META-INF/scout.xml b/org.eclipse.scout.rt.server.session.test/src/test/resources/META-INF/scout.xml
new file mode 100644
index 00000000000..e17c07b8ff8
--- /dev/null
+++ b/org.eclipse.scout.rt.server.session.test/src/test/resources/META-INF/scout.xml
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/org.eclipse.scout.rt.server.session.test/src/test/resources/logback-test.xml b/org.eclipse.scout.rt.server.session.test/src/test/resources/logback-test.xml
new file mode 100644
index 00000000000..b4174d12a46
--- /dev/null
+++ b/org.eclipse.scout.rt.server.session.test/src/test/resources/logback-test.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
diff --git a/org.eclipse.scout.rt.server.session/.settings/org.eclipse.core.resources.prefs b/org.eclipse.scout.rt.server.session/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 00000000000..13d34f372ba
--- /dev/null
+++ b/org.eclipse.scout.rt.server.session/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,18 @@
+eclipse.preferences.version=1
+encoding//src/main/client=UTF-8
+encoding//src/main/fixture=UTF-8
+encoding//src/main/java=UTF-8
+encoding//src/main/java-jcl=UTF-8
+encoding//src/main/java-log4j=UTF-8
+encoding//src/main/java-original=UTF-8
+encoding//src/main/js=UTF-8
+encoding//src/main/resources=UTF-8
+encoding//src/main/shared=UTF-8
+encoding//src/main/webapp=UTF-8
+encoding//src/test/java=UTF-8
+encoding//src/test/js=UTF-8
+encoding//src/test/resources=UTF-8
+encoding//target/generated-sources/annotations=UTF-8
+encoding//target/generated-sources/wsimport=UTF-8
+encoding/=UTF-8
+encoding/files=UTF-8
diff --git a/org.eclipse.scout.rt.server.session/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.scout.rt.server.session/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 00000000000..5a0ad22d2a7
--- /dev/null
+++ b/org.eclipse.scout.rt.server.session/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/org.eclipse.scout.rt.server.session/.settings/org.eclipse.jdt.apt.core.prefs b/org.eclipse.scout.rt.server.session/.settings/org.eclipse.jdt.apt.core.prefs
new file mode 100644
index 00000000000..d4313d4b25e
--- /dev/null
+++ b/org.eclipse.scout.rt.server.session/.settings/org.eclipse.jdt.apt.core.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.apt.aptEnabled=false
diff --git a/org.eclipse.scout.rt.server.session/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.scout.rt.server.session/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000000..b79226010fc
--- /dev/null
+++ b/org.eclipse.scout.rt.server.session/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,399 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=m_
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=21
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=21
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.processAnnotations=disabled
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=21
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=16
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true
+org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=false
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=false
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=120
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
+org.eclipse.jdt.core.formatter.indentation.size=2
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=false
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=true
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=true
+org.eclipse.jdt.core.formatter.lineSplit=240
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=true
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=2
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=true
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/org.eclipse.scout.rt.server.session/.settings/org.eclipse.jdt.launching.prefs b/org.eclipse.scout.rt.server.session/.settings/org.eclipse.jdt.launching.prefs
new file mode 100644
index 00000000000..d211d326335
--- /dev/null
+++ b/org.eclipse.scout.rt.server.session/.settings/org.eclipse.jdt.launching.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=warning
diff --git a/org.eclipse.scout.rt.server.session/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.scout.rt.server.session/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 00000000000..a52f8c4ad0a
--- /dev/null
+++ b/org.eclipse.scout.rt.server.session/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,127 @@
+cleanup.add_default_serial_version_id=true
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=false
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_missing_override_annotations_interface_methods=true
+cleanup.add_serial_version_id=false
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=false
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_functional_interfaces=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.correct_indentation=true
+cleanup.format_source_code=true
+cleanup.format_source_code_changes_only=false
+cleanup.insert_inferred_type_arguments=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=false
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.organize_imports=true
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=false
+cleanup.qualify_static_member_accesses_with_declaring_class=false
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_redundant_type_arguments=true
+cleanup.remove_trailing_whitespaces=true
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_casts=false
+cleanup.remove_unnecessary_nls_tags=false
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.use_anonymous_class_creation=false
+cleanup.use_blocks=false
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_lambda=true
+cleanup.use_parentheses_in_expressions=false
+cleanup.use_this_for_non_static_field_access=false
+cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup.use_type_arguments=false
+cleanup_profile=_Eclipse Scout
+cleanup_settings_version=2
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_Eclipse Scout
+formatter_settings_version=12
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.javadoc=true
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.overrideannotation=true
+org.eclipse.jdt.ui.text.custom_code_templates=/*&\#13;\r\n * Copyright (c) 2010, ${year} BSI Business Systems Integration AG&\#13;\r\n *&\#13;\r\n * This program and the accompanying materials are made&\#13;\r\n * available under the terms of the Eclipse Public License 2.0&\#13;\r\n * which is available at https\://www.eclipse.org/legal/epl-2.0/&\#13;\r\n *&\#13;\r\n * SPDX-License-Identifier\: EPL-2.0&\#13;\r\n */${filecomment}\r\n${package_declaration}\r\n\r\n${typecomment}\r\n${type_declaration}\r\n\r\n\r\n\r\n// ${todo} Auto-generated catch block\r\n${exception_var}.printStackTrace();${body_statement}${body_statement}return ${field};${field} \= ${param};${filecomment}\r\n${package_declaration}\r\n\r\n${typecomment}\r\n${type_declaration}\r\n${exception_var}.printStackTrace();${body_statement}${body_statement}return ${field};${field} \= ${param};/**\r\n * @author ${user}\r\n *\r\n * ${tags}\r\n */\r\n
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=false
+sp_cleanup.add_missing_deprecated_annotations=false
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=false
+sp_cleanup.add_missing_override_annotations_interface_methods=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_functional_interfaces=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_type_arguments=false
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=false
+sp_cleanup.remove_unnecessary_nls_tags=true
+sp_cleanup.remove_unused_imports=true
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_blocks=true
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_lambda=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_type_arguments=false
diff --git a/org.eclipse.scout.rt.server.session/.settings/org.eclipse.m2e.core.prefs b/org.eclipse.scout.rt.server.session/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 00000000000..f897a7f1cb2
--- /dev/null
+++ b/org.eclipse.scout.rt.server.session/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/org.eclipse.scout.rt.server.session/pom.xml b/org.eclipse.scout.rt.server.session/pom.xml
new file mode 100644
index 00000000000..a1d67d7caaf
--- /dev/null
+++ b/org.eclipse.scout.rt.server.session/pom.xml
@@ -0,0 +1,36 @@
+
+
+
+ 4.0.0
+
+
+ org.eclipse.scout.rt
+ org.eclipse.scout.rt
+ 26.2-SNAPSHOT
+ ../org.eclipse.scout.rt
+
+
+ org.eclipse.scout.rt.server.session
+ jar
+ ${project.artifactId}
+
+
+
+
+ org.eclipse.scout.rt
+ org.eclipse.scout.rt.server
+
+
+ org.eclipse.scout.rt
+ org.eclipse.scout.rt.shared.session
+
+
+
diff --git a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/AbstractServerSession.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/AbstractServerSession.java
similarity index 95%
rename from org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/AbstractServerSession.java
rename to org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/AbstractServerSession.java
index fb9dc9258b9..43478756f6f 100644
--- a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/AbstractServerSession.java
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/AbstractServerSession.java
@@ -24,10 +24,10 @@
import org.eclipse.scout.rt.platform.util.event.FastListenerList;
import org.eclipse.scout.rt.platform.util.event.IFastListenerList;
import org.eclipse.scout.rt.rest.cancellation.RestRequestCancellationRegistry;
-import org.eclipse.scout.rt.server.context.ServerRunContext;
-import org.eclipse.scout.rt.server.extension.IServerSessionExtension;
-import org.eclipse.scout.rt.server.extension.ServerSessionChains.ServerSessionLoadSessionChain;
import org.eclipse.scout.rt.server.session.ServerSessionProviderWithCache;
+import org.eclipse.scout.rt.server.session.context.ServerSessionRunContext;
+import org.eclipse.scout.rt.server.session.extension.IServerSessionExtension;
+import org.eclipse.scout.rt.server.session.extension.ServerSessionChains.ServerSessionLoadSessionChain;
import org.eclipse.scout.rt.shared.extension.AbstractSerializableExtension;
import org.eclipse.scout.rt.shared.extension.IExtensibleObject;
import org.eclipse.scout.rt.shared.extension.IExtension;
@@ -206,7 +206,7 @@ protected void cancelRunningJobs() {
RunContext currentRunContext = RunContext.CURRENT.get();
// cancel requests of this session.
BEANS.get(RestRequestCancellationRegistry.class)
- .cancel(runContext -> runContext != currentRunContext && runContext instanceof ServerRunContext && ((ServerRunContext) runContext).getSession() == AbstractServerSession.this);
+ .cancel(runContext -> runContext != currentRunContext && runContext instanceof ServerSessionRunContext && ((ServerSessionRunContext) runContext).getSession() == AbstractServerSession.this);
// cancel running jobs of this session.
Jobs.getJobManager().cancel(Jobs.newFutureFilterBuilder()
diff --git a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/IServerSession.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/IServerSession.java
similarity index 86%
rename from org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/IServerSession.java
rename to org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/IServerSession.java
index 3ec60384c65..172c8a5d815 100644
--- a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/IServerSession.java
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/IServerSession.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
diff --git a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/IServerSessionCacheMBean.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/IServerSessionCacheMBean.java
similarity index 95%
rename from org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/IServerSessionCacheMBean.java
rename to org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/IServerSessionCacheMBean.java
index c87622040ed..e2b0c04a3dc 100644
--- a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/IServerSessionCacheMBean.java
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/IServerSessionCacheMBean.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
diff --git a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/IServerSessionLifecycleHandler.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/IServerSessionLifecycleHandler.java
similarity index 89%
rename from org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/IServerSessionLifecycleHandler.java
rename to org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/IServerSessionLifecycleHandler.java
index c87daafbbad..d8bcd3b9a06 100644
--- a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/IServerSessionLifecycleHandler.java
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/IServerSessionLifecycleHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
diff --git a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ScoutSessionBindingListener.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ScoutSessionBindingListener.java
similarity index 96%
rename from org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ScoutSessionBindingListener.java
rename to org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ScoutSessionBindingListener.java
index 20332dca480..727cbc50539 100644
--- a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ScoutSessionBindingListener.java
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ScoutSessionBindingListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
diff --git a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionCache.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionCache.java
similarity index 98%
rename from org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionCache.java
rename to org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionCache.java
index e9ac06055d9..94eafc2eb52 100644
--- a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionCache.java
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionCache.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
diff --git a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionCacheMBean.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionCacheMBean.java
similarity index 97%
rename from org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionCacheMBean.java
rename to org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionCacheMBean.java
index ca1df888f5a..d0f96bbc635 100644
--- a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionCacheMBean.java
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionCacheMBean.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
diff --git a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionEntry.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionEntry.java
similarity index 94%
rename from org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionEntry.java
rename to org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionEntry.java
index 11f9fd70b13..30e02a352a7 100644
--- a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionEntry.java
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionEntry.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -14,7 +14,7 @@
import org.eclipse.scout.rt.platform.util.FinalValue;
import org.eclipse.scout.rt.server.IServerSession;
-import org.eclipse.scout.rt.server.context.ServerRunContexts;
+import org.eclipse.scout.rt.server.session.context.ServerSessionRunContexts;
/**
* Cache Entry for {@link IServerSession} and meta data: HttpSessions using this {@link IServerSession} and lifecycle
@@ -81,7 +81,7 @@ protected void destroy() {
}
else {
// in case the destroy is called by the servlet container when invalidating the HTTP session: ensure the session is on the context
- ServerRunContexts
+ ServerSessionRunContexts
.copyCurrent(true)
.withSession(session)
.run(() -> m_sessionLifecycleHandler.destroy(session));
diff --git a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionLifecycleHandler.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionLifecycleHandler.java
similarity index 97%
rename from org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionLifecycleHandler.java
rename to org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionLifecycleHandler.java
index 5e950dda8ae..98f3edaff34 100644
--- a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionLifecycleHandler.java
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionLifecycleHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
diff --git a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionProvider.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionProvider.java
similarity index 91%
rename from org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionProvider.java
rename to org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionProvider.java
index 0f5ec3f50cd..ff19eff9710 100644
--- a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionProvider.java
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2026 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -17,7 +17,8 @@
import org.eclipse.scout.rt.platform.util.Assertions.AssertionException;
import org.eclipse.scout.rt.server.IServerSession;
import org.eclipse.scout.rt.server.context.ServerRunContext;
-import org.eclipse.scout.rt.server.context.ServerRunContexts;
+import org.eclipse.scout.rt.server.session.context.ServerSessionRunContexts;
+import org.eclipse.scout.rt.shared.session.SessionId;
import org.eclipse.scout.rt.shared.session.Sessions;
/**
@@ -48,7 +49,7 @@ public SESSION provide(final ServerRunContext s
* Creates and initializes a new {@link IServerSession} with data as specified by the given {@link ServerRunContext}.
*
* @param sessionId
- * unique session ID, or null to use a random id (see {@link Sessions#randomSessionId()}).
+ * unique session ID, or null to use a random id (see {@link SessionId#randomSessionId()}).
* @param serverRunContext
* applied during session start.
* @return the new session, is not null.
@@ -65,7 +66,7 @@ public SESSION provide(final String sessionId,
* Creates and initializes a new {@link IServerSession} with data as specified by the given {@link ServerRunContext}.
*
* @param sessionId
- * unique session ID, or null to use a random id (see {@link Sessions#randomSessionId()}).
+ * unique session ID, or null to use a random id (see {@link SessionId#randomSessionId()}).
* @param serverRunContext
* applied during session start.
* @return the new session or {@code null} if no session class could be found.
@@ -73,7 +74,7 @@ public SESSION provide(final String sessionId,
* if session creation failed.
*/
public SESSION opt(final String sessionId, final ServerRunContext serverRunContext) {
- final String sid = sessionId != null ? sessionId : Sessions.randomSessionId();
+ final String sid = sessionId != null ? sessionId : SessionId.randomSessionId();
// Create the session with the given context applied.
return serverRunContext
@@ -87,7 +88,7 @@ public SESSION opt(final String sessionId, fina
}
// 2. Start the session.
- return ServerRunContexts.copyCurrent()
+ return ServerSessionRunContexts.copyCurrent()
.withSession(session)
.withTransactionScope(TransactionScope.MANDATORY) // run in the same transaction
.call(() -> {
diff --git a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionProviderWithCache.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionProviderWithCache.java
similarity index 98%
rename from org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionProviderWithCache.java
rename to org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionProviderWithCache.java
index 325fe8574b1..17d2add67ba 100644
--- a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionProviderWithCache.java
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/ServerSessionProviderWithCache.java
@@ -23,7 +23,7 @@
import org.eclipse.scout.rt.server.IServerSession;
import org.eclipse.scout.rt.server.ServerConfigProperties.ServerSessionCacheExpirationProperty;
import org.eclipse.scout.rt.server.context.ServerRunContext;
-import org.eclipse.scout.rt.server.context.ServerRunContexts;
+import org.eclipse.scout.rt.server.session.context.ServerSessionRunContexts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -139,7 +139,7 @@ protected void execEntryEvicted(CompositeObject key, IServerSession session) {
session.stop();
}
else {
- ServerRunContexts
+ ServerSessionRunContexts
.copyCurrent(true)
.withSession(session)
.run(session::stop);
diff --git a/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/context/HttpServerSessionRunContextProducer.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/context/HttpServerSessionRunContextProducer.java
new file mode 100644
index 00000000000..5316b2a5cc9
--- /dev/null
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/context/HttpServerSessionRunContextProducer.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2010, 2026 BSI Business Systems Integration AG
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.eclipse.scout.rt.server.session.context;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpSession;
+
+import org.eclipse.scout.rt.platform.BEANS;
+import org.eclipse.scout.rt.platform.Replace;
+import org.eclipse.scout.rt.platform.util.StringUtility;
+import org.eclipse.scout.rt.server.IServerSession;
+import org.eclipse.scout.rt.server.commons.HttpSessionMutex;
+import org.eclipse.scout.rt.server.commons.servlet.HttpClientInfo;
+import org.eclipse.scout.rt.server.context.HttpServerRunContextProducer;
+import org.eclipse.scout.rt.server.context.ServerRunContext;
+import org.eclipse.scout.rt.server.context.ServerRunContexts;
+import org.eclipse.scout.rt.server.session.IServerSessionLifecycleHandler;
+import org.eclipse.scout.rt.server.session.ServerSessionCache;
+import org.eclipse.scout.rt.server.session.ServerSessionLifecycleHandler;
+import org.eclipse.scout.rt.shared.session.SessionId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Replace
+public class HttpServerSessionRunContextProducer extends HttpServerRunContextProducer {
+
+ private static final Logger LOG = LoggerFactory.getLogger(HttpServerSessionRunContextProducer.class);
+
+ private final ServerSessionCache m_serverSessionCache;
+
+ public HttpServerSessionRunContextProducer() {
+ m_serverSessionCache = createServerSessionCache();
+ }
+
+ @Override
+ public ServerSessionRunContext produce(HttpServletRequest req, HttpServletResponse resp) {
+ return produce(req, resp, null, null);
+ }
+
+ @Override
+ public ServerSessionRunContext produce(HttpServletRequest req, HttpServletResponse resp, String scoutSessionId, ServerRunContext existingContext) {
+ ServerRunContext contextToFill = existingContext;
+ if (contextToFill == null) {
+ contextToFill = ServerRunContexts.copyCurrent(true);
+ }
+
+ final ServerSessionRunContext serverRunContext = (ServerSessionRunContext) getInnerRunContextProducer().produce(req, resp, contextToFill);
+ serverRunContext.withUserAgent(HttpClientInfo.get(req).toUserAgents().build());
+ if (!hasSessionSupport()) {
+ // don't touch the session
+ return serverRunContext;
+ }
+
+ final IServerSession session = getOrCreateScoutSession(req, serverRunContext, scoutSessionId);
+ return serverRunContext
+ .withSession(session);
+ }
+
+ protected ServerSessionCache createServerSessionCache() {
+ return BEANS.get(ServerSessionCache.class);
+ }
+
+ public ServerSessionCache getServerSessionCache() {
+ return m_serverSessionCache;
+ }
+
+ /**
+ * Lookup (or create if not existing) an {@link IServerSession} on the {@link HttpServletRequest} specified. If a new
+ * session must be created, a random session id is used.
+ *
+ * @param serverRunContextForSessionStart
+ * If no session is already available: the new session will be started using this {@link ServerRunContext}.
+ * May not be {@code null}.
+ * @return the existing or newly created session or {@code null} if this producer has no session support (see
+ * {@link #withSessionSupport(boolean)}).
+ */
+ public IServerSession getOrCreateScoutSession(HttpServletRequest req, ServerRunContext serverRunContextForSessionStart) {
+ return getOrCreateScoutSession(req, serverRunContextForSessionStart, null);
+ }
+
+ /**
+ * Lookup (or create if not existing) an {@link IServerSession} on the {@link HttpServletRequest} specified. If a new
+ * session must be created, the given id is used.
+ *
+ * @param serverRunContextForSessionStart
+ * If no session is already available: the new session will be started using this {@link ServerRunContext}.
+ * May not be {@code null}.
+ * @return the existing or newly created session or {@code null} if this producer has no session support (see
+ * {@link #withSessionSupport(boolean)}).
+ */
+ public IServerSession getOrCreateScoutSession(HttpServletRequest req, ServerRunContext serverRunContextForSessionStart, String scoutSessionId) {
+ if (!hasSessionSupport()) {
+ return null;
+ }
+
+ final HttpSession httpSession = req.getSession();
+ final String sid = ensureScoutSessionId(scoutSessionId, httpSession);
+ final IServerSessionLifecycleHandler lifecycleHandler = new ServerSessionLifecycleHandler(sid, serverRunContextForSessionStart);
+ final IServerSession session = getServerSessionCache().getOrCreate(lifecycleHandler, httpSession);
+ if (session == null) {
+ LOG.warn("{} is configured to create a Scout session but no class implementing {} could be found. Consider disabling session support.",
+ HttpServerRunContextProducer.class.getName(), IServerSession.class.getName());
+ }
+ return session;
+ }
+
+ protected String ensureScoutSessionId(String scoutSessionId, HttpSession httpSession) {
+ if (StringUtility.hasText(scoutSessionId)) {
+ return scoutSessionId;
+ }
+ return computeSessionIdIfAbsent(httpSession);
+ }
+
+ protected String computeSessionIdIfAbsent(HttpSession httpSession) {
+ synchronized (HttpSessionMutex.of(httpSession)) {
+ String scoutSessionId = (String) httpSession.getAttribute(SCOUT_SESSION_ID_KEY);
+ if (StringUtility.hasText(scoutSessionId)) {
+ return scoutSessionId;
+ }
+
+ scoutSessionId = SessionId.randomSessionId();
+ httpSession.setAttribute(SCOUT_SESSION_ID_KEY, scoutSessionId);
+ return scoutSessionId;
+ }
+ }
+}
+
diff --git a/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/context/ServerSessionRunContext.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/context/ServerSessionRunContext.java
new file mode 100644
index 00000000000..86adb90b059
--- /dev/null
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/context/ServerSessionRunContext.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.eclipse.scout.rt.server.session.context;
+
+import java.util.Collection;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.security.auth.Subject;
+
+import org.eclipse.scout.rt.dataobject.id.NodeId;
+import org.eclipse.scout.rt.platform.Replace;
+import org.eclipse.scout.rt.platform.chain.callable.CallableChain;
+import org.eclipse.scout.rt.platform.context.RunContext;
+import org.eclipse.scout.rt.platform.context.RunMonitor;
+import org.eclipse.scout.rt.platform.logger.DiagnosticContextValueProcessor.IDiagnosticContextValueProvider;
+import org.eclipse.scout.rt.platform.transaction.ITransaction;
+import org.eclipse.scout.rt.platform.transaction.ITransactionMember;
+import org.eclipse.scout.rt.platform.transaction.TransactionScope;
+import org.eclipse.scout.rt.platform.util.ThreadLocalProcessor;
+import org.eclipse.scout.rt.platform.util.ToStringBuilder;
+import org.eclipse.scout.rt.server.clientnotification.ClientNotificationCollector;
+import org.eclipse.scout.rt.server.context.ServerRunContext;
+import org.eclipse.scout.rt.server.IServerSession;
+import org.eclipse.scout.rt.server.session.ServerSessionProvider;
+import org.eclipse.scout.rt.shared.ISession;
+import org.eclipse.scout.rt.shared.ui.UserAgent;
+
+import io.opentelemetry.context.Context;
+
+@Replace
+public class ServerSessionRunContext extends ServerRunContext {
+
+ protected IServerSession m_session;
+
+ @Override
+ protected void interceptCallableChain(CallableChain callableChain) {
+ callableChain.add(new ThreadLocalProcessor<>(ISession.CURRENT, m_session));
+ super.interceptCallableChain(callableChain);
+ }
+
+ /**
+ * @see #withSession(IServerSession)
+ */
+ public IServerSession getSession() {
+ return m_session;
+ }
+
+ /**
+ * Associates this context with the given {@link IServerSession}, meaning that any code running on behalf of this
+ * context has that {@link ISession} set in {@link ISession#CURRENT} thread-local.
+ */
+ public ServerSessionRunContext withSession(final IServerSession session) {
+ m_session = session;
+ return this;
+ }
+
+ @Override
+ public ServerSessionRunContext withRunMonitor(final RunMonitor runMonitor) {
+ super.withRunMonitor(runMonitor);
+ return this;
+ }
+
+ @Override
+ public ServerSessionRunContext withSubject(final Subject subject) {
+ super.withSubject(subject);
+ return this;
+ }
+
+ @Override
+ public ServerSessionRunContext withLocale(final Locale locale) {
+ super.withLocale(locale);
+ return this;
+ }
+
+ @Override
+ public ServerSessionRunContext withCorrelationId(final String correlationId) {
+ super.withCorrelationId(correlationId);
+ return this;
+ }
+
+ @Override
+ public ServerSessionRunContext withOpenTelemetryContext(Context context) {
+ super.withOpenTelemetryContext(context);
+ return this;
+ }
+
+ @Override
+ public ServerSessionRunContext withTransactionScope(final TransactionScope transactionScope) {
+ super.withTransactionScope(transactionScope);
+ return this;
+ }
+
+ @Override
+ public ServerSessionRunContext withTransaction(final ITransaction transaction) {
+ super.withTransaction(transaction);
+ return this;
+ }
+
+ @Override
+ public ServerSessionRunContext withTransactionMember(final ITransactionMember transactionMember) {
+ super.withTransactionMember(transactionMember);
+ return this;
+ }
+
+ @Override
+ public ServerSessionRunContext withoutTransactionMembers() {
+ super.withoutTransactionMembers();
+ return this;
+ }
+
+ @Override
+ public ServerSessionRunContext withThreadLocal(final ThreadLocal threadLocal, final THREAD_LOCAL value) {
+ super.withThreadLocal(threadLocal, value);
+ return this;
+ }
+
+ @Override
+ public ServerSessionRunContext withDiagnostic(IDiagnosticContextValueProvider provider) {
+ super.withDiagnostic(provider);
+ return this;
+ }
+
+ @Override
+ public ServerSessionRunContext withDiagnostics(Collection extends IDiagnosticContextValueProvider> diagnosticContextValueProviders) {
+ super.withDiagnostics(diagnosticContextValueProviders);
+ return this;
+ }
+
+ @Override
+ public ServerSessionRunContext withProperty(final Object key, final Object value) {
+ super.withProperty(key, value);
+ return this;
+ }
+
+ @Override
+ public ServerSessionRunContext withProperties(final Map, ?> properties) {
+ super.withProperties(properties);
+ return this;
+ }
+
+ @Override
+ public ServerSessionRunContext withClientNotificationCollector(final ClientNotificationCollector collector) {
+ m_clientNotificationCollector = collector;
+ return this;
+ }
+
+ @Override
+ public ServerSessionRunContext withClientNodeId(NodeId clientNodeId) {
+ super.withClientNodeId(clientNodeId);
+ return this;
+ }
+
+ /**
+ * Associates this context with the given {@link UserAgent}, meaning that any code running on behalf of this context
+ * has that {@link UserAgent} set in {@link UserAgent#CURRENT} thread-local.
+ */
+ @Override
+ public ServerSessionRunContext withUserAgent(final UserAgent userAgent) {
+ m_userAgent = userAgent;
+ return this;
+ }
+
+ @Override
+ protected void interceptToStringBuilder(final ToStringBuilder builder) {
+ super.interceptToStringBuilder(builder
+ .ref("session", getSession()));
+ }
+
+ @Override
+ protected void copyValues(final RunContext runContext) {
+ super.copyValues(runContext);
+
+ final ServerSessionRunContext origin = (ServerSessionRunContext) runContext;
+ m_session = origin.m_session;
+ }
+
+ @Override
+ protected void fillCurrentValues() {
+ super.fillCurrentValues();
+
+ m_session = ServerSessionProvider.currentSession();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public T getAdapter(final Class type) {
+ if (ISession.class.isAssignableFrom(type)) {
+ return (T) m_session;
+ }
+ return null;
+ }
+}
diff --git a/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/context/ServerSessionRunContextProducer.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/context/ServerSessionRunContextProducer.java
new file mode 100644
index 00000000000..3b63fb6a612
--- /dev/null
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/context/ServerSessionRunContextProducer.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.eclipse.scout.rt.server.session.context;
+
+import javax.security.auth.Subject;
+
+import org.eclipse.scout.rt.platform.BEANS;
+import org.eclipse.scout.rt.platform.Replace;
+import org.eclipse.scout.rt.platform.transaction.TransactionScope;
+import org.eclipse.scout.rt.platform.util.ObjectUtility;
+import org.eclipse.scout.rt.server.context.ServerRunContext;
+import org.eclipse.scout.rt.server.context.ServerRunContextProducer;
+import org.eclipse.scout.rt.server.IServerSession;
+import org.eclipse.scout.rt.server.session.ServerSessionProviderWithCache;
+
+@Replace
+public class ServerSessionRunContextProducer extends ServerRunContextProducer {
+
+ @Override
+ public ServerRunContext produce(Subject subject) {
+ final ServerSessionRunContext serverRunContext = ServerSessionRunContexts.copyCurrent(true)
+ .withSubject(subject)
+ .withTransactionScope(TransactionScope.REQUIRES_NEW);
+
+ // ensure that the session belongs to the specified subject
+ // use the current set subject as subject of the session, because if the session is not null it must be the current session
+ IServerSession session = serverRunContext.getSession();
+ if (session == null || ObjectUtility.notEquals(Subject.current(), subject)) {
+ serverRunContext.withSession(BEANS.get(ServerSessionProviderWithCache.class).provide(serverRunContext.copy()));
+ }
+
+ return serverRunContext;
+ }
+}
diff --git a/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/context/ServerSessionRunContexts.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/context/ServerSessionRunContexts.java
new file mode 100644
index 00000000000..907c82eb5f0
--- /dev/null
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/context/ServerSessionRunContexts.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.eclipse.scout.rt.server.session.context;
+
+import org.eclipse.scout.rt.platform.BEANS;
+import org.eclipse.scout.rt.platform.Replace;
+import org.eclipse.scout.rt.platform.context.PropertyMap;
+import org.eclipse.scout.rt.platform.context.RunContext;
+import org.eclipse.scout.rt.platform.context.RunContexts;
+import org.eclipse.scout.rt.platform.context.RunContexts.RunContextFactory;
+import org.eclipse.scout.rt.platform.context.RunMonitor;
+import org.eclipse.scout.rt.platform.transaction.ITransactionMember;
+import org.eclipse.scout.rt.platform.transaction.TransactionScope;
+import org.eclipse.scout.rt.platform.util.Assertions;
+import org.eclipse.scout.rt.platform.util.Assertions.AssertionException;
+import org.eclipse.scout.rt.server.context.ServerRunContext;
+import org.eclipse.scout.rt.server.context.ServerRunContexts.ServerRunContextFactory;
+
+/**
+ * Factory methods to create a new {@link ServerRunContext} objects to propagate server-side state. See
+ * {@link RunContexts} for more information.
+ *
+ * Usage:
+ *
+ *
+ * ServerRunContexts.copyCurrent()
+ * .withLocale(Locale.US)
+ * .withSubject(...)
+ * .withSession(...)
+ * .withTransactionScope(TransactionScope.REQUIRES_NEW)
+ * .run(new IRunnable() {
+ *
+ * @Override
+ * public void run() {
+ * // run code on behalf of the context
+ * }
+ * });
+ *
+ *
+ * @see ServerRunContext
+ * @since 5.1
+ */
+public final class ServerSessionRunContexts {
+
+ private ServerSessionRunContexts() {
+ }
+
+ /**
+ * Creates an empty {@link ServerRunContext} with all values managed by {@link ServerRunContext} class set to their
+ * default value. This method does not require to already run in a {@link RunContext}.
+ *
+ * {@link RunMonitor}
+ * Uses a new {@link RunMonitor} which is not registered as child monitor of {@link RunMonitor#CURRENT}, meaning that
+ * the context is not cancelled upon cancellation of the current monitor.
+ *
+ * {@link TransactionScope}
+ * Uses the transaction scope {@link TransactionScope#REQUIRES_NEW} which always starts a new transaction.
+ */
+ public static ServerSessionRunContext empty() {
+ return BEANS.get(ServerSessionRunContextFactory.class).empty();
+ }
+
+ /**
+ * Creates a "snapshot" of the current calling context for values managed by {@link ServerRunContext} class. This
+ * method requires to run in a {@link RunContext}, meaning that {@link RunContext#CURRENT} is set, or this method
+ * throws an {@link AssertionException} otherwise.
+ *
+ * {@link RunMonitor}
+ * Uses a new {@link RunMonitor} which is registered as child monitor of {@link RunMonitor#CURRENT}, meaning that the
+ * context is cancelled upon cancellation of the current (parent) monitor. Cancellation works top-down, so
+ * cancellation of the context's monitor has no effect to the current (parent) monitor.
+ *
+ * {@link TransactionScope}
+ * Uses the transaction scope {@link TransactionScope#REQUIRES_NEW} which always starts a new transaction.
+ *
+ * {@link ITransactionMember}
+ * If the current context has some transaction members registered, those are not registered with the new context.
+ *
+ * {@link ThreadLocal}
+ * Thread-Locals associated with the current context via {@link RunContext#withThreadLocal(ThreadLocal, Object)} are
+ * copied as well.
+ *
+ * @throws AssertionException
+ * if not running in a {@link RunContext}
+ */
+ public static ServerSessionRunContext copyCurrent() {
+ return copyCurrent(false);
+ }
+
+ /**
+ * Same as {@link ServerSessionRunContexts#copyCurrent()}, but less strict if not running in a {@link RunContext} yet.
+ *
+ * @param orElseEmpty
+ * indicates whether to return an empty {@link RunContext} if not running in a context yet.
+ * @throws AssertionException
+ * if not running in a {@link RunContext}, and orElseEmpty is set to false.
+ */
+ public static ServerSessionRunContext copyCurrent(final boolean orElseEmpty) {
+ if (RunContext.CURRENT.get() != null) {
+ return BEANS.get(ServerSessionRunContextFactory.class).copyCurrent();
+ }
+ if (orElseEmpty) {
+ return BEANS.get(ServerSessionRunContextFactory.class).empty();
+ }
+ return Assertions.fail("Not running in a RunContext. Use '{}.empty()' or {}.copyCurrent(true) instead.", ServerSessionRunContexts.class.getSimpleName(), ServerSessionRunContexts.class.getSimpleName());
+ }
+
+ /**
+ * Factory to create initialized {@link ServerRunContext} objects.
+ */
+ @Replace
+ public static class ServerSessionRunContextFactory extends ServerRunContextFactory {
+
+ @Override
+ public ServerSessionRunContext empty() {
+ return (ServerSessionRunContext) super.empty()
+ .withProperty(PropertyMap.PROP_SERVER_SCOPE, true)
+ .withTransactionScope(TransactionScope.REQUIRES_NEW);
+ }
+
+ @Override
+ public ServerSessionRunContext copyCurrent() {
+ return (ServerSessionRunContext) super.copyCurrent()
+ .withProperty(PropertyMap.PROP_SERVER_SCOPE, true)
+ .withTransactionScope(TransactionScope.REQUIRES_NEW);
+ }
+
+ @Override
+ protected ServerSessionRunContext newInstance() {
+ return BEANS.get(ServerSessionRunContext.class);
+ }
+ }
+}
diff --git a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/extension/AbstractServerSessionExtension.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/extension/AbstractServerSessionExtension.java
similarity index 78%
rename from org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/extension/AbstractServerSessionExtension.java
rename to org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/extension/AbstractServerSessionExtension.java
index 4a591119cf4..83698844396 100644
--- a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/extension/AbstractServerSessionExtension.java
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/extension/AbstractServerSessionExtension.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -7,10 +7,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.scout.rt.server.extension;
+package org.eclipse.scout.rt.server.session.extension;
import org.eclipse.scout.rt.server.AbstractServerSession;
-import org.eclipse.scout.rt.server.extension.ServerSessionChains.ServerSessionLoadSessionChain;
+import org.eclipse.scout.rt.server.session.extension.ServerSessionChains.ServerSessionLoadSessionChain;
import org.eclipse.scout.rt.shared.extension.AbstractSerializableExtension;
public abstract class AbstractServerSessionExtension extends AbstractSerializableExtension implements IServerSessionExtension {
diff --git a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/extension/IServerSessionExtension.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/extension/IServerSessionExtension.java
similarity index 69%
rename from org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/extension/IServerSessionExtension.java
rename to org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/extension/IServerSessionExtension.java
index aa26dc65484..bcd4106814f 100644
--- a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/extension/IServerSessionExtension.java
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/extension/IServerSessionExtension.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -7,10 +7,11 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.scout.rt.server.extension;
+package org.eclipse.scout.rt.server.session.extension;
+
import org.eclipse.scout.rt.server.AbstractServerSession;
-import org.eclipse.scout.rt.server.extension.ServerSessionChains.ServerSessionLoadSessionChain;
+import org.eclipse.scout.rt.server.session.extension.ServerSessionChains.ServerSessionLoadSessionChain;
import org.eclipse.scout.rt.shared.extension.IExtension;
public interface IServerSessionExtension extends IExtension {
diff --git a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/extension/ServerSessionChains.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/extension/ServerSessionChains.java
similarity index 92%
rename from org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/extension/ServerSessionChains.java
rename to org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/extension/ServerSessionChains.java
index c8dfd350c06..bdd2f7a95bc 100644
--- a/org.eclipse.scout.rt.server/src/main/java/org/eclipse/scout/rt/server/extension/ServerSessionChains.java
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/extension/ServerSessionChains.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2023 BSI Business Systems Integration AG
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
@@ -7,7 +7,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.scout.rt.server.extension;
+package org.eclipse.scout.rt.server.session.extension;
import java.util.List;
diff --git a/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/services/common/clustersync/SessionClusterSynchronizationService.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/services/common/clustersync/SessionClusterSynchronizationService.java
new file mode 100644
index 00000000000..6de44bd0013
--- /dev/null
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/services/common/clustersync/SessionClusterSynchronizationService.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.eclipse.scout.rt.server.session.services.common.clustersync;
+
+import org.eclipse.scout.rt.platform.BEANS;
+import org.eclipse.scout.rt.platform.Replace;
+import org.eclipse.scout.rt.platform.context.RunContext;
+import org.eclipse.scout.rt.server.context.ServerRunContext;
+import org.eclipse.scout.rt.server.services.common.clustersync.ClusterSynchronizationService;
+import org.eclipse.scout.rt.server.session.ServerSessionProviderWithCache;
+import org.eclipse.scout.rt.server.session.context.ServerSessionRunContext;
+
+@Replace
+public class SessionClusterSynchronizationService extends ClusterSynchronizationService {
+
+ @Override
+ protected ServerRunContext createRunContext() {
+ ServerSessionRunContext serverRunContext = (ServerSessionRunContext) super.createRunContext();
+ return serverRunContext.withSession(BEANS.get(ServerSessionProviderWithCache.class).provide(serverRunContext.copy()));
+ }
+}
diff --git a/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/servicetunnel/SessionServiceTunnelService.java b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/servicetunnel/SessionServiceTunnelService.java
new file mode 100644
index 00000000000..c0df628d1f0
--- /dev/null
+++ b/org.eclipse.scout.rt.server.session/src/main/java/org/eclipse/scout/rt/server/session/servicetunnel/SessionServiceTunnelService.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.eclipse.scout.rt.server.session.servicetunnel;
+
+import jakarta.servlet.http.HttpServletRequest;
+
+import org.eclipse.scout.rt.platform.Replace;
+import org.eclipse.scout.rt.platform.util.LazyValue;
+import org.eclipse.scout.rt.server.IServerSession;
+import org.eclipse.scout.rt.server.commons.servlet.IHttpServletRoundtrip;
+import org.eclipse.scout.rt.server.context.ServerRunContext;
+import org.eclipse.scout.rt.server.servicetunnel.ServiceTunnelService;
+import org.eclipse.scout.rt.server.session.context.HttpServerSessionRunContextProducer;
+import org.eclipse.scout.rt.server.session.context.ServerSessionRunContext;
+import org.eclipse.scout.rt.shared.servicetunnel.ServiceTunnelRequest;
+import org.eclipse.scout.rt.shared.session.SessionId;
+
+@Replace
+public class SessionServiceTunnelService extends ServiceTunnelService {
+
+ protected transient LazyValue m_serverSessionRunContextProducer = new LazyValue<>(HttpServerSessionRunContextProducer.class);
+
+ @Override
+ protected ServerRunContext createServiceTunnelRunContext(ServiceTunnelRequest serviceRequest) {
+ ServerSessionRunContext serverRunContext = (ServerSessionRunContext) super.createServiceTunnelRunContext(serviceRequest);
+
+ //if (serviceRequest.getSessionId() != null) { // FIXME PBZ SESSION cleanup
+ if (SessionId.CURRENT.get() != null) {
+ final HttpServletRequest req = IHttpServletRoundtrip.CURRENT_HTTP_SERVLET_REQUEST.get();
+ final IServerSession session = m_serverSessionRunContextProducer.get().getOrCreateScoutSession(req, serverRunContext, SessionId.CURRENT.get());
+ serverRunContext.withSession(session);
+ }
+ return serverRunContext;
+ }
+}
diff --git a/org.eclipse.scout.rt.server.session/src/main/resources/META-INF/scout.xml b/org.eclipse.scout.rt.server.session/src/main/resources/META-INF/scout.xml
new file mode 100644
index 00000000000..e17c07b8ff8
--- /dev/null
+++ b/org.eclipse.scout.rt.server.session/src/main/resources/META-INF/scout.xml
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/org.eclipse.scout.rt.server.test/pom.xml b/org.eclipse.scout.rt.server.test/pom.xml
index 1e381d5da1b..c8672a56e1c 100644
--- a/org.eclipse.scout.rt.server.test/pom.xml
+++ b/org.eclipse.scout.rt.server.test/pom.xml
@@ -14,7 +14,7 @@
org.eclipse.scout.rtorg.eclipse.scout.rt
- 26.1-SNAPSHOT
+ 26.2-SNAPSHOT../org.eclipse.scout.rt
diff --git a/org.eclipse.scout.rt.server.test/src/main/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunner.java b/org.eclipse.scout.rt.server.test/src/main/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunner.java
index c2ae75de66e..9e9e497d1ba 100644
--- a/org.eclipse.scout.rt.server.test/src/main/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunner.java
+++ b/org.eclipse.scout.rt.server.test/src/main/java/org/eclipse/scout/rt/testing/server/runner/ServerTestRunner.java
@@ -11,15 +11,12 @@
import java.lang.reflect.Method;
-import org.eclipse.scout.rt.platform.BEANS;
import org.eclipse.scout.rt.platform.context.RunContext;
import org.eclipse.scout.rt.platform.reflect.ReflectionUtility;
import org.eclipse.scout.rt.server.context.ServerRunContexts;
-import org.eclipse.scout.rt.server.session.ServerSessionProvider;
import org.eclipse.scout.rt.testing.platform.runner.PlatformTestRunner;
import org.eclipse.scout.rt.testing.platform.runner.RunWithSubject;
import org.eclipse.scout.rt.testing.server.runner.statement.ClientNotificationsStatement;
-import org.eclipse.scout.rt.testing.server.runner.statement.ServerRunContextStatementFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -28,7 +25,7 @@
import org.junit.runners.model.Statement;
/**
- * Use this Runner to run tests which require a session and transaction context.
+ * Use this Runner to run tests which require a session and transaction context. FIXME PBZ SESSION cleanup javadoc
*
* Use the following mandatory annotations to configure the Runner:
*
@@ -53,7 +50,6 @@
*
Each test-method is executed in a separate transaction - meaning that the transaction boundary starts before
* executing the first 'before-method', and ends after executing the last 'after-method'.
*
By default, server sessions are shared among same users. This can be changed by setting the
- * {@link ServerSessionProvider} or a custom provider to {@link RunWithServerSession#provider()}.
*
'beforeClass' and 'afterClass' are executed in the same transaction.