If this project saved you some time or made your day a little easier, a star would mean a lot — it helps others find it too.
This set of Java libraries forms a package to build Java web applications.
Contained subprojects are:
- ph-oton-html - Java wrapper for all HTML elements and attributes
- ph-oton-markdown - Java wrapper for Markdown processing (since 10.2.0; previously in ph-oton-html)
- ph-oton-jscode - a Java code model to build structured JS code
- ph-oton-jquery - an extension to ph-html-jscode to also support jQuery
- ph-oton-atom - ATOM newsfeed stuff
- ph-oton-io - basic IO stuff (since 9.2.0; previously in ph-oton-app)
- ph-oton-app - basic application stuff
- ph-oton-audit - basic auditing stuff
- ph-oton-ajax - basic AJAX stuff
- ph-oton-api - basic API stuff
- ph-oton-security - security elements (user, user groups, roles etc.)
- ph-oton-exchange - data exchange (import and export)
- ph-oton-connect - connectivity modules
- ph-oton-mgrs - basic managers (since 10.2.0; previously in ph-oton-core)
- ph-oton-core - basic web stuff
- ph-oton-uicore - basic web UI stuff
- ph-oton-icon - icon library. Deprecated for removal - the icon libraries moved to the separate project https://github.com/phax/ph-oton-icon (Maven group
com.helger.photon.icon) - ph-oton-tinymce4 - TinyMCE4 wrapper
- ph-oton-datatables- Datatables.net wrapper
- ph-oton-uictrls - misc web UI controls
- ph-oton-jetty - wrapper for Jetty to simply use as main
- ph-oton-jdbc - provides certain JDBC-based manager implementations (since 8.4.2)
- Java 17+ is required for building
- Application server requirements:
- At least Tomcat 10.1.x (JakartaEE 10)
- Jetty 12.x with AnnotationConfiguration enabled
Note: actual frontend bindings were moved to separate projects:
- Bootstrap v3: https://github.com/phax/ph-oton-bootstrap3
- Bootstrap v4: https://github.com/phax/ph-oton-bootstrap4
- Bootstrap v5: https://github.com/phax/ph-oton-bootstrap5 (work in progress)
Replace x.y.z with the effective version number.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.helger.photon</groupId>
<artifactId>ph-oton-parent-pom</artifactId>
<version>x.y.z</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>Note: prior to v8.2.5 the Maven groupId was com.helger.
v10.6.0 - 2026-09-06
- Added the package
com.helger.photon.core.paging(ph-oton-core) withITableColumn,SortColumnandTableColumnHelper. They describe the sortable and searchable columns of a domain object, and resolve the sort fields of anIPagingSpecas well as the global search text onto them. The methodsTableColumnHelper.getPage (...)andgetCount (...)are the in-memory implementation of a paged, sorted and filtered query - the reference behaviour every native data store implementation must comply to. The classes were extracted from phoss-smp and phoss-directory, that both had a copy of them. - Added the class
DataTablesOnDemandHelper(ph-oton-datatables) that wires anITableColumnbased data provider to a DataTables running in the server side modeON_DEMAND.registerAjaxFunction (...)registers the per page AJAX function in theGlobalAjaxInvoker,applyOnDemandMode (...)switches an existingDataTablesto that mode andcreateInitialOrder (...)maps the default order declared by the columns onto the column indices of the table. This requires that the sortable columns of the table are named after the ID of the respectiveITableColumnviaDTCol.setName (...). - Breaking API change: the class
LoginThrottlePerIP(ph-oton-security) is now a global singleton and must be retrieved viaLoginThrottlePerIP.getInstance ()instead of being instantiated. It was previously owned byAbstractLoginManageras an instance field, which made the effective scope of the failed login throttling depend on the life time the application happened to give its login manager - all known applications create it once inFilter.init (), but an application creating one per request silently lost all throttling, without an error, a log entry or a metric. There is now exactly one throttle per application, no matter how many login managers or login filters exist.AbstractLoginManager.getFailedLoginPerIP ()keeps its signature and now returns that singleton, so the usual configuration code likegetFailedLoginPerIP ().setTimeToLive (...)continues to work unchanged - it just applies application wide now. The internal cache is cleared when the global scope is destroyed. - Added the new method
LoginThrottlePerIP.getTrackedIPCount ()that returns the number of distinct IP addresses currently having failed logins on record. - Added ph-telemetry instrumentation for the REST API invocation in
APIInvoker(ph-oton-api): the spanphoton.api.invoke(kindSERVER), the counterphoton.api.invocationsand the histogramphoton.api.duration. The new classesCAPITelemetry(names) andAPIMetrics(instruments) are the public reference for dashboards, alerting rules and tests. The bounded metric dimension is the path template like/user/{id}- the concrete requested path is a span attribute only, because its cardinality is unbounded. An exception that was handled by anIAPIExceptionMapperstill marks the span as failed, even thoughinvoke (...)returns normally. - Added ph-telemetry instrumentation for the AJAX function invocation in
AjaxInvoker(ph-oton-ajax): the spanphoton.ajax.invoke(kindSERVER), the counterphoton.ajax.invocationsand the histogramphoton.ajax.duration. The new classesCAjaxTelemetry(names) andAjaxMetrics(instruments) are the public reference for dashboards, alerting rules and tests. - Behaviour change:
AjaxInvoker.invokeFunction (...)now stops the execution time measurement in afinallyblock, so that failing invocations are timed as well. As a consequence the statistics timerAjaxInvoker$timerand the registeredIAjaxLongRunningExecutionCallbacks are now also triggered for failing invocations - as it has always been the case inAPIInvoker. - Added ph-telemetry instrumentation for the UI page rendering path: the span
photon.page.request(kindSERVER), the counterphoton.page.requestsand the histogramphoton.page.durationinAbstractApplicationXServletHandler(ph-oton-core), plus the nested spanphoton.html.response(kindINTERNAL) and the histogramphoton.html.durationinPhotonHTMLHelper(ph-oton-app). The new classesCCoreTelemetryandPageRequestMetrics(ph-oton-core) as well asCAppTelemetryandHTMLResponseMetrics(ph-oton-app) are the public reference for dashboards, alerting rules and tests. Thephoton.html.responsespan covers the serialization of the HC tree only - the creation of the HC tree happens before the span is started, because it may end in a Post-Redirect-Get. - Added ph-telemetry instrumentation for the web page content creation in
AbstractWebPage.getContent (...)(ph-oton-uicore): the spanphoton.webpage.content(kindINTERNAL), the counterphoton.webpage.renderedand the histogramphoton.webpage.duration. The page ID is the bounded metric dimension, so this is the instrument that answers which screen of an application is slow - the display locale is a span attribute only. A page that is not displayed becauseisValidToDisplayPage (...)rejected it, is counted as well, with the attributephoton.webpage.displayedset tofalse. The new classesCUICoreTelemetry(names) andWebPageMetrics(instruments) are the public reference for dashboards, alerting rules and tests. - A
ForcedRedirectException(Post-Redirect-Get) does not mark the spansphoton.page.requestandphoton.webpage.contentas failed - it is a regular control flow, exactly asXServletHandlerToSimpleHandlertreats it. Instead the span eventsphoton.page.forcedredirectrespectivelyphoton.webpage.forcedredirectare added, and the request still counts as successful. - Added ph-telemetry instrumentation for the logins and logouts in
LoggedInUserManager(ph-oton-security): the countersphoton.security.login.success,photon.security.login.failedandphoton.security.logout, the observable gaugephoton.security.users.loggedinand the histogramphoton.security.session.duration. The only metric dimension is the name of theELoginResultconstant - no user ID, no login name and no IP address ever becomes a metric attribute. Every login failure is counted exactly once, includingUSER_NOT_EXISTING, which does not go through the internal failure choke point. The new classesCSecurityTelemetry(names) andLoginMetrics(instruments) are the public reference for dashboards, alerting rules and tests. - Added ph-telemetry instrumentation for the failed login throttling: the counter
photon.security.throttle.failedinLoginThrottlePerIP(ph-oton-security), the histogramphoton.security.throttle.delayinAbstractLoginManager(ph-oton-core), which records the artificial waiting time that was really applied, and the observable gaugephoton.security.throttle.trackedover the number of distinct IP addresses currently being throttled. No instrument carries any attribute - the remote IP address is unbounded and personal data. The new classLoginThrottleMetricsholds them all. - Added ph-telemetry instrumentation for the HTTP session and servlet context life cycle in
WebAppListener(ph-oton-core): the counterphoton.http.sessions.created, the up-down counterphoton.http.sessions.activeand the histogramsphoton.app.startup.durationandphoton.app.shutdown.duration. The two duration histograms reuse theStopWatchvalues that were previously only logged. The new classWebAppMetricsholds the instruments. - Added ph-telemetry instrumentation for the internal errors in
InternalErrorHandler(ph-oton-core): the counterphoton.internalerror.countby throwable class name, and the counterphoton.internalerror.mail.suppressedby reason. The latter makes a silently mis-configured internal error notification visible - previously a missing sender, receiver or SMTP configuration produced no notification and no signal that notifications are broken. The new classInternalErrorMetricsholds the instruments. - Added ph-telemetry instrumentation for the CSRF nonce checks in
WebPageCSRFHandler(ph-oton-uicore): the counterphoton.csrf.checkswith the attributesphoton.csrf.page.idandphoton.csrf.valid. Valid checks are counted as well, so that a failure rate can be computed. The nonce value itself never appears in telemetry. The new classCSRFMetricsholds the instrument. - Added ph-telemetry instrumentation for the asynchronous tasks of
PhotonWorkerPool(ph-oton-io): the spanphoton.worker.execute(kindINTERNAL), the countersphoton.worker.startedandphoton.worker.ended, the up-down counterphoton.worker.runningand the histogramphoton.worker.duration. The four public methodsrun,runThrowing,supplyandsupplyThrowingkeep their signatures but now share one private instrumented helper instead of four near-identical bodies. The caller supplied action name is a span attribute only and deliberately never a metric attribute - callers do interpolate unbounded values into it. The new classesCIOTelemetry(names) andPhotonWorkerPoolMetrics(instruments) are the public reference for dashboards, alerting rules and tests. - Added ph-telemetry instrumentation for the system migrations of
SystemMigrationHelper(ph-oton-mgrs): the spanphoton.migration.execute(kindINTERNAL), the counterphoton.migration.executedand the histogramphoton.migration.duration. A migration that reports a failure without throwing is distinguished from one that threw via the attributephoton.migration.failure.kind(none/business/technical), and both mark the span as failed. A migration that was already performed and is therefore skipped emits nothing at all. The new classesCMgrsTelemetry(names) andSystemMigrationMetrics(instruments) are the public reference;CLongRunningJobTelemetryis unchanged. - Added ph-telemetry instrumentation for the audit trail (ph-oton-audit): the counter
photon.audit.itemsinAbstractAuditor, so that all auditor implementations are covered by one increment, and the observable gaugephoton.audit.queue.lengthoverAsynchronousAuditor.getQueueLength (). Only the boundedEAuditActionTypeand the success flag are used as dimensions - never the audit action string, the audit arguments or the user ID. The gauge is closed inAsynchronousAuditor.stop (). The new classesCAuditTelemetry(names) andAuditMetrics(instruments) are the public reference for dashboards, alerting rules and tests. - Added ph-telemetry instrumentation for the SFTP operations of
ChannelSftpRunner(ph-oton-connect): the spanphoton.sftp.executeof kindCLIENT- these are the only genuine outbound network calls in ph-oton - plus the counterphoton.sftp.operationsand the histogramphoton.sftp.duration.JSchSessionFactoryadditionally emits the up-down counterphoton.sftp.sessions.open, which is the difference between the two existing statistics counters that a monitoring system cannot compute itself. The remote host is the only metric dimension; the operation display name is a span attribute only, and credentials, remote paths and user names never appear anywhere. The new classesCConnectTelemetry(names) andSftpMetrics(instruments) are the public reference for dashboards, alerting rules and tests. - Added ph-telemetry instrumentation for the server-side DataTables processing of
AjaxExecutorDataTables(ph-oton-datatables): the spanphoton.datatables.requestwith the child spansphoton.datatables.sortandphoton.datatables.filter, the histogramphoton.datatables.durationand the row count histogramsphoton.datatables.rows.totalandphoton.datatables.rows.filtered. Sorting and filtering are timed separately, because a table that is slow to filter needs a different fix from one that is slow to sort. Only whether a search was active is recorded, never what was searched - the search terms are user input and routinely contain personal data. The new classesCDataTablesTelemetry(names) andDataTablesMetrics(instruments) are the public reference for dashboards, alerting rules and tests. - Added ph-telemetry instrumentation for the web site resource cache and the resource bundling (ph-oton-app): the counters
photon.resource.cache.access(by hit and resource type),photon.resource.bundles.createdandphoton.resource.bundles.skipped. Counting hits and misses makes the hit ratio derivable and makes a forgottenWebSiteResourceCache.setCacheEnabled (false)in production visible. No resource path and no content hash is used as an attribute. No spans are emitted, because this is startup-time work that belongs to no request trace. The new classWebSiteResourceMetricsholds the instruments. - The modules ph-oton-io, ph-oton-app, ph-oton-audit, ph-oton-ajax, ph-oton-api, ph-oton-security, ph-oton-connect, ph-oton-core, ph-oton-uicore and ph-oton-datatables now have a direct dependency to
com.helger.telemetry:ph-telemetry(ph-oton-mgrs already had one). As before ph-oton never depends on an OpenTelemetry implementation - registering anITelemetryTracerSPI/ITelemetryMeterSPIis the business of the deploying application, and without one all telemetry degrades to cheap no-ops. All existingStatisticsManagerhandlers are unchanged - the telemetry is emitted alongside them.
v10.5.0 - 2026-09-04
- Added the new method
ISystemMessageManager.getSystemMessageData ()that returns all system message fields at once. It is now the only method an implementation needs to provide, and it allows a backend to read everything in a single step - the JDBC implementation previously issued oneSELECTper field. - Deprecated the methods
ISystemMessageManager.getLastUpdateDT (),getMessageType (),getSystemMessage ()andhasSystemMessage ()for removal. They are nowdefaultmethods that delegate togetSystemMessageData (). - Added the copy constructor
SystemMessageData (ISystemMessageData)and the methodSystemMessageData.getClone ()- the class now implementsICloneable. - Security fix:
IUserTokenManager.getUserTokenOfTokenString (String)now only considers access tokens that are valid now (IAccessToken.isValidNow ()) and that are not revoked. Previously an expired access token was still resolved. - Security fix:
UserTokenAuthCredentialValidatorSPInow also checks the state of the user owning the token and returnsELoginResult.USER_IS_DELETEDorELoginResult.USER_IS_DISABLEDaccordingly. Previously a token of a deleted or disabled user was still valid. - Security fix: a user that is deleted, disabled or whose password is changed, is now logged out immediately.
Previously he stayed logged in until his session timed out.
This is implemented in the new class
UserModificationLogoutCallbackthat is registered by default inPhotonSecurityManager. The internal password hash algorithm upgrade performed during login does not trigger a logout. - Security fix: when a session containing a logged in user is activated (e.g. after an application server restart with session persistence), the user state is now checked again. A user that was deleted or disabled in the meantime, or that is already logged in elsewhere, is no longer logged in again.
- Security fix:
LoggedInUserManager.loginUser (...)now checks whether the current session already has a user before an existing login of the user to be logged in is terminated. Previously a login failing withELoginResult.SESSION_ALREADY_HAS_USERcould log out that user's other session as a side effect. - Security fix:
LoggedInUserManager.loginUser (...)now spends the same amount of time on password hashing if no user could be resolved, so that the response time no longer discloses whether a login name exists. A failed login without a resolvable user is now also audited. - Added the new method
LoggedInUserManager.getInstanceIfInstantiated (). GlobalUserIDProvider.DEFAULT_SUPPLIERno longer throws an exception if no global scope is present.PhotonSecurityManager.FactoryXML.createAuditMgr (),AuditManagerJDBCandObjectLockManagernow useGlobalUserIDProviderinstead ofLoggedInUserManagerdirectly, so that alternative ways of authentication are correctly attributed.LoggedInUserManagerno longer executes theIUserLogoutCallbacks while holding the internal write lock during a login.- The mutable fields of
LoginInfoare nowvolatile, because aLoginInfois shared between all requests of a session. - Breaking API change: moved the class
LoginThrottlePerIPfrom packagecom.helger.photon.core.login(ph-oton-core) tocom.helger.photon.security.login(ph-oton-security), so that it can be reused by non-UI authentication. AuditorJDBCnow extendsAbstractAuditorinstead of implementingIAuditordirectly, so that the containedICurrentUserIDProviderand theIAuditActionStringProvidercan be changed after instantiation, as for all other auditors. The methodAuditorJDBC.createAuditItem (...)was therefore replaced byhandleAuditItem (IAuditItem).- Added the new class
RequestUserIDProvider(ph-oton-security) that remembers the ID of a user that was authenticated for the current request only - e.g. a REST API call using HTTP Basic Auth or a Bearer token - without creating an HTTP session. GlobalUserIDProvider.DEFAULT_SUPPLIERnow prefers the user ID of theRequestUserIDProviderover the session user ID of theLoggedInUserManager. Therefore stateless authenticated requests are now correctly attributed in the audit log and in the created business objects, without any additional configuration.IUser.USER_ID_MAX_LENGTHisGlobalIDFactory.STRING_ID_MAX_LENGTH(45) instead of 20 now, so that a user ID created by the default ID factory is no longer trimmed. Added the new Flyway scriptV3__user_id_max_length.sqlindocs/flyway/<dialect>/for that. It widens every column holding a user ID to 45 characters -audit.userid, thecreationuserid,lastmoduseridanddeleteuseridofsecrole,secusergroup,secuserandsecusertoken, as well assecuser.idandsecusertoken.userid, which were 20 characters and would overflow otherwise.long_running_job.idstays at 40 characters, because it holds a persistent ID fromGlobalIDFactoryand not a user ID. Only the length of the columns is changed, so existing data is preserved. Seedocs/README.mdfor details.- Breaking API change: the method
handleRequest (...)of the classesAbstractApplicationXServletHandler,AbstractObjectDeliveryHttpHandler,LogoutXServletHandler,PingPongXServletHandler,UserUploadXServletHandler(all ph-oton-core) andAjaxXServletHandler(ph-oton-ajax) now declaresthrows Exceptioninstead ofthrows IOException, ServletException. The overwritten methodIXServletSimpleHandler.handleRequest (...)always declaredthrows Exception- the listed classes just narrowed it, whileAPIXServletHandler,ErrorXServletHandlerandGoXServletHandlerdid not. Subclasses that overwrite one of these methods with a narrowerthrowsclause and invokesuper.handleRequest (...)need to be widened as well. This is the precondition for wrapping the request handling in acom.helger.telemetry.Telemetryspan, becauseTelemetry.withSpanVoidThrowing (...)can only propagate a single checked exception type.
v10.4.0 - 2026-08-30
- Requires at least ph-commons 12.4.0
- Updated to DataTables 3.0.2 + current plugins: AutoFill 3.0.0, Buttons 4.0.2, ColReorder 3.0.1, ColumnControl 2.0.1, DateTime 2.0.0, FixedColumns 6.0.0, FixedHeader 5.0.0, KeyTable 3.0.0, Responsive 4.0.2, RowGroup 2.0.0, RowReorder 2.0.0, Scroller 3.0.0, SearchBuilder 2.0.0 and Select 4.0.1.
Note that DataTables 3 no longer requires jQuery.
Breaking API change: removed the enum entries
EDataTablesJSPathProvider.DATATABLES_BUTTONS_COLVIS,DATATABLES_BUTTONS_HTML5andDATATABLES_BUTTONS_PRINT. Buttons 4 mergedbuttons.colVis.js,buttons.html5.jsandbuttons.print.jsintodataTables.buttons.js, so the separate files no longer exist - registeringEDataTablesJSPathProvider.DATATABLES_BUTTONSis now sufficient for all button types. Breaking API change: removed the enum entriesEDTPButtonsButtonType.COPY_FLASH,CSV_FLASH,EXCEL_FLASHandPDF_FLASH. The Flash based buttons were dropped in Buttons 2 already and resolved to nothing at runtime. Breaking API change: removed the constantsCDataTablesComponentVersion.SEARCH_PANESandSTATE_RESTOREincl. the respective resources. SearchPanes and StateRestore are not yet ported to DataTables 3 and their DataTables 2 versions are incompatible with it. Added the new enum entriesDATATABLES_COLUMN_CONTROL,DATATABLES_DATE_TIMEandDATATABLES_SEARCH_BUILDERtoEDataTablesCSSPathProviderandEDataTablesJSPathProvider. The resources were shipped before, but were not reachable from Java. Added the new enum entriesDATATABLES_COLUMN_CONTROL_BOOTSTRAP4andDATATABLES_SEARCH_BUILDER_BOOTSTRAP4toEDataTablesB4CSSPathProvider. Added entries for ColReorder, ColumnControl, FixedColumns, FixedHeader, KeyTable, RowGroup, RowReorder, Scroller, SearchBuilder and Select toEDataTablesB4JSPathProvider- DataTables 3 ships Bootstrap integration JS for these extensions for the first time, previously only the CSS existed. The identical entries were added to the two Bootstrap 5 counterparts. Note: the CardView and Editor extensions that the DataTables 3 download builder offers are deliberately not included, because they are licensed under "DataTables Plus" and must not be redistributed. Fixed the SearchHighlight plugin (DataTablesPluginSearchHighlight), that stopped working with DataTables 3. It read the initialisation options of a table fromsettings.oInit, which DataTables 3 renamed tosettings.init- the resultingTypeErroraborted theinit.dthandler, so no search term was ever highlighted. The bundleddataTables.searchHighlight.jsnow reads both and additionally ignores foreign "init" events that bubble up to the document. The bundled SearchHighlight plugin was updated from v1.0.1 to v1.1.0, which highlights the search term of a single column as well - in its own colour, using the new CSS classcolumn_highlightindataTables.searchHighlight.css. The global search term keeps usinghighlight. Breaking API change: removedDataTables.isJQueryUI (),setJQueryUI (boolean)and the constantDataTables.DEFAULT_JQUERY_UI. ThejQueryUIinitialisation option was dropped in DataTables 2 already, so the emitted option had no effect any more. - Reworked the CSP violation reporting in
CSPReportingXServletHandlerand added the new packagecom.helger.photon.core.csp. The handler now also accepts the Reporting API format (application/reports+json) next to the legacy format (application/csp-report) and normalizes both into the new classCSPReport, which additionally carries the User-Agent, the remote address, the receipt date time and the query parameters of the report URI. The latter are the only way to add server side context to a report, because the report body itself is created by the browser from a fixed set of fields. AddedICSPReportClassifierto separate actionable reports from the browser internal and browser extension noise that reaches every public reporting endpoint. The default implementation classifies a report as noise if its "source-file" has a scheme other thanhttporhttps; an absent "source-file" is deliberately not treated as a noise signal. The classification is part ofCSPReportand can be replaced per application viaCSPReportingXServletHandler.setClassifier (...). Noise is logged on the info level instead of the warning level. AddedCSPReportingEndpointthat ties the name of the CSPreport-todirective to the URI of theReporting-EndpointsHTTP response header and of the legacyreport-uridirective, so that the three cannot drift apart, andICSPReportingParameterProviderfor an application to contribute the query parameters of the report URI (default: none). Incompatible change: theCSPReportingXServletHandlerconstructor now takes aConsumer <? super CSPReport>instead of aConsumer <? super IJsonObject>. UseCSPReportingXServletHandler.asJsonConsumer (...)to keep an existing JSON based consumer. Incompatible change: a request with a content type other thanapplication/csp-reportorapplication/reports+jsonis now answered with HTTP 415 instead of being parsed as JSON. Behaviour change: the legacycsp-reportenvelope is now unwrapped, so a consumer receives the violation fields themselves. As a side effect the duplicate filtering by "blocked-uri" works for the first time - it read the field off the envelope before and therefore never matched. - Added the new class
SingleRunLockin packagecom.helger.photon.security.lock. It is a process wide "only one at a time" lock for expensive activities like long running jobs, that additionally remembers since when and by whom the running activity was started, so that a rejected caller can be told what is going on. - Added the new method
ILongRunningJobResultManager.deleteResult (String)incl. the implementations inLongRunningJobResultManager(XML backend) andLongRunningJobResultManagerJDBC(SQL backend). Previously long running job results could only be added and read, but never be removed - for results of typeFILEthat meant, that the referenced files piled up without any way to clean them up from the application. Note: deleting a job result does not delete a possibly referenced result file on disk. Custom implementations ofILongRunningJobResultManagerneed to implement the new method. - Integrated ph-telemetry 1.0.1 into
LongRunningJobManager- submoduleph-oton-mgrsnow depends oncom.helger.telemetry:ph-telemetry. Every long running job execution is now covered by the spanphoton.longrunningjob.execute(started inonStartJob, closed inonEndJob), and the instrumentsphoton.longrunningjob.started,photon.longrunningjob.ended,photon.longrunningjob.runningandphoton.longrunningjob.durationare emitted. Emission goes through the vendor neutral ph-telemetry facades only - without a registeredITelemetryTracerSPI/ITelemetryMeterSPIeverything degrades to cheap no-ops, so no observability backend is required. - Added the new classes
CLongRunningJobTelemetry(the constant span, metric and attribute names) andLongRunningJobMetrics(the metric instruments), so that applications can reference the literally same names in dashboards, alerting rules and tests - Breaking API change: removed the method
ILongRunningJob.getJobID (). A single job execution is identified by the globally unique ID thatLongRunningJobManager.onStartJobcreates and that is available asLongRunningJobData.getID (), so a separately provided job ID was redundant.LongRunningJobManager.onStartJobnow usesGlobalIDFactory.getNewPersistentStringID ()instead ofgetNewStringID ()- applications therefore need a registered persistent ID factory. - Added the new method
ILongRunningJob.getJobType ()together with the constantILongRunningJob.JOB_TYPE_MAX_LENGTH(100). The job type is a coarse grained category that groups multiple jobs together - likeimportorexport- and it can be used to filter the persisted job results. It is persisted and available via the new methodLongRunningJobData.getJobType (). For job results that were written before v10.4.0 it isnull, so they never match a job type filter. All implementations ofILongRunningJobneed to implement the new method. - Added the new methods
ILongRunningJobResultManager.forEachJobResult (String, Consumer)andILongRunningJobResultManager.getAllJobResults (String)to iterate respectively retrieve the job results of a single job type only. Passingnullas the job type means "no filtering".forEachJobResultinvokes the consumer per job result instead of building the full list first - the SQL backend deserializes row by row and therefore no longer needs to keep the whole table in memory.getAllJobResults ()andgetAllJobResults (String)are nowdefaultmethods based onforEachJobResult, so custom implementations ofILongRunningJobResultManageronly need to implement the newforEachJobResultmethod. - Breaking SQL schema change: the table
long_running_jobused byLongRunningJobResultManagerJDBCneeds the new nullable columnjob_type VARCHAR(100); an index on it is recommended. Existing rows keep an empty job type and therefore never match a job type filter. - Added the DDL of all tables used by
ph-oton-jdbcas Flyway migrations in the new folderdocs/flyway, for MySQL, PostgreSQL, DB2, SQL Server and Oracle. Seedocs/README.mdfor the usage, the origin of all column lengths and the known caveats. The scripts were cross checked against the production schema of phoss-SMP, which runs these managers on all five databases - hence the surrogate keyaudit.id,SMALLINTinstead ofBOOLEANon DB2 and the unbounded text types forsecuser.pwsalt/pwhash/firstname/lastname - Breaking API change: the public constructor
LongRunningJobData (String, IMultilingualText, String)was changed toLongRunningJobData (String, String, IMultilingualText, String)- the new second parameter is the job type - Added the new server side mode
EDataTablesServerSideMode.ON_DEMANDfor DataTables, that keeps nothing in the session, next to the existing (and still default) modePRERENDERED. In the modePRERENDEREDthe whole table is rendered up-front and stored in the session as aDataTablesServerData, so that paging, sorting and filtering can be applied on that snapshot. The memory consumption of that snapshot is proportional to the number of rows times the number of sessions, which does not scale to large tables. In the modeON_DEMANDevery AJAX request is instead answered by the application via the new interfaceIDataTablesOnDemandDataProvider, so only the rows of the currently requested page are ever rendered. Select the mode viaDataTables.setServerSideMode (...)and point the AJAX URL to the newAjaxExecutorDataTablesOnDemandinstead ofAjaxExecutorDataTables. The request is provided asDataTablesOnDemandRequest, which converts the DataTables parameters into a data store agnosticIPagingSpec(see ph-commons 12.4.0). The sort field name of a column is taken from thenameproperty of the column - seeDataTablesColumnDef.setName (String)- and falls back to the 0-based column index. Note that the field names and the search text come from the client and must be treated as untrusted input. The answer is provided asDataTablesOnDemandResult, consisting of the rows of the page plus the total and the filtered row count. - Added the new method
DataTablesServerDataRow.getAsJson (HCSpecialNodes)incl. the constantsDT_ROW_ID,DT_ROW_CLASS,DT_ROW_DATAandDT_ROW_ATTR.AjaxExecutorDataTablesuses it as well now, so that both server side modes create the identical JSON. - Incompatible change:
DTSSResponseDatauseslonginstead ofintfor the total and the filtered record count - this affects the constructor as well asgetTotalRecords ()andgetTotalDisplayRecords (). - Fixed the DataTables server side search to no longer create an empty first search term, if the entered search text starts with whitespace. An empty search term matches every row and therefore silently weakened the filter.
- Reduced the memory consumption of the DataTables server side mode
PRERENDERED(DataTablesServerData) by roughly half, without any behaviour change.DataTablesServerDataCellcached up to four representations of every single cell at the same time and never released any of them: the HC node tree, a full micro DOM copy of it, the HTML string and the plain text string. The micro DOM copy is now only an intermediate that is created on demand and discarded again, and the HC node tree is released as soon as both derived strings are present. Measured with 4.000 rows x 6 columns = 24.000 cells: the retained size of a snapshot dropped from 15.913 KiB to 9.588 KiB (-40%) when a single page of 25 rows is rendered, and from 19.123 KiB to 7.055 KiB (-63%) when all rows are rendered. The emitted HTML and the extracted text content are unchanged. The price is that the micro DOM is created twice for the cells of the currently displayed page - once for the text content and once for the HTML - which only affects the rows actually sent to the client. - Breaking API change: removed the methods
DataTablesServerDataCell.getContent ()andsetContent (IHCNodeList). The cell content is now released after rendering, so it can no longer be handed out. Both methods had no caller. Also removed thewriteObject/readObjectmethods ofDataTablesServerDataCell- the class does not implementSerializable, so they were never called. Note thatDataTablesServerDataimplementsIHasUIState(and thereforeSerializable), but neitherDataTablesServerDataRownorDataTablesServerDataCelldo, so a session containing a DataTables snapshot cannot be serialized anyway. DataTablesServerDataCell.getHTMLString ()is now annotated@NonNullinstead of@Nullable- it never returnednullbefore either.- Breaking API change: the constructor of
AbstractLongRunningJobRunnabletakes the job type instead of the job ID as its first parameter, and the methodgetJobID ()was removed from it - Breaking API change: the telemetry attribute constant
CLongRunningJobTelemetry.ATTR_JOB_ID(photon.job.id) was replaced byATTR_JOB_TYPE(photon.job.type), because the job type is now the low cardinality dimension the metrics are grouped by.ATTR_JOB_EXECUTION_ID(photon.job.execution.id) is unchanged. - All
CompletableFutureinstances created byPhotonWorkerPool(run,runThrowing,supplyandsupplyThrowing) now have anexceptionallyhandler that logs otherwise unnoticed asynchronous failures (e.g.Errors or rejected executions). Previously such exceptions were only contained in the returned future and were silently lost if the caller never evaluated it.
v10.3.1 - 2026-08-12
- Requires at least ph-web 11.4.3
- Updated to ph-masterdata 8.2.0
v10.3.0 - 2026-07-25
- Updated to Jetty 12.1.10
- Deprecated submodule
ph-oton-iconfor removal - the icon libraries moved to the separate project https://github.com/phax/ph-oton-icon (Maven groupcom.helger.photon.icon) - Added throttling on login, if unknown user names are used
v10.2.3 - 2026-05-16
- Updated to ph-commons 12.2.5
- Updated to ph-db 8.4.0
- Updated to Jetty 12.1.9
- Updated the default password hash algorithm to
PBKDF2_SHA256_100000_48 - Removed OSGI bundling
- Added class
GlobalUserIDProviderto provide an application wide current user ID. See #31 - Storing the new session scope in
LoginInfoafter session ID renewal on login - Added method
EHTMLEntity.htmlUnescape (String) - Added an additional constructor to
SftpSettings - SFTP connection settings now expose the connection timeout as
java.time.Duration getConnectionTimeout (). The new configuration key*.connectiontimeoutaccepts duration strings (e.g.10s,1m 30s) parsed viaIConfig.getAsConfigDuration. The previousint getConnectionTimeoutMillis ()API and*.connectiontimeoutmsconfiguration key remain available and are marked@Deprecated (forRemoval = true) - Deprecated old entries in
EStandardMetaElement
v10.2.2 - 2026-03-02
- Fixed a regression on login, that killed the web-scope management
v10.2.1 - 2026-03-02
- Extracted class
AbstractHCExtSelect - Change HTTP session ID after successful login. See #28 - thx @andreasa-winenet
- Added
ISftpSettingsHost.getKnownHostsPath () - Added class
SftpMaxParallelRunner
v10.2.0 - 2026-02-21
- Updated to Jetty 12.1.6
- Extracted new submodule
ph-oton-mgrs - Extracted new submodule
ph-oton-markdownfor Markdown handling - Extracted the interface
ISystemMigrationManagerand provided an SQL backend viaSystemMigrationManagerJDBC - Moved the class
SystemMigrationManagerinto packagecom.helger.photon.mgrs.sysmigration - Created new class
PhotonCMSManagerand moved access to theFavoriteManagerthere - Extracted interface
ISystemMessageManagerand provided an SQL backend viaSystemMessageManagerJDBC - Extracted interface
ILongRunningJobResultManagerand provided an SQL backend viaLongRunningJobResultManagerJDBC - Moved class
PhotonBasicManagerto the new submoduleph-oton-mgrs
v10.1.2 - 2026-01-10
- Added
IHCAttrContainer.setAria(Current|Disabled) - Updated to prism.js 1.3.0
- Updated to Datatables 2.3.5 + current plugins
- Added new internal class
PhotonInternalUnparsedJS - Fixed an error that
MarkdownProcessorcreated nested<td>elements - Made sure
UserGroupManagerJDBCworks with a single DB connection
v10.1.1 - 2025-12-14
- Updated to Jetty 12.1.5
- Extended API of
ConstantCSSPathProviderandConstantJSPathProvider - Fixed an error in
PageViewExternalHTMLCleanserthat may lead to paths with two consecutive slashes (//)
v10.1.0 - 2025-11-16
- Updated to Jetty 12.1.4
- Updated to ph-commons 12.1.0
- Using JSpecify annotations
- Made sure the
DefaultCSSClassProvideruses a thread-safe Map internally
v10.0.2 - 2025-10-23
- Updated to Jetty 12.1.3
- In case an application uses a custom server URL, the
StaticServerInfois now also using the path component from the provided URL instead of theServletContextpath
v10.0.1 - 2025-09-19
- Updated to Jetty 12.1.1
- Made
JettyStarterResourceFactorycustomizable - Created new class
PhotonResourceFactoryand using it as the default inJettyStarter - Added new class
SpringBootURIToURLConverter
v10.0.0 - 2025-08-25
- Requires Java 17 as the minimum version
- Updated to ph-commons 12.0.0
- Updated to Jetty 12.1.0
- Removed all code marked as deprecated for removal
- Made two constructors of
TenantandAccountingAreapublic - Moved the Bootstrap 4 binding to https://github.com/phax/ph-oton-bootstrap4
v9.3.2 - 2025-05-31
- Updated to Jetty 11.0.25
- Ensuring that BigDecimals with a negative scale are correctly formatted in JS. See #23 - thx @domids
- Cache tab on Administration page "Statistics" now shows the cache hit and miss percentage
- Read-only
AbstractHCControlno longer set the tabindex to-1
v9.3.1 - 2025-03-05
- Re-added class
ChartPaletteDefaultin packagecom.helger.photon.uictrls.chart - Made sure that dynamically loaded JS and CSS also get the
nonceattributes, if applicable
v9.3.0 - 2025-02-26
- Requires ph-web 10.4.0
- Updated to Bootstrap Icons 1.11.3
- Removed support for chart.js v1.x
- Updated list of global attributes in
IHCElement PhotonWorkerPoolnow has a silent mode option- The
InternalErrorBuildercan now deal with custom email settings. See #21 - The default administration page
Statisticsgot a "Download" buttons. See #22 - Moved classes
CSRFManagerandCSRFSessionManagerto submoduleph-oton-app - Class
CSRFManagernow creates nonces with 32 instead of 64 bytes and uses Base64 instead of Base16 encoding. - Added builders for
ConstantJSPathProviderandConstantCSSPathProvider - Added classes
JSLetandJSConstand usingletby default in JSforandfor inloops - Added class
JSParamand using it for function params and catch clauses (instead ofJSVar)
v9.2.9 - 2025-02-03
- Updated to ph-web 10.3.0
- Added reusable SFTP helper classes to package
com.helger.photon.connect.sftp AbstractLoginManagerno longer stores the user agent by default
v9.2.8 - 2025-01-21
- Added support for Google ReCaptcha v3
- Updated to Log4J 2.24.3
- Updated to DataTables 2.2.1
- Updated to ph-web 10.2.x
v9.2.7 - 2024-10-03
- Updated to Jetty 11.0.24
- Updated to Log4J 2.24.0
- Allowed
.cjsand.mjsas valid JavaScript file extensions typeattribute ofscriptelement was changed fromIMimeTypetoString- Improved consistency of
aria-label,aria-labelledby,aria-description,aria-describedby
v9.2.6 - 2024-08-09
- Updated to Jetty 11.0.22
- Fixed an error in DataTables max page calculation if length menu with only "all" is present
- Updated to DataTables 2.1.3
v9.2.5 - 2024-06-30
- Updated to Jetty 11.0.21
- Updated to DataTables 2.0.8 and updated translations
- Using
addAriaLabeledByinconnectFormControlWithLabel. See #18 - thx @NikovacsDev - API extensions for DataTables
aria-labelin pagination area
v9.2.4 - 2024-04-25
- Updated to DataTables 2.0.5 and latest plugin versions
- Chart.js V4 API improvements
v9.2.3 - 2024-04-18
- Updated to Log4J 2.23.1
- Updated to jQuery 3.7.1
- Updated to moment.js 2.30.1
- Added more charts.js v4 support
- Moved the Bootstrap 3 binding to https://github.com/phax/ph-oton-bootstrap3
v9.2.2 - 2024-03-28
- Updated to ph-commons 11.1.5
- Updated to Jetty 11.0.20
- Created Java 21 compatibility
- The default folder structure for internal errors was changed from
YYYY/MMtoYYYY/MM/DD - Added initial support for charts.js v4
v9.2.1 - 2023-09-26
- Updated to Jetty 11.0.16
- Fixed DateTime picker error in September for en-gb locale [Java 17]
v9.2.0 - 2023-08-20
- Extracted submodule
ph-oton-iofor dependency minimized inclusion
v9.1.4 - 2023-08-17
- Updated to DataTables 1.13.6 and latest plugin versions
- Updated to ph-web 10.1.5
- Avoid Exception on "Delete all" in failed mail page with Bootstrap4 UI
v9.1.3 - 2023-07-31
- Updated to ph-commons 11.1
v9.1.2 - 2023-07-24
- Updated to DataTables 1.13.5 and latest plugin versions
- Updated to jQuery 3.7.0
- Updated to ph-web 10.1.2
v9.1.1 - 2023-05-03
- Updated to Jetty 11.0.15
- Updated to jQuery 3.6.4
- Added new enumeration
EHCAutoCompleteand the possibility to use in the HC edits - Updated to DataTables 1.13.4 and latest plugin versions
v9.1.0 - 2023-02-24
- Using Servlet API 5.0.0 as the baseline: JakartaEE 9, Java 11+, Apache Tomcat v10.0.x, Jetty 11.x
- Switched all namespaces from
javax.servlettojakarta.servlet - Updated to Jetty 11.0.13
- Updated to Log2J 2.20.0
- Updated to Jetty 11.0.13
- Incorporated UserToken JDBC manager from v8.4.5
v9.0.1 - 2025-05-06 [backport]
- Updated to ph-commons 11.2.1
- Updated to ph-web 10.0.2
- Updated to Jetty 10.0.25
- Moved the Bootstrap 3 binding to https://github.com/phax/ph-oton-bootstrap3
v9.0.0 - 2023-02-14
- Using Java 11 as the baseline
- Updated to ph-commons 11
- Using Servlet API 4.0.1 as the baseline: JakartaEE 8, Java 11+, Apache Tomcat v9.x, Jetty 10.0.x
- Updated to Jetty 10.0.13
- Updated from
org.apache.logging.log4j:log4j-slf4j-impltoorg.apache.logging.log4j:log4j-slf4j2-implfor SLF4J 2.x
v8.4.5 - 2023-02-23
- Updated to Jetty 9.4.50
- Updated to Log2J 2.20.0
- Fixed default caching option for non GET requests
- Extended some API to adopt to the new UserToken requirements
- Added UserToken manager for JDBC
v8.4.4 - 2023-01-23
- Updated to jQuery 3.6.3
- Updated to DataTables 1.13.1 and latest plugin versions
- Added methods
setAriaRequired,addToAriaDescribedByandsetAriaInvalidto classIHCAttrContainer - Added method
IHCElement.withCustomAttrs - Made some general accessibility improvements
v8.4.3 - 2022-10-04
- Updated to Jetty 9.4.49
- Updated to Log2J 2.19.0
- Extended the interface
ISystemMessageRendererwith a display text - Renamed Java method
vartovariableinJS*classes - Fixed a potential NPE when trying to login with a non-existing user
- Fixed an issue in chartjs v1 CSS
- Changed chart.js package from
com.helger.photon.uictrls.charttocom.helger.photon.uictrls.chart.v1(backwards incompatible change)
v8.4.2 - 2022-09-07
- Updated to jQuery 3.6.1
- Updated to jQuery Migrate 3.4.0
- Updated to js-cookie v3.0.1
- Updated to js-storage v1.0.4
- Updated to Moment.js 2.29.4
- Updated PDFObject to v2.2.8
- Integrated ph-oton-jdbc submodule
- The default minimum password length changed from 6 to 8
- Deprecated
HCSWFObject
v8.4.1 - 2022-08-17
- Updated to Apache HttpClient 5.x
- Updated to Bootstrap 4.6.2
- Updated to Jetty 9.4.48
- Updated to Log2J 2.18.0
- Updated to ph-web 9.7.1
- Made class
DoNothingAuditorfinal - Added class
DoNothingAuditManager - Class
AbstractLoginManagernow has the possibility to specify a waiting time in case of a failed login - Deprecated classes
HCUniversalAnalyticsandHCGoogleAnalytics - Added support for Google Analytics V4
- Fixed an error in the MarkDown "safe mode" processing
- The
UITextFormatterand theBootstrapSystemMessageMarkDown renderer now use the "safe mode" as the default
v8.4.0 - 2022-04-04
- Updated to Jetty 9.4.46
- Updated chart.js from 1.0.2 to 1.1.1
- Updated to Bootstrap Icons 1.8.1
- Updated to DataTables 1.11.5 and latest plugin versions
- Updated the list of predefined
aria-attributes - Disabled the "directory listing" in the JettyStarter by default
- Disabled sending the server version and the
X-Powered-Byheader in JettyStarter by default - Added support for HTML element
<dialog> - Moved class
HCHgroupfrom package.deprecatedto.section - Moved class
HCMenufrom package.interactiveto.grouping - Added classes
HCMap,HCArea,EHCReferrerPolicy - Improved the overall HTML compliance according to the latest standard
- Dropped the specific HTML 5 annotations
HCMenunow takesHCLIchildren instead ofHCMenuItemchildren- Extended HTML accessibility API - thx to @Dafnik
- The default script mode for inline scripts was changed from
PLAIN_TEXT_WRAPPED_IN_COMMENTtoPLAIN_TEXT_NO_ESCAPE - Dropped support for Internet Explorer
v8.3.6 - 2022-01-04
- Updated Log2J to 2.17.1 - fixes CVE-2021-44832 - see https://logging.apache.org/log4j/2.x/security.html
- Made redirect URL after login customizable in
AbstractLoginManager
v8.3.5 - 2021-12-21
- Updated Log2J to 2.17.0 - fixes CVE-2021-45105 - see https://logging.apache.org/log4j/2.x/security.html
v8.3.4 - 2021-12-14
- Updated Log2J to 2.16.0 - fixes CVE-2021-45046 - see https://www.lunasec.io/docs/blog/log4j-zero-day/
- Corrected error in DataTables 1.11.3 integration that lead to CSP errors because too much was included
v8.3.3 - 2021-12-13
- Updated Log2J to 2.15.0 - fixes CVE-2021-44228 - see https://www.lunasec.io/docs/blog/log4j-zero-day/
- Updated DataTables to 1.11.3
v8.3.2 - 2021-11-24
- Updated to Bootstrap 4.6.1
- Updated to FineUploader 5.16.2
- Updated to Jetty 9.4.44
- Updated to ph-commons 10.1.4
- Made the
IAuditManagercustomizable in the PhotonSecurityManager - Added built-in Base64 encode and decode pages in the "Utilities" menu area
- Added class
CountingSftpProgressMonitor - Fixed some SonarQube issues - nothing serious
v8.3.1 - 2021-08-05
- Updated to Jetty 9.4.43
- Updated to ph-web 9.6.1
- Updated DataTables to 1.10.24
- Updated Bootstrap4 DateTimePicker to 5.39.0
- Updated FontAwesome to 5.15.4
- Added Bootstrap Icons 1.5.0 in ph-oton-icon
- Improved the way, Jetty dependencies are handled in the POM
BootstrapFormandBootstrapViewFormhandle splitting with negative values for certain grid elements- Made the
BootstrapFileUploadplaceholder label customizable - Added the possibility to add an ID on the
BootstrapNavof aBootstrapTabBox - Made class
BootstrapCardCollapsiblemore customizable - Added custom jQuery function
setReadOnly - Made the BootstrapDateTimePicker default icon customizable - #9
- Hiding environment variables that start with
SECRET_- see #10
v8.3.0 - 2021-03-22
- Updated to Apache commons-net 3.8.0
- Updated to Bootstrap 4.6.0
- Updated to Jetty 9.4.36
- Updated to jQuery 3.6.0
- Updated to ph-commons 10
- The name of the WebFragment
ph-oton-bootstrap3-stubchanged toph_oton_bootstrap4_stub - The name of the WebFragment
ph-oton-bootstrap4-stubchanged toph_oton_bootstrap3_stub - Extended
HCExtImgto correctly remove the servlet context if it is present - Added
BootstrapSelect2as a Bootstrap 4 theme of Select2 - Added new predefined page to change the log level at runtime (when using Log4J 2.x)
v8.2.9 - 2020-11-18
- Updated to Apache commons-net 3.7.2
- Updated to Bootstrap 4.5.3
- Updated to Jetty 9.4.34
- Updated to Log4j 2.14.0
- Improved handling of generic children for HTML tables
- Added new sanity method
BootstrapFormGroup.setLabelForCheckBox - Added CSS classes to
ELabelTypedirectly
v8.2.8 - 2020-09-17
- Updated to Jakarta JAXB 2.3.3
v8.2.7 - 2020-09-15
- Updated to ph-commons 9.4.8
- Improved long running job error handling
- Extended
ConfigurationFileManagerAPI - Using Popper UMD JS instead of the default distribution
v8.2.6 - 2020-08-20
- Updated animate.css to 4.1.0
- Updated to Apache commons-net 3.7
- Updated to autoNumeric 1.9.46
- Updated to Bootstrap 4.5.2
- Updated to CookieConsent 3.1.1
- Updated to Jetty 9.4.31
- Updated to popper.js 1.16.1-lts
- Updated to PrismJS 1.2.1
- Updated to Select2 4.0.13
- Removed autosize 1.8
- Improved customizability of
ExporterExcel - Fixed XML serialization of long running job data
- Reworked the PrismJS API and made the plugins more customizable
- Extended the Long running job API
- Added new class
PhotonWorkerPoolas a shared worker pool - Improved coding style thanks to Sonar
v8.2.5 - 2020-05-26
- Changed Maven groupId to
com.helger.photon - Updated to ph-web 9.3.0 (new Maven groupId)
v8.2.4 - 2020-05-25
- Updated to Bootstrap 4.5.0
- Updated to Jetty 9.4.29
- Updated to jQuery 3.5.1
- Updated to Log4j 2.13.3
- Updated to ph-commons 9.4.4
- Added new classes
SessionBackedRequestFieldBooleanandSessionBackedRequestFieldBooleanMultiValue - Added new configuration file syntax
JSON - Fixed an issue with the configuration file ID for the tab
- Extracted
IRoleManagerfromRoleManager - Extracted
IUserManagerfromUserManager - Extracted
IUserGroupManagerfromUserGroupManager - Made
PhotonUnifiedResponsechainable
v8.2.3 - 2020-02-19
- Fixed an error with the temporary directory name creation in
JettyStarter - Updated to ph-web 9.1.10
- Made
HttpClientSettingsconfigurable forReCaptchaServerSideValidator - Improved API to be more sensitive on encoded and decoded URI paths
- Added different date time representations to the default
InternalErrorMetadata - Added a new Admin page for performing a remote HTTP client call
- Extended traits interfaces
IHCTraitandIHCBootstrap4Trait
v8.2.2 - 2020-02-12
- Updated to Jetty 9.4.26
- Updated to Bootstrap 4.4.1
- Updated to log4j 2.13.0
- Made a
StubObjectconstructor public - Added a version number constant to access information at runtime
- Extended
JettyStarterto create multiple contexts - Added possibility to add "redirects" to the menu tree to allow to change the URLs of existing items without breaking existing bookmarks
- Extracted
IUserTokenManagerinterface - Added possibility to globally configure if internal errors should be send as email and/or saved as XML
- Unified the
WebPageActionHandlerAPI (backwards incompatible change) - Added traits interfaces
IHCTraitandIHCBootstrap4Traitas syntactic sugar - Added a new system page showing the content of the System Truststore (cacerts)
v8.2.1 - 2019-10-08
- Updated to log4j 2.12.1
- Updated to Jetty 9.4.21
- Updated to ph-web 9.1.4
- Updated to ph-commons 9.3.7
- Fixed the automatic module name of project
ph-oton-bootstrap4-pages BootstrapLoginHTMLProvidernow uses a form URL without the leading hostname- Updated to HandleBars 4.x
v8.2.0 - 2019-06-24
- Improved B4 InputGroup API for easier extension
- Updated to Jetty 9.4.19
- Improved Bootstrap 4 inline form UI creation
- Improved API path ambiguity resolution API (interface
IAPIPathAmbiguityResolveret. al.) - Added new API Interface
IAPIRegistryand letGlobalAPIInvokerimplement it - Clearly separate between
AjaxRegistryandAjaxInvokersimilar to new API API - Reworked module structure (created
ph-oton-app,ph-oton-audit,ph-oton-ajax,ph-oton-api, removedph-oton-basic) - Updated to jQuery 3.4.1
- Requires ph-commons 9.3.3
- Requires ph-web 9.1.2
CheckDiskUsableSpaceJobcan now be scheduled more than once for different paths- Application startup time is now displayed in the "System Properties" Administration page
- Added support for
loadingattribute inHCImgandHCIFrame - Started extending audit library to be more flexible and efficient - not used yet
v8.1.3 - 2019-02-18
- Updated to Bootstrap 4.3.1
- Updated to Bootstrap 3.4.1
- Bootstrap 4
BootstrapInputGroupAPI was reworked, so that the parent/child relationship holds true (incompatible) - Updated to log4j 2.11.2
ISimpleWebExecutionContextwas extended with theLoggedInUser- API API was extended to support only different MIME types
- Added an exception mapper to the API handling
- Requires ph-web 9.1.1
v8.1.2 - 2019-01-07
- Added B4 tooltips, Jumbotron and Modal dialog
- Added class
BootstrapPageRendererfor consistent page rendering - Added B4 collapsible Card
- Small improvement in rendering memory consumption and speed
- Extracted
IDataTablesLengthMenuinterface - Added B4 file upload control
- B4
BootstrapHelperbecameBootstrapFormHelper
v8.1.1 - 2018-11-25
- Fixed error in quoting of B3 user group management page
- Added special CSS Class to B4
BootstrapPageHeader - Changed B4
BootstrapDateTimePickerinitialization to correctly handle the default values - Extended
FavoriteManagerAPI - Updated to Jetty 9.4.14
- Changed B4
BootstrapDateTimePickerto not use currentDate by default - Requires ph-commons 9.2.0
v8.1.0 - 2018-10-25
- Extended the
FavoriteAPIs - Initial versions of the subproject
ph-oton-bootstrap4-uictrlsis available - Initial versions of the subproject
ph-oton-bootstrap4-pagesis available - Initial versions of the subproject
ph-oton-bootstrap4-demois available - Internal errors are stored in an additional "month" sub-directory
- Internal error storage paths are now customizable
- Added FontAwesome 5.2.0 free icons
- Improved state API slightly
- User group and role user interfaces were improved
- Updated to ph-web 9.0.5
- Updated to popper 1.14.4
- Added bulk export format "JSON (simple)" to have one without type information
- Added a new Bootstrap 4 DateTime picker UI ctrl
- Updated to Jetty 9.4.12
- Updated to TinyMCE 4.8.2
- Separated
HCPrismJSandTypeaheadEditin Bootstrap 3 and 4 versions - Dropped jQuery 1.x and 2.x files
- Updated DataTables to 1.10.18
- Added new base page "Port checker"
- Improved JettyStarter customizability
v8.0.2 - 2018-07-25
- Updated to Bootstrap 4.1.3
- Reworked meta element API so that
<meta charset="...">can be handled - Fixed OSGI ServiceProvider configuration
- Updated to Jetty 9.4.11
- Updated to ph-commons 9.1.3
- Updated to ph-web 9.0.2
- Extended
*HCSelectAPIs for multi values - The "Change log" page was removed
- Extended
JSSwitchAPI - Improved signatures of
AbstractJSBlock(binary incompatible) - Updated to ph-masterdata 6.1.0
v8.0.1 - 2018-04-18
- Updated to Jetty 9.4.9
- Updated to Bootstrap 4.0.0
- Bootstrap3Panel type can be changed
- Replaced some
StubjObjectwithIBusinessObject
v8.0.0 - 2018-01-05
- Updated to ph-commons 9.0.0
- Renamed 'Client' to 'Tenant' and moved to ph-tenancy in ph-masterdata project
- Updated to Bootstrap 4.0.0-beta
- Updated to TinyMCE 4.6.6
- Updated to Jetty 9.4.8
- Extracted ph-oton-atom
- Initial versions of the subproject
ph-oton-bootstrap4-stubis available
v7.1.2 - 2017-07-19
- Fixed an error with path handling of resource bundles when deployed as JAR
v7.1.1 - 2017-07-18
- Requires ph-commons 8.6.6
- ServletContext base path can now be any URL (instead of a mandatory File)
- Made
ServletStatusManagernon-static - Improved JS API (better Json support)
v7.1.0 - 2017-07-05
- Updated to ph-web 8.8.x
- Improved rendering speed through internal optimizations
- Updated to Bootstrap Datetime picker 2.4.4
- Updated to Jetty 9.4.6
CharacterEncodingFiltermore flexible- Updated to DataTables 1.10.15
v7.0.5 - 2017-03-30
- Updated to Jetty 9.4.3
- Updated to ph-schedule 3.6.1
- Improved SystemMessage API
v7.0.4 - 2017-03-09
- Updated to Jetty 9.4.2
- API extensions
- Updated to Apache commons-net 3.6
- Improved internal error handling API
- Internal changes in the ph-oton jobs.
- Removed some deprecated methods
v7.0.3 - 2017-01-10
- Integrated ph-html into ph-oton
- Binds to ph-commons 8.6.0
v7.0.2 - 2017-01-03
- Updated to Jetty 9.4.0
- Binds to ph-commons 8.5.6
- Binds to ph-web 8.7.0
- Improved default request parameter handling customizability
- New artefact
ph-oton-icon
v7.0.1 - 2016-11-14
- Improvements in request tracking logging
- Misc small improvements in different areas
- Updated to Jetty 9.3.14.v20161028
v7.0.0 - 2016-10-24
- Requires ph-commons 8.5.2
v7.0.0-beta3 - 2016-09-22
- Based on ph-commons 8.5.x
v7.0.0-beta2 - 2016-08-31
- Based on ph-commons 8.4.x
v7.0.0-beta1 - 2016-07-27
- Updated to Java 1.8
- Based on ph-commons 8.2.x
v6.2.0 - 2015-12-03
- extracted security module
- added support for app and user token management
- Last release for Java 1.7
v6.1.0 - 2015-10-02
- merged web actions and ajax functions
v6.0.0 - 2015-09-14
- first ph-oton release based on old webbasics and webctrls etc.
- requires ph-commons 6.x
My personal Coding Styleguide | It is appreciated if you star the GitHub project if you like it.