Skip to content

Conversation

@ramonskie
Copy link
Contributor

Migrate Cloud Foundry Java Buildpack to Ruby 3.4.7

Summary

Migrates the buildpack from Ruby 2.5.9 (released 2019, EOL 2021) to Ruby 3.4.7,
as ruby 2.x does not compile anymore on newer machines due to openssl incompatibility.
so local development was harder..

this is also addressing breaking changes in Psych 4.0+ YAML loading, REXML XML parsing,
adding required standard library gems, and modernizing the codebase for current Ruby best practices.

Changes Overview

28 files changed, 112 insertions(+), 104 deletions(-)

This PR includes 6 focused commits that systematically address Ruby 3.4 compatibility:

  1. Core Migration - Psych 4.0+ compatibility, standard library gems, modern syntax
  2. RuboCop Toolchain - Updated to support Ruby 3.4 parsing and linting
  3. Test Fixes - Resolved pre-existing test infrastructure bugs
  4. REXML Compatibility - Fixed XML parsing for Ruby 3.4 changes
  5. Platform Support - Updated Ubuntu support (bionic → jammy/noble)
  6. CI Infrastructure - Modernized Docker build environment

Key Technical Changes

1. Psych 4.0+ YAML Loading Security

Ruby 3.1+ ships with Psych 4.0, which changed YAML.load_file behavior for security:

Before (Ruby 2.x with Psych 3.x)

YAML.load_file(file)

After (Ruby 3.x with Psych 4.x)

YAML.load_file(file, permitted_classes: [Symbol], aliases: true)

Files updated:

• lib/java_buildpack/util/configuration_utils.rb
• lib/java_buildpack/repository/repository_index.rb
• lib/java_buildpack/framework/multi_buildpack.rb

2. Standard Library Gems

Ruby 3.4+ removed several gems from the default bundle. Added to Gemfile:

• base64 - Base64 encoding/decoding
• bigdecimal - Arbitrary precision decimals
• digest - Cryptographic hash functions
• set - Set data structure
• tmpdir - Temporary directory utilities

3. REXML XML Parsing

Ruby 3.4 changed REXML behavior:

• Empty XML documents now require explicit declaration creation
• Formatters strip trailing whitespace from text nodes

Fixed: lib/java_buildpack/container/tomcat/tomcat_geode_store.rb

4. RuboCop Toolchain Update

• Updated from 1.28.2 → 1.81.7 (Ruby 3.4 support)
• Added racc gem (required by parser)
• Updated rubocop-rspec 2.10.0 → 3.8.0
• Modernized .rubocop.yml configuration

5. Platform Support Update

Updated supported Ubuntu platforms for LTS lifecycle compliance:

• Removed: bionic (Ubuntu 18.04 - EOL April 2023)
• Kept: jammy (Ubuntu 22.04 LTS - support until 2027)
• Added: noble (Ubuntu 24.04 LTS - support until 2029)

Updated 10 documentation files with current platform examples.

6. CI Docker Environment

Updated ci/Dockerfile:

• Base image: ubuntu:bionic → ubuntu:jammy
• Ruby versions: Single version (3.4.7) instead of four (2.5.9, 2.7.6, 3.0.4, 3.1.3)
• Dependencies: Added libffi-dev, libyaml-dev for Ruby 3.4 compilation
• Python: python → python3 (Python 2 removed from jammy)
• SSL: libssl1.0-dev → libssl-dev (jammy compatibility)

Benefits: Faster builds, smaller images, aligned with buildpack requirements

Testing

All 972 non-integration tests passing ✅

Finished in 2.3 seconds
972 examples, 0 failures

Comprehensive test coverage includes:

• Core buildpack functionality (127 examples)
• Container specs (121 examples)
• Framework specs (200+ examples)
• JRE specs (39 examples)
• Utility specs (266 examples)
• Download cache specs (28 examples)

Docker CI image verified: Successfully builds with Ruby 3.4.7 (983MB)

Breaking Changes

None for buildpack users. This is an internal Ruby version update that maintains full backward compatibility for Java applications deployed with the buildpack.

For buildpack developers:

