You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@struts.apache.org by "ASF GitHub Bot (Jira)" <ji...@apache.org> on 2026/07/01 10:20:00 UTC

[jira] [Work logged] (WW-5640) Add WebJars support to Struts core

     [ https://issues.apache.org/jira/browse/WW-5640?focusedWorklogId=1027815&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1027815 ]

ASF GitHub Bot logged work on WW-5640:
--------------------------------------

                Author: ASF GitHub Bot
            Created on: 01/Jul/26 10:19
            Start Date: 01/Jul/26 10:19
    Worklog Time Spent: 10m 
      Work Description: lukaszlenart opened a new pull request, #1765:
URL: https://github.com/apache/struts/pull/1765

   Fixes [WW-5640](https://issues.apache.org/jira/browse/WW-5640)
   
   ## What
   
   Adds first-class **WebJars** support to Struts core: client-side libraries packaged as WebJars (`org.webjars:*`, shipped under `META-INF/resources/webjars/<name>/<version>/…`) can be referenced by a **version-less logical path** and are resolved + served through Struts' existing static-content pipeline.
   
   Example: a template references `bootstrap/css/bootstrap.min.css` → Struts serves `META-INF/resources/webjars/bootstrap/5.3.8/css/bootstrap.min.css` at `<ctx>/static/webjars/bootstrap/5.3.8/css/bootstrap.min.css`.
   
   ## Why
   
   Plugins/apps currently vendor client-side assets on the classpath and re-commit them each release (the struts2-bootstrap plugin commits ~2000 files by hand). WebJars replace this with a dependency bump (auto-updatable via Renovate/Dependabot). First intended consumer: the struts2-bootstrap plugin (separate work).
   
   ## Changes
   
   - **Dependency:** `org.webjars:webjars-locator-lite:1.1.3` (MIT; single Apache-2.0 transitive dep `jspecify`; no Jackson/classpath-scanner — the variant Spring Framework 6.2 adopted).
   - **`WebJarUrlProvider`** (container bean, the public seam for plugins) + `DefaultWebJarUrlProvider` wrapping a singleton `WebJarVersionLocator`.
   - **Serving:** a `/webjars/**` branch in `DefaultStaticContentLoader` reusing existing caching; content-type map extended for fonts/svg/source-maps/json/ico.
   - **`<s:webjar>` tag + `<@s.webjar>` macro** emitting the resolved URL string (composes with `<s:script>`/`<s:link>`; supports `var`).
   - **Config:** `struts.webjars.enabled` (default `true`), `struts.webjars.allowlist` (comma-separated; empty = all).
   
   ## Security
   
   Resolution is hard-constrained to the `META-INF/resources/webjars/` root: per-segment `..`/`.` rejection and backslash rejection before the locator is called, a containment re-check on the resolved path, locator-backed resolution only (unknown webjar → null), plus the optional allowlist. Unresolved / disabled / traversal / allowlist-blocked all **fail closed** (404 when serving, empty output when building URLs). This is hardening for the new endpoint, not a fix to existing shipped behavior.
   
   ## Testing
   
   - Unit: resolution (known → versioned path/URL; unknown → empty), traversal rejection (both `resolveResourcePath` and `resolveUrl`), allowlist, disabled; content-type mappings.
   - Serving: 200 + content-type for a known asset, 404 for unknown, 404 when disabled (servlet-mocked).
   - Tag/macro: renders the resolved URL; `var` storage; empty on unresolved.
   - Full `core` suite: **2985 tests, 0 failures**. No regression to existing static-content serving.
   
   Backward compatible: `enabled=true` only activates the new `<staticContentPath>/webjars/**` namespace; existing `/static/**` serving is untouched.




Issue Time Tracking
-------------------

            Worklog Id:     (was: 1027815)
    Remaining Estimate: 0h
            Time Spent: 10m

> Add WebJars support to Struts core
> ----------------------------------
>
>                 Key: WW-5640
>                 URL: https://issues.apache.org/jira/browse/WW-5640
>             Project: Struts 2
>          Issue Type: New Feature
>          Components: Core
>            Reporter: Lukasz Lenart
>            Priority: Major
>             Fix For: 7.3.0
>
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> Add first-class WebJars support to Struts core so client-side libraries packaged as WebJars (shipped under {{META-INF/resources/webjars/<name>/<version>/…}}) can be referenced by a version-less logical path and served through Struts' existing static-content pipeline.
> Example: a template references bootstrap/css/bootstrap.min.css; Struts resolves and serves {{META-INF/resources/webjars/bootstrap/5.3.8/css/bootstrap.min.css}}.
> Today plugins and apps vendor client-side assets directly on the classpath and re-commit them on every upgrade (the struts2-bootstrap plugin commits ~2000 files by hand each release). WebJars replace this with a dependency bump (auto-updatable via Renovate/Dependabot).
> Scope (core only):
> - Add {{org.webjars:webjars-locator-lite}} (MIT; one Apache-2.0 transitive dep) for version resolution.
> - New {{WebJarUrlProvider}} container bean — the public, injectable seam for plugins.
> - Serve {{<staticContentPath>/webjars/**}} via a branch in {{DefaultStaticContentLoader}}, reusing existing caching; extend content-type coverage for fonts/svg/source-maps.
> - Thin {{<s:webjar>}} tag + {{<@s.webjar>}} macro emitting the resolved URL string.
> - New config: {{struts.webjars.enabled}} (default true), {{struts.webjars.allowlist}} (optional).
> - Security: constrain resolution to the webjars root, block .. traversal, fail closed (404 / no URL) on unresolved paths.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)