You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ofbiz.apache.org by "aldous liu (Jira)" <ji...@apache.org> on 2026/05/06 05:32:00 UTC
[jira] [Updated] (OFBIZ-13193) Circular dependency: base and common components have compile-time dependencies on webapp and widget
[ https://issues.apache.org/jira/browse/OFBIZ-13193?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
aldous liu updated OFBIZ-13193:
-------------------------------
Component/s: framework/base
framework/common
Affects Version/s: 24.09.05
Description:
Problem:
The framework foundation components (base, common, security) have hard compile-time imports from the higher-level UI components (webapp, widget). This violates the layered architecture principle and prevents building a headless / non-web / embedded OFBiz distribution where the web layer is excluded from the classpath.
Current dependency graph (ideal → actual):
Expected: Actual:
base base ──────────────> widget
├─ entity │ └──────────────> webapp
├─ security │
├─ common common ────────────> widget
├─ service │ └──────────────> webapp
│ │
├─ webapp (UI layer) security ──────────> webapp
└─ widget (UI layer)
Affected files with wrong-way imports:
framework/base should not depend on UI:
┌──────────────────────────────────────────────┬───────────────────────────────────────────────────────────────────┐
│ File │ Imports from removed component │
├──────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────┤
│ │ webapp.control.ConfigXMLReader, webapp.control.SameSiteFilter, │
│ base/.../util/UtilHttp.java │ webapp.event.FileUploadProgressListener, │
│ │ widget.renderer.VisualTheme │
├──────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────┤
│ base/.../util/UtilHtml.java │ widget.model.ThemeFactory │
├──────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────┤
│ base/.../util/template/FreeMarkerWorker.java │ widget.model.ModelWidget │
├──────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────┤
│ base/.../util/string/UelFunctions.java │ widget.renderer.ScreenRenderer │
└──────────────────────────────────────────────┴───────────────────────────────────────────────────────────────────┘
framework/common should not depend on UI:
┌────────────────────────────────────────────┬─────────────────────────────────────────────────────────────────────┐
│ File │ Imports from removed component │
├────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────┤
│ common/.../CommonEvents.java │ webapp.control.JWTManager, webapp.control.LoginWorker, │
│ │ widget.model.*, widget.renderer.VisualTheme │
├────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────┤
│ common/.../login/LoginServices.java │ webapp.control.LoginWorker │
├────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────┤
│ common/.../email/EmailServices.java │ webapp.view.ApacheFopWorker, widget.model.ThemeFactory, │
│ │ widget.renderer.* │
├────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────┤
│ common/.../email/NotificationServices.java │ webapp.OfbizUrlBuilder, webapp.WebAppUtil │
├────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────┤
│ common/.../UrlServletHelper.java │ webapp.WebAppUtil, webapp.website.WebSiteWorker │
├────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────┤
│ common/.../scripting/ContextHelper.java │ widget.renderer.VisualTheme │
└────────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────┘
framework/security should not depend on UI:
┌────────────────────────────────────────┬─────────────────────────────────────────────────────────────────────────┐
│ File │ Imports from removed component │
├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ security/.../SecurityUtil.java │ webapp.control.JWTManager │
├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ security/.../CsrfUtil.java │ webapp.control.ConfigXMLReader, webapp.control.RequestHandler, │
│ │ webapp.control.RequestHandlerException │
├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ security/.../CsrfDefenseStrategy.java │ webapp.control.RequestHandlerExceptionAllowExternalRequests │
├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ security/.../ICsrfDefenseStrategy.java │ webapp.control.RequestHandlerExceptionAllowExternalRequests │
└────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────────┘
Practical impact:
When a user wants to embed OFBiz as a headless backend (Entity Engine + Service Engine only, no Tomcat/Servlet
container), they cannot exclude webapp and widget from the Gradle build because:
1. activeComponents() in common.gradle reads component-load.xml to determine both the compile-time source set AND the
runtime component list
2. Removing webapp/widget from component-load.xml causes 15+ compilation errors across base, common, and security
Workaround:
Keep webapp and widget in component-load.xml (so they compile), but accept that unwanted entity tables (BrowserType,
PlatformType, Visit, ServerHit, WebSite, etc.) will be created in the database by the entity engine.
Suggested resolution:
1. Move VisualTheme, ThemeFactory, ModelWidget from widget to common (or create a theme-api interface in base)
2. Move JWTManager from webapp to security
3. Extract LoginWorker core auth logic to security — the webapp.control.LoginWorker should be an HTTP-specific wrapper
4. Remove CsrfUtil / CsrfDefenseStrategy from security — CSRF is a web-layer concern; these classes should live in
webapp
5. Remove UrlServletHelper from common — it's purely servlet-related
6. Refactor UtilHttp.java to extract the widget/webapp-specific parts into webapp
7. Refactor CommonEvents.java to extract widget/theme-related methods
This separation would allow headless deployments to exclude the webapp and widget components entirely at both compile
time and runtime.
OFBiz Version: 24.09.05 (trunk)
Component(s): framework/base, framework/common, framework/security, framework/webapp, framework/widget
Issue Type: Improvement (was: Bug)
Labels: Architecture (was: )
Summary: Circular dependency: base and common components have compile-time dependencies on webapp and widget (was: ofbizsetup)
Remaining Estimate: 672h
Original Estimate: 672h
> Circular dependency: base and common components have compile-time dependencies on webapp and widget
> -----------------------------------------------------------------------------------------------------
>
> Key: OFBIZ-13193
> URL: https://issues.apache.org/jira/browse/OFBIZ-13193
> Project: OFBiz
> Issue Type: Improvement
> Components: framework/base, framework/common
> Affects Versions: 24.09.05
> Reporter: aldous liu
> Priority: Major
> Labels: Architecture
> Original Estimate: 672h
> Remaining Estimate: 672h
>
> Problem:
> The framework foundation components (base, common, security) have hard compile-time imports from the higher-level UI components (webapp, widget). This violates the layered architecture principle and prevents building a headless / non-web / embedded OFBiz distribution where the web layer is excluded from the classpath.
> Current dependency graph (ideal → actual):
> Expected: Actual:
> base base ──────────────> widget
> ├─ entity │ └──────────────> webapp
> ├─ security │
> ├─ common common ────────────> widget
> ├─ service │ └──────────────> webapp
> │ │
> ├─ webapp (UI layer) security ──────────> webapp
> └─ widget (UI layer)
> Affected files with wrong-way imports:
> framework/base should not depend on UI:
> ┌──────────────────────────────────────────────┬───────────────────────────────────────────────────────────────────┐
> │ File │ Imports from removed component │
> ├──────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────┤
> │ │ webapp.control.ConfigXMLReader, webapp.control.SameSiteFilter, │
> │ base/.../util/UtilHttp.java │ webapp.event.FileUploadProgressListener, │
> │ │ widget.renderer.VisualTheme │
> ├──────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────┤
> │ base/.../util/UtilHtml.java │ widget.model.ThemeFactory │
> ├──────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────┤
> │ base/.../util/template/FreeMarkerWorker.java │ widget.model.ModelWidget │
> ├──────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────┤
> │ base/.../util/string/UelFunctions.java │ widget.renderer.ScreenRenderer │
> └──────────────────────────────────────────────┴───────────────────────────────────────────────────────────────────┘
> framework/common should not depend on UI:
> ┌────────────────────────────────────────────┬─────────────────────────────────────────────────────────────────────┐
> │ File │ Imports from removed component │
> ├────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────┤
> │ common/.../CommonEvents.java │ webapp.control.JWTManager, webapp.control.LoginWorker, │
> │ │ widget.model.*, widget.renderer.VisualTheme │
> ├────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────┤
> │ common/.../login/LoginServices.java │ webapp.control.LoginWorker │
> ├────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────┤
> │ common/.../email/EmailServices.java │ webapp.view.ApacheFopWorker, widget.model.ThemeFactory, │
> │ │ widget.renderer.* │
> ├────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────┤
> │ common/.../email/NotificationServices.java │ webapp.OfbizUrlBuilder, webapp.WebAppUtil │
> ├────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────┤
> │ common/.../UrlServletHelper.java │ webapp.WebAppUtil, webapp.website.WebSiteWorker │
> ├────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────┤
> │ common/.../scripting/ContextHelper.java │ widget.renderer.VisualTheme │
> └────────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────┘
> framework/security should not depend on UI:
> ┌────────────────────────────────────────┬─────────────────────────────────────────────────────────────────────────┐
> │ File │ Imports from removed component │
> ├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
> │ security/.../SecurityUtil.java │ webapp.control.JWTManager │
> ├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
> │ security/.../CsrfUtil.java │ webapp.control.ConfigXMLReader, webapp.control.RequestHandler, │
> │ │ webapp.control.RequestHandlerException │
> ├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
> │ security/.../CsrfDefenseStrategy.java │ webapp.control.RequestHandlerExceptionAllowExternalRequests │
> ├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
> │ security/.../ICsrfDefenseStrategy.java │ webapp.control.RequestHandlerExceptionAllowExternalRequests │
> └────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────────┘
> Practical impact:
> When a user wants to embed OFBiz as a headless backend (Entity Engine + Service Engine only, no Tomcat/Servlet
> container), they cannot exclude webapp and widget from the Gradle build because:
> 1. activeComponents() in common.gradle reads component-load.xml to determine both the compile-time source set AND the
> runtime component list
> 2. Removing webapp/widget from component-load.xml causes 15+ compilation errors across base, common, and security
> Workaround:
> Keep webapp and widget in component-load.xml (so they compile), but accept that unwanted entity tables (BrowserType,
> PlatformType, Visit, ServerHit, WebSite, etc.) will be created in the database by the entity engine.
> Suggested resolution:
> 1. Move VisualTheme, ThemeFactory, ModelWidget from widget to common (or create a theme-api interface in base)
> 2. Move JWTManager from webapp to security
> 3. Extract LoginWorker core auth logic to security — the webapp.control.LoginWorker should be an HTTP-specific wrapper
> 4. Remove CsrfUtil / CsrfDefenseStrategy from security — CSRF is a web-layer concern; these classes should live in
> webapp
> 5. Remove UrlServletHelper from common — it's purely servlet-related
> 6. Refactor UtilHttp.java to extract the widget/webapp-specific parts into webapp
> 7. Refactor CommonEvents.java to extract widget/theme-related methods
> This separation would allow headless deployments to exclude the webapp and widget components entirely at both compile
> time and runtime.
> OFBiz Version: 24.09.05 (trunk)
> Component(s): framework/base, framework/common, framework/security, framework/webapp, framework/widget
--
This message was sent by Atlassian Jira
(v8.20.10#820010)