• Ruby 3.4.7+ now required for development
• RuboCop updated (may flag new style issues)
• CI environment updated to Ubuntu Jammy

Pre-existing Issues Fixed

During migration, discovered and fixed two unrelated bugs:

  1. JavaMemoryAssistant test - Missing test helper (bug from 2016)
  2. XML fixture files - Trailing whitespace inconsistencies

Update buildpack to use Ruby 3.4.7, addressing YAML loading changes in Psych 4.0+, adding required standard library gems, and modernizing Ruby syntax. All core utility specs (266 examples) pass successfully.

Key changes:
- Update YAML.load_file calls to use permitted_classes and aliases parameters
- Add Psych::DisallowedClass to exception handling
- Include base64, bigdecimal, digest, set, and tmpdir gems explicitly
- Adopt endless range syntax (tokens[1..] vs tokens[1..-1])
- Remove Ruby 2.x version-specific test code
- Modernize RuboCop configuration for rubocop-rspec
Add racc gem required by RuboCop parser in Ruby 3.4+, and update RuboCop
to version 1.60+ which recognizes Ruby 3.4 as a supported version.

Key changes:
- Add racc gem (required by parser gem in Ruby 3.4+)
- Update rubocop from 1.28.2 to 1.81.7 (adds Ruby 3.4 support)
- Update rubocop-rspec from 2.10.0 to 3.8.0
- Modernize .rubocop.yml configuration:
  - Change 'require' to 'plugins' (new preferred syntax)
  - Replace deprecated RSpec/FilePath with RSpec/SpecFilePathFormat and
    RSpec/SpecFilePathSuffix
  - Update RSpec/VerifiedDoubleReference config (obsolete EnforcedStyle)

This allows the buildpack's code quality tools to work with Ruby 3.4.7.
Add missing sub_configuration_context helper method to
java_memory_assistant_spec.rb. This test has been broken since it was
originally added in commit f2eee85 (Oct 26, 2016).

The test references sub_configuration_context() on line 59 but never
defined the helper method. Other specs (tomcat_spec.rb,
open_jdk_like_spec.rb, ibm_jre_spec.rb) each define their own local
helper following the same pattern.

This is a pre-existing bug unrelated to the Ruby 3.4 migration - the
test would have failed on any Ruby version (2.5, 2.6, 2.7, 3.0, 3.1, 3.4)
with NoMethodError for undefined method 'sub_configuration_context'.

Fixes #436 (original PR where test was introduced)
- Update TomcatGeodeStore to properly create XML documents with REXML
- Ruby 3.4's REXML no longer allows creating documents with just XML declaration
- Remove trailing whitespace from XML fixture files (REXML Pretty formatter now strips these)
- All 972 non-integration tests now passing
- Remove bionic (Ubuntu 18.04 EOL April 2023) from PLATFORMS
- Add noble (Ubuntu 24.04 LTS) to PLATFORMS for future support
- Keep jammy (Ubuntu 22.04 LTS) as primary supported platform
- Update all documentation references from bionic to jammy
- Aligns buildpack with Ubuntu LTS lifecycle and support dates

The platform detection at runtime already supported all Ubuntu codenames
via /etc/os-release parsing. This change only affects offline buildpack
packaging (which platforms to cache) and documentation examples.
- Update base image from ubuntu:bionic to ubuntu:jammy
- Remove old Ruby versions (2.5.9, 2.7.6, 3.0.4, 3.1.3)
- Install only Ruby 3.4.7 and set as global default
- Update libssl1.0-dev to libssl-dev for jammy compatibility
- Update python to python3 (Python 2 removed from jammy)
- Align bundler version with Gemfile.lock (2.3.12)

This streamlines CI builds and aligns with the Ruby 3.4.7 migration.
Reduces Docker image build time and size by removing 3 unused Ruby
versions.
@wayneeseguin
Copy link

@ramonskie I've been over this twice, nothing glaring stands out, so "LGTM".

@ramonskie ramonskie merged commit de6e09d into main Nov 21, 2025
1 check passed
@ramonskie ramonskie deleted the migrate-ruby-3.4.7 branch November 21, 2025 09:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants