Dependency Deprecation Pattern
Experiment Overview
| Item | Details |
|---|---|
| Date | 2025-12-11 |
| Goal | Remove Java/Maven/FIJI/CLIJ2 dependencies from KINTSUGI while maintaining backward compatibility |
| Environment | Python 3.10+, cross-platform (Windows/Linux/macOS) |
| Status | Success |
Context
KINTSUGI originally depended on Java/Maven for PyImageJ and CLIJ2 GPU processing. This created installation friction and cross-platform issues. The goal was to replace these with pure Python implementations (CuPy/NumPy) while allowing legacy users to continue using Java if needed.
Verified Workflow
Step 1: Identify all dependency touchpoints
Search for all references to the dependency:
bash
# Search code grep -r "java\|Java\|FIJI\|fiji\|clij\|CLIJ\|maven\|Maven\|ImageJ\|imagej" src/ notebooks/ # Check configuration files grep -r "java\|openjdk\|maven" envs/ pyproject.toml
Files typically affected:
- •
pyproject.toml- optional dependencies - •
envs/*.yml- conda environment files - •
src/*/deps.py- dependency checker - •
docs/*.md- documentation - •Core modules using the dependency
Step 2: Update the core module with deprecation
python
# Example: edf.py - deprecating CLIJ2 backend
import warnings
from typing import Literal
BackendType = Literal["auto", "cupy", "numpy", "clij2"]
def _detect_backend(self, requested: BackendType) -> str:
"""Detect best available backend."""
if requested == "clij2":
warnings.warn(
"CLIJ2 backend is deprecated and will be removed in v2.0. "
"Use 'cupy' or 'numpy' instead.",
DeprecationWarning,
stacklevel=2
)
# Still allow it to work for now
if self._check_clij2_available():
return "clij2"
else:
warnings.warn("CLIJ2 not available, falling back to cupy")
requested = "auto"
if requested == "auto":
# NEW priority order: CuPy > NumPy (CLIJ2 excluded from auto)
if self._check_cupy_available():
return "cupy"
return "numpy"
return requested
Step 3: Update dependency checker
python
# deps.py - mark as deprecated but keep functional
def _check_java(self, verbose: bool):
"""Check Java installation.
.. deprecated::
Java/Maven dependencies are no longer required for core functionality.
Kept for backward compatibility with legacy CLIJ2 workflows.
"""
if verbose:
print("\n[Java/Maven] (DEPRECATED - no longer required)")
# Still check and report, but don't fail
try:
# ... existing check code ...
if verbose:
print(f" [OK] java v{version} (optional)")
except Exception as e:
if verbose:
print(f" [SKIP] java (optional, not required)")
Step 4: Update pyproject.toml
toml
[project.optional-dependencies]
# Keep the optional group but exclude from [full]
java = [
"JPype1>=1.5.0",
"scyjava>=1.0.0",
"pyimagej>=1.4.0",
]
# Remove java from full install
full = [
"kintsugi[gpu,viz,dl,analysis,bio]", # Note: java excluded
]
Step 5: Update environment files
yaml
# envs/env-*.yml - comment out with deprecation note # Java/ImageJ Integration (DEPRECATED - no longer required) # Uncomment if you need legacy CLIJ2 support: # - openjdk=11 # - maven # - jpype1
Step 6: Update documentation
Add deprecation notices to all relevant docs:
markdown
> **Note:** Java, Maven, and FIJI are no longer required. KINTSUGI now uses > pure Python implementations (CuPy/NumPy) for all processing including EDF.
For historical documents, add a header:
markdown
> **DEPRECATION NOTICE (2025):** This document is historical. Java/Maven/FIJI > dependencies have been removed. See `src/kintsugi/edf.py` for current implementation.
Failed Attempts (Critical)
| Attempt | Why it Failed | Lesson Learned |
|---|---|---|
| Removing code completely | Broke existing user workflows | Keep deprecated code functional |
| Silent removal | Users confused when code stopped working | Always emit deprecation warnings |
| Keeping in [full] install | Users still got Java install failures | Exclude from aggregate installs |
| No migration path | Users didn't know what to use instead | Document the replacement clearly |
Key Insights
- •Gradual deprecation: Mark as deprecated first, remove in next major version
- •Keep it working: Deprecated doesn't mean broken - users need time to migrate
- •Clear warnings: Use Python's
warnings.warn()withDeprecationWarning - •Document the alternative: Every deprecation notice should say what to use instead
- •Update ALL touchpoints: Code, configs, docs, environment files, README
- •Test both paths: Verify deprecated code still works AND new code works
Checklist for Dependency Deprecation
- • Search entire codebase for dependency references
- • Add deprecation warnings to code using the dependency
- • Update auto-detection to prefer new implementation
- • Keep optional dependency group but exclude from
[full] - • Comment out in environment files with explanation
- • Update installation documentation
- • Add deprecation notices to historical docs
- • Update CLAUDE.md / project documentation
- • Test deprecated path still works
- • Test new path works
- • Update changelog/release notes
References
- •Python deprecation warnings: https://docs.python.org/3/library/warnings.html
- •Semantic versioning for breaking changes: https://semver.org/
- •PEP 387 - Backwards Compatibility Policy: https://peps.python.org/pep-0387/