Skip to content

wheels-legacy-adapter does NOT shim application.wirebox despite upgrade guide framing it as a soft landing #2627

@bpamiri

Description

@bpamiri

Describe the issue

The 3.x → 4.0 upgrade guide frames wheels-legacy-adapter as the soft-landing path for teams that "need 4.0 in production now and cannot schedule the migration work yet." A reader could reasonably infer the adapter shims the application.wirebox rename described in item 10 of the guide.

It does not. Reading wheels-dev/wheels-legacy-adapter@v1.0.0's LegacyAdapter.cfc, the shims are:

  • renderPage()renderView() (1.x/2.x era)
  • renderPageToString() (1.x/2.x era)
  • $legacySendEmail() (argument remap, 2.x era)
  • $legacyAppScopeGet(key) — an opt-in helper method, not a transparent shim of application.wirebox.foo access
  • Migration scanner + deprecation logger

There is no shim that makes either of the following work after the upgrade:

// Both of these break in 4.0, even with the legacy adapter installed:
injector = new wirebox.system.ioc.Injector("wheels.Wirebox");  // package gone from vendor/wheels/
svc = application.wirebox.getInstance("emailService");          // application.wirebox doesn't exist

Why this matters

Real-world 3.x apps that bootstrap WireBox directly in Application.cfc (the canonical 2.x bootstrap pattern still present in many old codebases — confirmed in titan, the app I'm upgrading) cannot use the adapter as a transparent soft-landing. They must rewrite the bootstrap up front. The blog skeleton's framing "install the adapter, ship the upgrade, modernize incrementally" overstates what the adapter does for these apps.

Expected behavior

Either:

  1. The adapter actually shims this rename. Register application.wirebox as an alias for application.wheelsdi at boot (and re-export the wirebox.system.ioc.Injector class path to point at wheels.Injector or a thin wrapper). Log a deprecation warning on use. This would make the adapter match what the rename docs imply.
  2. The docs explicitly call out the gap. Add a callout to the upgrade guide's item 10 saying the adapter does not cover this rename; apps that directly instantiate WireBox or read from application.wirebox must update those references regardless of whether the adapter is installed.

Reproducer

Take any 3.x app with this canonical CFWheels 2.x-era bootstrap (titan has it; many older apps do):

// public/Application.cfc
function onApplicationStart() {
    wirebox = new wirebox.system.ioc.Injector("wheels.Wirebox");
    application.wo = wirebox.getInstance("global");
    application.wirebox.getInstance(name = "wheels.events.onapplicationstart", initArguments = initArgs).$init(this);
}

Upgrade per the guide. Install wheels-legacy-adapter per the guide's recommendation. Run wheels start. Boot fails — wirebox package doesn't exist in vendor/wheels/.

Suggested fix

Adapter side is preferable — the docs make a promise the adapter doesn't keep. A LegacyAdapter.cfc that registers itself in onApplicationStart to:

  • Set application.wirebox = application.wheelsdi (alias)
  • Provide a Java class loader override or component-mapping shim that resolves wirebox.system.ioc.Injector to wheels.Injector (or a thin wrapper that delegates)
  • Log a deprecation warning on first use of either

…would let many real-world 3.x apps install the adapter and boot without touching Application.cfc. That's the actual "soft landing" the guide promises.

If a code shim isn't feasible, please at least amend the upgrade guide's item 10 to be explicit that this rename requires manual remediation regardless of adapter installation.

Environment

  • Wheels: 4.0.0-SNAPSHOT+1779
  • wheels-legacy-adapter: 1.0.0
  • Engine: Lucee 7.0.0.395, Java 21
  • Source app: PAI Industries titan storefront (3.0.0+40 → 4.0 upgrade testbed)

🤖 Filed by Claude Code while assisting with a 4.0 upgrade testbed

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions