TopLogic - the automated application engine
  • Releases
  • Dokumentation
  • Github
  • Discord
  1. Home
  2. Releases
  3. TL_8.0.0-alpha11
  4. #29840

8.0.0-alpha11
TopLogic Release

2026-10-20

enhancement

major
#29659
TL Views: Popover-Element mit beliebigem Inhalt an einer auslösenden Schaltfläche
#29713
TL Views: a user cannot hide a tile of a <dashboard> and add it again later
#29755
React-UI: Auswahl in Objektlisten (<object-list selection>) – Karten direkt anwählbar
#29756
React view table: Excel export (parity with classic TableComponent) and generic download view action
#29757
React view table: show row count (total / filtered / selected) like the classic table
#29776
TL Views: Einheitliches Drag & Drop für Tabellen, Baum-Tabellen, Bäume und Kanban-Boards mit mehreren Drop-Operationen, Drop-Positionen und Drag-Arten
#29782
Concept: Discover right for the model based security (filtered object sources, masked form fields)
#29785
OpenAPI server: request bodies are not validated against the declared schema
#29786
MUI: Avatar (TLAvatar) mit Material UI darstellen
#29787
React UI: Atomare Bausteine (Schaltflächen, Menü-Auslöser, Checkboxen, Eingabefelder, Chips, …) sehen überall gleich aus und lassen sich durch eine Komponentenbibliothek (z.B. Material UI) ersetzen
#29797
XML import into existing data: resolve IDs against existing objects, skip known subtrees, optional references, language and variables from the input
#29799
Form dependencies: derived fields do not follow edited values; Java script functions cannot report what they read to the ScriptTracer
#29811
TL Views: a <button> ignores the display mode of its command and always shows icon and label
#29812
TL Views: a table column declares its own comparator; enumeration columns follow the enumeration's order
#29814
TL Views: no supported way for a server-side background source (a bus listener) to push a channel value into a view; only <start-job> does it through internal API
#29815
TL Views table: no per-row CSS class (a row cannot be marked as changed, stale or own)
#29816
TL Views table: a <computed-column> cannot be hidden by default (shown only through the column chooser)
#29821
Design System wave 3b: table, tree, column selection and text read the design system package
#29825
Design System: column selection of the React table – grouping as one select, checkbox first, visible and hidden columns apart
#29829
TL Views: Beschreibbarer Kanal, der aus anderen Kanälen vorbelegt wird
#29830
Transaction monitor: Select a time range or a revision range instead of a single day.
#29836
Design System wave 4a: dialog, window, drawer, snackbar and notice bar read the design system package
#29840
Persistent object wrapper hierarchy: remove dead and duplicated code, move stateless behavior into interface defaults, replace class identity checks
#29849
Configuration: an encrypted property value that is not a valid encrypted value is silently "decrypted" to garbage instead of being rejected
#29854
PowerPoint-Präsentationen aus TL-Script erzeugen: deklarative Folienbausteine, Export in eine Firmenvorlage, Analyse von Vorlagen
#29858
Privileged TL-Script functions: authorize a configured script as a whole by a command group on a computed security object
#29859
React-Einfachauswahl: Die aktuell gewählte Option fehlt in der Optionsliste
#29866
Design System wave 4b: app shell, app bar, sidebar and bottom bar read the design system package
#29870
Design System wave 4c: layout containers read the design system package
#29907
Entwicklerkommandos und Skript-Rekorder außerhalb des Produktivmodus für alle Benutzer
minor
#28605
Möglichkeit zum Download eines aufgezeichneten Skripts
#28995
Spaltenfilter sollte Comparator der Spalte bei Sortierung der Optionen berücksichtigen
#29801
TL Views: the split of <adaptive-detail> is configurable (size, unit, min-size on <selector> and <detail>; drawer width as drawer-size)
#29805
TL Views: a <value-input> is declared like a model attribute (mandatory, annotations) - a mandatory enumeration input offers no "no value" option

defect

