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)