critical
#29784
OpenAPI server: basic authentication of a technical user accepts an empty password when the configured password is empty (e.g. unset environment variable)
#29823
HistoryCompaction: Löschen von REVISION/REVISION_XREF und Umschreiben der Revisionsbereiche in je einer Transaktion lässt die Datenbank explodieren
major
#29580
RowSourceObserver: a disposed observer is still notified and throws NPE (_scope null) from DerivedViewChannel and GlobalModelEventForwarder
#29783
TLScriptFunctions: a script function is bound to an arbitrary overload of the same name, including a private one
#29788
Configuration: the error for an undecodable encrypted property echoes the value (e.g. a plain-text password) into the log
#29789
tl:generate-java fails on the first build after a TopLogic version change: it neither resolves the engine web fragments nor reads the project's own model sources
#29791
TL Views table: the row activation button runs the activation command without selecting its row, so commands reading the selection channel see another row (wrong breadcrumb label)
#29792
TL Views: a closed dialog (and a left tile-stack frame) stays visible for 1 s unless the application ships its own exit animation - move the demo's animations into the engine
#29800
Model patch of an existing database fails when a class gains a generalization and overrides its attributes in the same change
#29806
WrapperGenerator: every top-level class of a module with a singleton extends StructuredElement (regression of #26716)
#29807
WrapperGenerator: classifier constants of two enumerations collide, the generated factory does not compile
#29808
TL Views: the <on-submit> command of a text or number <value-input> runs on Enter only, not when the field is left with a changed value
#29810
TL Views: the selection channel of a <tree> keeps an object deleted in another view, and scripts over it fail
#29813
TL Views: a <tree> does not react to a change of an object it does not display yet, so a node that becomes a child of a shown node does not appear
#29822
CompactHistoryTask: Wartungsfenster bleibt nach dem Lauf aktiv, Task-Ende geht im Neustart der Persistenzschicht verloren
#29824
TL Views table: "Standard wiederherstellen" in the column selection drops a declared group-by (and does not restore the declared sort)
#29837
TestCompileJSPs modifies the module's source webapp and breaks concurrently running scripted tests of the same module
#29838
ClusterManager: a database connection that failed in a cluster transaction is returned to the pool and keeps failing every refetch
#29846
Changing the type of a column with content fails on Oracle (ORA-01439) and of an indexed column on MS SQL Server
#29848
ReportQueueTest.testAddJob fails sporadically: the queue thread may process the job before the test checks that it is queued
#29871
TestZipper.testEmptyFolder fails depending on the order in which the file system lists a folder
#29878
React UI does not react behind a proxy that buffers or refuses the window event stream
minor
#29766
TL-Script add() wirft UnsupportedOperationException bei Multi-Referenz auf transientem Objekt
#29804
XML import: line and column of a message location are formatted with a thousands separator ("line 4,433")
#29809
TL Views: a <value-input type="tl.core:Binary"> shows the file name as text instead of the binary field (no upload, no download)

task

minor
#29790
Upgrade guide 7.11 to 8.0: add the Maven >= 3.8.9 requirement, state that 7.10.x applications can follow it, and point to it from the release notes
#29793
Developer docs: recipe for an application-defined primitive type whose display depends on the owning object (custom datatype, value class, type-level storage, label provider, input control)
enhancement

major

#29840

Persistent object wrapper hierarchy: remove dead and duplicated code, move stateless behavior into interface defaults, replace class identity checks

MigrationTLObject

Context

A persistent object is a KnowledgeObject plus a Java object implementing TLObject on top of it. The class chain between the two is PersistentObject → AbstractWrapper → AbstractBoundWrapper and then, in tl-element, AttributedWrapper and WrapperTLElement → StructuredElementWrapper → AttributedStructuredElementWrapper. The typed interfaces generated for a model (ABase, A`) are default methods over the `TLObject API; the implementation classes only attach them to a persistent object.

An inventory of the chain (bytecode reference scan over the whole reactor plus source grep, 2026-10-13) shows:

  • The only state in the chain is the KnowledgeObject reference and one lazily cached DataAccessProxy (AbstractWrapper.dap). Everything else is behavior over tHandle().
  • About 25 members of AbstractWrapper have no caller at all (single-partner association helpers and their private chain, getKOValue/`setKOValue`, setSecurity, hasIncoming, revalidate, isValid, idSet/`idArray`, both getWrappersFromIterator, static getReference(TLObject, Class, String), instance resolveOrderedValue, instance associateWith, setDouble, getWrappersFromAssociations(KAIterator, Filter, Filter)). Also dead: WrapperTLElement.USE_CACHE, StructuredElementWrapper.tGetFactory/traverseUp/preloadParents, the StructuredElement.addChild/removeChild defaults, WrapperFactory.getWrapper(TLID, String[]), getWrapper(Branch, Revision, TLID, String[]), hasWrapper(..), getWrapperMapping, and the classes ItemWrapperAdapter and TLObjectProxy.
  • Five overrides in AbstractWrapper are identical to the interface defaults they override (getValue, setValue, getKnowledgeBase, tValid, touch = tTouch).
  • The ~20 one-line delegations to PersistentObjectImpl/`PersistentScope` (tType, tContainer, tValue, tUpdate, tAdd, tRemove, getValue, setValue, generateFullText, the MetaElementHolder and TLScope methods) exist 19 times: in AttributedWrapper, AttributedStructuredElementWrapper and 17 hand-written copies (AttributedPerson, AttributedGroup, AttributedDocument, …, PersistentClassifier, PersistentEnumeration, DynamicType, DynamicModelPart, IMAPMail, IMAPMailFolder, …).
  • The typed accessors (getString(String), …), the resolveLinks/`resolveWrappers` forwarders, compareTo, getAllValues, getDSN and all of AbstractBoundWrapper are pure functions of this.
  • Engine code identifies persistent objects by class: instanceof PersistentObject in WrappedKnowledgeItem and ReferenceDeletionHelper (lifecycle hooks), instanceof AbstractBoundWrapper in BoundHelper, BoundSecurityFilter, Group.bind, DocumentJournalSupport, DocumentTileFormBuilder, instanceof WrapperTLElement inside the default method StructuredElement.move, casts to AbstractWrapper in DumpWriter, WrapperMetaAttributeUtil, AbstractGanttChartCreator, ExpressionSelectorComponent, CommentDialogComponent.

Goal

The chain carries no behavior that a TLObject implementation could not get from interface default methods, and the engine does not depend on the identity of these classes. This is the precondition for providing the typed interfaces for all TLObject implementations (transient objects, form overlays) and, later, for replacing the generated implementation classes.

Solution

Four steps, each building and tested on its own:

  1. Dead code. The members and classes listed above are deleted; the five overrides duplicating interface defaults are removed (callers of touch() use tTouch()).
  2. One copy of the persistent delegations. Two default-method interfaces in tl-element carry the delegations: AttributedObject extends Wrapper (type, container, attribute access, full text, attribute names, over PersistentObjectImpl) and PersistentTLScope extends MetaElementHolder (the MetaElementHolder and TLScope methods over PersistentScope). They are separate because engine code branches on instanceof TLScope, which the attributed classes are not. AttributedWrapper and AttributedStructuredElementWrapper implement both, PersistentScope the second, and the copies in AttributedAddress, AttributedCurrency, AttributedDocument, AttributedDocumentVersion, AttributedGroup, AttributedPerson, AttributedRole, AttributedUnit, AttributedWebFolder, PersistentView, IMAPMail and IMAPMailFolder are removed. Where a superclass declares one of these methods itself (a class method always wins over an interface default), the class keeps a one-line override forwarding to the interface default (AttributedDocument.getValue, AttributedAddress.generateFullText); for the same reason AbstractWrapper.tValue, tUpdate and getAllAttributeNames become Wrapper defaults. AttributedPerson and PersistentView support tAdd/`tRemove` like every attributed object (they threw UnsupportedOperationException before). The model-part classes DynamicModelPart, DynamicType, PersistentClassifier, PersistentEnumeration and PersistentStructuredTypePart keep their delegations: their tType() comes from PersistentModelPart, so they never were copies of AttributedWrapper.
  3. Stateless behavior as defaults. The typed accessors, getReference/`setReference`, the resolveLinks/`resolveWrappers`/`updateOrderedLinkSet` forwarders, getOutgoingWrappers/`getIncomingWrappers`, getAllValues, compareTo and getDSN are Wrapper defaults (the static helpers stay in AbstractWrapper). The AbstractBoundWrapper methods (getID, the role lookups, getSecurityChildren, getSecurityParent, getSecurityParents) are defaults of the interface BoundWrapper extends Wrapper, BoundObject; BoundObject itself is unchanged. Group and BoundedRole declare getID() explicitly because IGroup and BoundRole declare their own abstract getID(); PersonalConfigurationWrapper declares the three boolean accessors it also inherits as defaults from PersonalConfiguration.
  4. No class identity. The lifecycle hooks handleLoad, handleDelete, notifyUpcomingDeletion and refetchWrapper are the interface WrapperLifecycle (default no-ops) that WrappedKnowledgeItem, ReferenceDeletionHelper and DBKnowledgeBase call on the application object of an item; Wrapper extends it, PersistentObject implements it. StructuredElement.move rejects only a null child. The remaining engine sites use the interface they need: BoundObject/`BoundWrapper` instead of AbstractBoundWrapper (BoundHelper, BoundSecurityFilter, Group.bind, DocumentJournalSupport, DocumentTileFormBuilder), Wrapper instead of AbstractWrapper (DumpWriter, WrapperMetaAttributeUtil, AbstractGanttChartCreator, CommentDialogComponent, MapBasedPersistancySupport, SaveExpressionCommand, WebFolder.getOwners, the journal delegates, PersistentObjectImpl.setMetaElement), AttributedObject instead of AttributedWrapper (ContactApplyHandler, the create handlers, AbstractWrapperResolver), StructuredElement/`MetaElementHolder` instead of StructuredElementWrapper/`AttributedStructuredElementWrapper` (StructuredElementWrapperFactory, StructuredElementAttributeFilter, AttributedSearchComponent, StructureProperty, StructuredElementDOImportHandler, ScriptingElementUtil).

What remains in the classes: the KnowledgeObject reference, the DataAccessProxy cache with its reset, the (KnowledgeObject) constructor, toString/`equals`/`hashCode`, the static helpers, and the fields of the hand-written subclasses that keep state of their own. ImplementationTemplateGenerator still generates classes extending AttributedWrapper/`AttributedStructuredElementWrapper`.

Out of scope: the typed interface for transient objects and form overlays, and removing the generated implementation classes (separate ticket, enabled by this one).

Migration

Application code that calls one of the deleted members of AbstractWrapper, StructuredElementWrapper or WrapperFactory (see the list under Context) no longer compiles; these members had no caller in the engine. touch() is replaced by TLObject.tTouch(). The protected lifecycle hooks handleLoad(), handleDelete() and notifyUpcomingDeletion() are public interface methods of WrapperLifecycle; an override in application code must be declared public. The protected forwarders resolveWrappers, resolveWrappersTyped, resolveLinks and updateOrderedLinkSet are public Wrapper defaults; the typed accessors (getString(String), …) and the AbstractBoundWrapper methods are no longer final. A hand-written class that overrides getValue(String)/`setValue(String, Object)` or tValue/`tUpdate` keeps working. Application code checking instanceof AbstractBoundWrapper or instanceof AbstractWrapper should use BoundObject/`BoundWrapper` respectively Wrapper.

  • Get Started
  • Github
  • Discord
  • Das Unternehmen hinter TopLogic
  • Softwareentwicklung heute
  • Kontakt

© Copyright – Business Operation Systems GmbH

  • top-logic.com
  • Nutzungsbedingungen
  • Impressum
  • Rechtlicher Hinweis
  • Datenschutz
  • EN
  • Login