diff --git a/README.md b/README.md index 34ee3f0..4d8b5cb 100644 --- a/README.md +++ b/README.md @@ -5,24 +5,26 @@ ![GitHub release](https://img.shields.io/github/v/release/WhyWhatHow/jenv) ![Build Status](https://img.shields.io/github/actions/workflow/status/WhyWhatHow/jenv/release.yml?branch=main) -![Version](https://img.shields.io/badge/version-v0.6.7-blue) +![Version](https://img.shields.io/badge/version-v0.6.9-blue) -**🚀 [Quick Start with Landing Page](https://jenv-win.vercel.app)** - One-click downloads with automatic platform detection (Windows/Linux/macOS) • Multi-language support (EN/中文) • Updated bi-weekly +English | [中文](README_zh.md) | [日本語](README_jp.md) + +**🚀 [Quick Start with Landing Page](https://jenv-win.vercel.app)** - One-click downloads with automatic platform detection (Windows/Linux/macOS) • Multi-language support (EN/中文/日本語) • Updated bi-weekly -## Recent Updates (v0.6.7) +## Recent Updates (v0.6.9) ### 🚀 Performance Improvements -- **Ultra-fast JDK scanning**: Reduced scanning time from 3 seconds to 300ms (90% improvement) +- **Ultra-fast JDK scanning**: Reduced scanning time from 3 seconds to 300ms (90% improvement). [Read more about how we did it.](doc/PERFORMANCE.md) - **Concurrent processing**: Implemented Dispatcher-Worker model with goroutines - **Smart filtering**: Aggressive pre-filtering to skip unnecessary directories - **Progress tracking**: Real-time scanning progress and detailed statistics ### ✅ Cross-Platform Support +- **macOS support completed**: Full macOS compatibility (Intel/Apple Silicon) - **Linux support completed**: Full Linux compatibility with multi-shell support - **Windows optimization**: Enhanced path validation and compatibility fixes -- **macOS preparation**: Infrastructure ready for macOS support (coming soon) ### 🔧 Technical Enhancements - **Java path validation**: Improved Windows JDK detection reliability @@ -83,7 +85,7 @@ different Java versions, add new Java installations, and manage your Java enviro - **Cross-Platform Support** - Windows support (✅ Complete) - Linux support (✅ Complete) - - macOS support (🚧 In Progress) + - macOS support (✅ Complete) ## Project Structure ``` @@ -266,17 +268,15 @@ Without root privileges, jenv will automatically use user-level configuration in ### Why was this project created? -While Linux and macOS users have mature tools like `sdkman` and `jenv` for Java version management, Windows users have -limited options. The existing [Jenv-forWindows](https://github.com/FelixSelter/JEnv-for-Windows) solution, while -functional, faces performance issues on Windows 10 systems. +While Linux and macOS users have mature tools like `sdkman` and the original `jenv` (bash-based) for Java version management, Windows users have historically had limited, often sub-optimal options. Existing solutions like [JEnv-for-Windows](https://github.com/FelixSelter/JEnv-for-Windows) can face significant performance bottlenecks on modern Windows systems. -This project was born out of two motivations: +This project was born out of two key motivations: -1. To create a fast, efficient Java version manager specifically optimized for Windows -2. To explore AI-assisted development using tools like `cursor` and `Trae` while learning Go programming from scratch +1. **Bridging the Windows Gap**: To provide Windows developers with a robust, high-performance Java version manager that matches (or exceeds) the experience found on Unix-like systems. +2. **Performance First**: Achieving near-instant JDK scanning and switching, regardless of system size or complexity. +3. **Modern Engineering**: Exploring AI-assisted development (using `Cursor` and `Trae`) to build a modern, cross-platform tool in Go from the ground up. -The goal is to provide Windows developers with a robust, performant solution for managing multiple Java environments, -similar to what Linux and macOS users already enjoy. +Our goal is to be the **de facto Java environment manager for Windows**, while providing a seamless, unified experience for developers who work across Windows, Linux, and macOS. ### How it works? diff --git a/README_jp.md b/README_jp.md new file mode 100644 index 0000000..d2178d1 --- /dev/null +++ b/README_jp.md @@ -0,0 +1,175 @@ +
+JEnv ロゴ + +# Jenv: Java 環境マネージャー + +![GitHub release](https://img.shields.io/github/v/release/WhyWhatHow/jenv) +![Build Status](https://img.shields.io/github/actions/workflow/status/WhyWhatHow/jenv/release.yml?branch=main) +![Version](https://img.shields.io/badge/version-v0.6.9-blue) + +[English](README.md) | [中文](README_zh.md) | 日本語 + +**🚀 [ランディングページでクイックスタート](https://jenv-win.vercel.app)** - プラットフォーム自動検出(Windows/Linux/macOS)によるワンクリックダウンロード • 多言語対応(EN/中文/日本語) • 隔週更新 + +
+ +## 最新のアップデート (v0.6.9) + +### 🚀 パフォーマンスの向上 +- **超高速 JDK スキャン**: スキャン時間を 3 秒から 300ms に短縮(90% の向上)。[詳細はこちら](doc/PERFORMANCE_jp.md) +- **並列処理**: Goroutine を使用した Dispatcher-Worker モデルの実装 +- **スマートフィルタリング**: 不要なディレクトリをスキップする積極的なプリフィルタリング +- **進捗追跡**: リアルタイムのスキャン進捗と詳細な統計表示 + +### ✅ クロスプラットフォーム対応 +- **macOS 対応完了**: macOS(Intel/Apple Silicon)への完全対応 +- **Linux 対応完了**: マルチシェル対応による完全な Linux 互換性 +- **Windows 最適化**: パス検証の強化と互換性の修正 + +### 🔧 技術的な強化 +- **Java パス検証**: Windows での JDK 検出の信頼性を向上 +- **環境管理**: クロスプラットフォームでの環境変数処理を最適化 +- **設定のクリーンアップ**: 未使用オプションの削除とコードの保守性向上 + +--- + +## 概要 + +`Jenv` は、システム上の複数の Java バージョンを管理するためのコマンドラインツールです。異なる Java バージョンを簡単に切り替え、新しい Java インストールを追加し、Java 環境を効率的に管理できます。 + +## 特徴 + +### 効率的な Java バージョン管理 + +- **シンボリックリンクベースのアーキテクチャ** + - シンボリックリンクによる高速なバージョン切り替え + - 1 回限りのシステム PATH 設定 + - システム再起動後も変更が持続 + - すべてのコンソールウィンドウで即座に反映 + +### クロスプラットフォーム対応 + +- **Windows 対応** + - レジストリベースの環境変数管理(Windows 標準) + - 管理者権限の自動処理 + - 最小権限の原則による UAC プロンプトの最小化 + - Windows 10/11 システムでの優れたパフォーマンス + +- **Linux/Unix 対応** + - シェル設定ファイルベースの環境管理 + - ユーザーレベルおよびシステムレベルの設定オプション + - マルチシェル環境(bash, zsh, fish)のサポート + - インテリジェントな権限処理 + +- **macOS 対応** + - Intel および Apple Silicon アーキテクチャのサポート + - macOS 標準の JDK 配置場所に対応 + +### モダンな CLI 体験 + +- **直感的なインターフェース** + - わかりやすいコマンド構造 + - ライト/ダークテーマのサポート + - 読みやすさを向上させるカラー出力 + - 詳細なヘルプドキュメント + +### 高度な機能 + +- **スマートな JDK 管理** + - システム全体での JDK スキャン + - **超高速スキャン(3s → 300ms)**: Dispatcher-Worker モデルによる並列処理 + - エイリアスベースの JDK 管理 + - 現在の JDK ステータス追跡 + - 簡単な JDK 追加と削除 + +--- + +## インストール + +### リリースから +[Releases ページ](https://github.com/WhyWhatHow/jenv/releases)から最新リリースをダウンロードしてください。 + +### ソースからビルド + +#### 前提条件 + +- Go 1.21 以上 +- Git +- **Windows**: システムシンボリックリンクの作成に管理者権限が必要 + +#### ビルド手順 + +1. リポジトリをクローン: +```bash +git clone https://github.com/WhyWhatHow/jenv.git +cd jenv +``` + +2. プロジェクトをビルド: + +```bash +cd src +# Windows (PowerShell) +go build -o jenv.exe +# Linux/macOS +go build -o jenv +``` + +## 使い方 + +### 初期設定 + +```bash +# jenv の初期化(初回使用時に必要) +jenv init + +# jenv をシステム PATH に追加 +jenv add-to-path +``` + +### JDK の追加と削除 + +```bash +# エイリアス名で新しい JDK を追加 +jenv add jdk8 "C:\Program Files\Java\jdk1.8.0_291" +# JDK の削除 +jenv remove jdk8 +``` + +### JDK の切り替え + +```bash +# インストール済み JDK の一覧表示 +jenv list + +# 特定の JDK バージョンに切り替え +jenv use jdk8 + +# 現在使用中の JDK を表示 +jenv current +``` + +### システムのスキャン + +```bash +# インストール済み JDK を自動検出 +jenv scan c:\ # Windows +jenv scan /usr/lib/jvm # Linux +``` + +--- + +## なぜこのプロジェクトが作られたのか? + +Linux や macOS のユーザーには `sdkman` やオリジナルの `jenv`(bash ベース)のような成熟した Java バージョン管理ツールがありますが、Windows ユーザーにはこれまで最適とは言えない選択肢しかありませんでした。既存の [JEnv-for-Windows](https://github.com/FelixSelter/JEnv-for-Windows) などのソリューションは、現代の Windows システムでパフォーマンスのボトルネックに直面することがあります。 + +このプロジェクトは、主に 2 つの動機から生まれました: + +1. **Windows のギャップを埋める**: Windows 開発者に、Unix 系システムと同等(またはそれ以上)の堅牢で高性能な Java バージョン管理ツールを提供すること。 +2. **パフォーマンス重視**: システムの規模や複雑に関わらず、JDK のスキャンと切り替えをほぼ瞬時に行うこと。 + +私たちの目標は、**Windows における事実上の標準 Java 環境マネージャー**になると同時に、Windows、Linux、macOS をまたいで作業する開発者にシームレスで統一された体験を提供することです。 + +## ライセンス + +このプロジェクトは Apache License 2.0 の下でライセンスされています。詳細は [LICENSE](LICENSE) ファイルをご覧ください。 diff --git a/README_zh.md b/README_zh.md new file mode 100644 index 0000000..f21aee4 --- /dev/null +++ b/README_zh.md @@ -0,0 +1,181 @@ +
+JEnv Logo + +# Jenv: Java 版本管理工具 + +![GitHub release](https://img.shields.io/github/v/release/WhyWhatHow/jenv) +![Build Status](https://img.shields.io/github/actions/workflow/status/WhyWhatHow/jenv/release.yml?branch=main) +![Version](https://img.shields.io/badge/version-v0.6.9-blue) + +[English](README.md) | 中文 | [日本語](README_jp.md) + +**🚀 [通过落地页快速开始](https://jenv-win.vercel.app)** - 一键下载,自动检测平台(Windows/Linux/macOS) • 多语言支持(EN/中文/日本語) • 每两周更新 + +
+ +## 最新更新 (v0.6.9) + +### 🚀 性能提升 +- **超快 JDK 扫描**:扫描时间从 3 秒缩短至 300ms(提升 90%)。[阅读更多技术细节](doc/PERFORMANCE_zh.md) +- **并发处理**:使用 goroutines 实现了 Dispatcher-Worker 模型 +- **智能过滤**:积极的预过滤,跳过不必要的目录 +- **进度追踪**:实时扫描进度和详细统计数据 + +### ✅ 跨平台支持 +- **macOS 支持已完成**:完全兼容 macOS(Intel/Apple Silicon) +- **Linux 支持已完成**:支持多种 Shell 的完整 Linux 兼容性 +- **Windows 优化**:增强了路径验证和兼容性修复 + +### 🔧 技术增强 +- **Java 路径验证**:提高了 Windows JDK 检测的可靠性 +- **环境管理**:优化了跨平台环境变量处理 +- **配置清理**:移除了未使用选项,提高了代码可维护性 + +--- + +## 概述 + +`Jenv` 是一个用于管理系统中多个 Java 版本的命令行工具。它允许你轻松地在不同的 Java 版本之间切换,添加新的 Java 安装,并管理你的 Java 环境。 + +## 特性 + +### 高效的 Java 版本管理 + +- **基于符号链接的架构** + - 通过符号链接快速切换版本 + - 一次性系统 PATH 配置 + - 更改在系统重启后依然有效 + - 在所有控制台窗口中立即生效 + +### 跨平台支持 + +- **Windows 支持** + - 基于注册表的环境变量管理(Windows 标准) + - 自动处理管理员权限 + - 遵循最小权限原则,减少 UAC 提示 + - 在 Windows 10/11 系统上表现优异 + +- **Linux/Unix 支持** + - 基于 Shell 配置文件比例的环境管理 + - 提供用户级和系统级配置选项 + - 支持多种 Shell 环境(bash, zsh, fish) + - 智能权限处理 + +- **macOS 支持** + - 支持 Intel 和 Apple Silicon 架构 + - 支持 macOS 标准 JDK 路径 + +### 现代 CLI 体验 + +- **用户友好界面** + - 直观的命令结构 + - 支持浅色/深色主题 + - 彩色输出,提高可读性 + - 详细的帮助文档 + +### 高级功能 + +- **智能 JDK 管理** + - 全系统 JDK 扫描 + - **超快扫描性能(3s → 300ms)**,使用并发 Dispatcher-Worker 模型 + - 基于别名的 JDK 管理 + - 当前 JDK 状态追踪 + - 轻松添加和删除 JDK + +--- + +## 安装 + +### 从 Release 下载 +从 [Releases 页面](https://github.com/WhyWhatHow/jenv/releases)下载最新版本。 + +### 从源码构建 + +#### 前置条件 + +- Go 1.21 或更高版本 +- Git +- **Windows**:创建系统符号链接需要管理员权限 + +#### 构建步骤 + +1. 克隆仓库: +```bash +git clone https://github.com/WhyWhatHow/jenv.git +cd jenv +``` + +2. 构建项目: + +```bash +cd src +# Windows (PowerShell) +go build -o jenv.exe +# Linux/macOS +go build -o jenv +``` + +## 使用方法 + +### 首次设置 + +```bash +# 初始化 jenv(首次使用必选) +jenv init + +# 将 jenv 添加到系统 PATH +jenv add-to-path +``` + +### 添加和删除 JDK + +```bash +# 使用别名添加新的 JDK +jenv add jdk8 "C:\Program Files\Java\jdk1.8.0_291" +# 移除 JDK +jenv remove jdk8 +``` + +### 切换 JDK 版本 + +```bash +# 列出所有已安装的 JDK +jenv list + +# 切换到指定的 JDK 版本 +jenv use jdk8 + +# 显示当前使用的 JDK +jenv current +``` + +### 扫描系统中的 JDK +```bash +# 自动检测已安装的 JDK +jenv scan c:\ # Windows +jenv scan /usr/lib/jvm # Linux +``` + +--- + +## 为什么创建这个项目? + +虽然 Linux 和 macOS 拥有像 `sdkman` 和原始 `jenv`(基于 bash)这样成熟的 Java 版本管理工具,但 Windows 用户一直以来只有有限且往往不够理想的选择。现有的 [JEnv-for-Windows](https://github.com/FelixSelter/JEnv-for-Windows) 等方案在现代 Windows 系统上可能会遇到明显的性能瓶颈。 + +本项目诞生于两个核心动力: + +1. **弥补 Windows 空白**:为 Windows 开发者提供一个稳健、高性能且与 Unix 类系统体验一致(甚至更好)的 Java 版本管理工具。 +2. **性能优先**:无论系统大小或复杂度如何,都能实现近乎瞬时的 JDK 扫描和切换。 + +我们的目标是成为 **Windows 上事实上的标准 Java 环境管理器**,同时为跨 Windows、Linux 和 macOS 工作的开发者提供无缝、统一的体验。 + +## 致谢 + +- [cobra](https://github.com/spf13/cobra) - 强大的 Go CLI 框架 +- [jreleaser](https://jreleaser.org/) - 发布自动化工具 +- [nvm-windows](https://github.com/coreybutler/nvm-windows) - 启发了我们的符号链接方案 +- [Jenv-for-Windows](https://github.com/FelixSelter/JEnv-for-Windows) - Windows Java 版本管理的前辈项目 + +## 开源协议 + +本项目采用 Apache License 2.0 协议开源 - 详情请参阅 [LICENSE](LICENSE) 文件。 diff --git a/doc/PERFORMANCE.md b/doc/PERFORMANCE.md new file mode 100644 index 0000000..da19548 --- /dev/null +++ b/doc/PERFORMANCE.md @@ -0,0 +1,122 @@ +# High-Performance JDK Scanning in JEnv + +English | [中文](PERFORMANCE_zh.md) | [日本語](PERFORMANCE_jp.md) + +One of the standout features of JEnv is its ultra-fast JDK scanning capability. While traditional tools might take several seconds to traverse your file system looking for Java installations, JEnv typically completes this task in **under 300ms**—a 10x improvement over conventional methods. + +This document explains the technical architecture and optimizations that make this possible. + +## The Challenge + +Scanning a large disk (like `C:\` on Windows or `/` on Linux) for JDK installations is IO-intensive. A naive recursive search: +1. Visits every single directory. +2. Checks for the existence of `javac` or other JDK markers. +3. Operates sequentially, meaning it's blocked by disk latency at every step. + +On a typical developer machine with hundreds of thousands of files, this can easily take 3-5 seconds or more. + +## Architecture Overview + +JEnv uses a multi-layered approach to maximize performance, combining concurrent processing with intelligent search space reduction. + +```mermaid +graph TD + Start[jenv scan] --> Dispatcher[Dispatcher Goroutine] + Dispatcher --> TaskQueue[Task Queue] + + subgraph Workers[Worker Pool] + W1[Worker 1] + W2[Worker 2] + WN[Worker N] + end + + TaskQueue --> W1 + TaskQueue --> W2 + TaskQueue --> WN + + W1 --> Filter{Aggressive Filter} + Filter -- Skip --> Dispatcher + Filter -- Proceed --> Validate{Validate JDK} + + Validate -- Found --> Result[JDK Found] + Validate -- Not Found --> SubDirs[Extract Subdirs] + + Result --> Dispatcher + SubDirs --> Dispatcher + + Dispatcher --> FinalResult[Scan Result] +``` + +## The Solution: Dispatcher-Worker Model + +JEnv employs a sophisticated **Dispatcher-Worker** model implemented using Go's lightweight goroutines and channels. + +### 1. Concurrent Processing +Instead of scanning one directory at a time, JEnv spawns a pool of worker goroutines (typically `runtime.NumCPU() * 2`). + +- **Dispatcher**: Manages a queue of directories to be scanned. It feeds tasks to workers and collects results. It maintains state and decides when the scan is complete. +- **Workers**: Pick up a directory path, perform filtering and validation, and if subdirectories need scanning, they are passed back to the dispatcher. + +### 2. Scanning Sequence + +The interaction between components follows a highly parallelized pattern: + +```mermaid +sequenceDiagram + participant D as Dispatcher + participant Q as Task Queue + participant W as Workers + participant FS as File System + + D->>Q: Push initial directory + loop While tasks pending + Q->>W: Assign task + W->>W: Apply Filters + alt Path should be scanned + W->>FS: Read directory entries + FS-->>W: Entries + W->>W: Validate JDK (bin/javac) + alt JDK Found + W-->>D: Result: JDK info + else Subdirs found + W-->>D: Result: New tasks (subdirs) + D->>Q: Push subdirs to queue + end + else Path filtered + W-->>D: Task complete (skipped) + end + end + D->>D: Aggregate Results +``` + +### 3. Aggressive Pre-Filtering +The fastest way to scan a directory is to not scan it at all. JEnv uses a built-in "blacklist" of directories that are known *never* to contain JDKs. + +Before a worker even opens a directory, it checks its name against patterns like: +- **System Folders**: `Windows`, `System32`, `$Recycle.Bin`, `/proc`, `/dev`. +- **Package Managers**: `node_modules`, `.m2`, `gradle`, `pip`, `anaconda`. +- **IDE/Build Artifacts**: `.git`, `.idea`, `.vscode`, `target`, `build`, `dist`. +- **User Content**: `Downloads`, `Documents`, `Pictures`, `Videos`. + +By skipping these massive directory trees, JEnv avoids millions of unnecessary syscalls. + +### 4. Smart Depth Limiting +JDKs are rarely buried 20 levels deep. JEnv uses an intelligent depth-limiting strategy (typically capped at 5 levels from the search root) to prevent the scanner from "getting lost" in deep application data folders, while still finding JDKs in standard locations. + +### 5. Optimized Path Validation +JEnv doesn't just look for any file; it specifically validates the structure of a JDK (checking for `bin/javac`). This validation is highly optimized to minimize disk hits. + +## Performance Benchmark + +| Method | Time (Typical) | Improvement | +| :--- | :--- | :--- | +| Naive Recursive Scan | ~3,000ms | Baseline | +| **JEnv (Concurrent + Filtered)** | **<300ms** | **90% Faster** | + +## Summary + +By combining Go's powerful concurrency primitives with domain-specific knowledge about where JDKs are (and aren't) located, JEnv provides a near-instant experience for managing your Java environments. + +--- + +*Explore the implementation in [`src/internal/java/sdk.go`](../src/internal/java/sdk.go).* diff --git a/doc/PERFORMANCE_jp.md b/doc/PERFORMANCE_jp.md new file mode 100644 index 0000000..7cd81a9 --- /dev/null +++ b/doc/PERFORMANCE_jp.md @@ -0,0 +1,122 @@ +# JEnv における高性能 JDK スキャン + +[English](PERFORMANCE.md) | [中文](PERFORMANCE_zh.md) | 日本語 + +JEnv の際立った機能の 1 つは、その超高速な JDK スキャン機能です。従来のツールでは Java インストールを探すためにファイルシステムのトラバースに数秒かかることがありますが、JEnv は通常、このタスクを **300ms 未満**で完了します。これは従来のプロセスと比較して 10 倍の向上です。 + +このドキュメントでは、これを可能にしている技術的なアーキテクチャと最適化について説明します。 + +## 課題 + +JDK インストールを求めて大きなディスク(Windows の `C:\` や Linux の `/` など)をスキャンすることは、I/O 負荷の高い作业です。ナイーブな再帰的検索では以下の問題が発生します: +1. すべてのディレクトリを訪問する。 +2. `javac` やその他の JDK マーカーの存在を確認する。 +3. 逐次的に動作するため、各ステップでディスクレイテンシによってブロックされる。 + +数十万のファイルがある一般的な開発者のマシンでは、これに 3〜5 秒、あるいはそれ以上かかることが容易にあります。 + +## アーキテクチャの概要 + +JEnv は、並列処理とインテリジェントな検索空間の削減を組み合わせることで、パフォーマンスを最大化する多層的なアプローチを採用しています。 + +```mermaid +graph TD + Start[jenv scan] --> Dispatcher[Dispatcher Goroutine] + Dispatcher --> TaskQueue[Task Queue] + + subgraph Workers[ワーカープール] + W1[ワーカー 1] + W2[ワーカー 2] + WN[ワーカー N] + end + + TaskQueue --> W1 + TaskQueue --> W2 + TaskQueue --> WN + + W1 --> Filter{積極的フィルタ} + Filter -- スキップ --> Dispatcher + Filter -- 続行 --> Validate{JDK 検証} + + Validate -- 発見 --> Result[JDK 発見] + Validate -- 未発見 --> SubDirs[サブディレクトリ抽出] + + Result --> Dispatcher + SubDirs --> Dispatcher + + Dispatcher --> FinalResult[スキャン結果] +``` + +## 解決策:Dispatcher-Worker モデル + +JEnv は、Go の軽量な goroutine とチャネルを使用して実装された高度な **Dispatcher-Worker** モデルを採用しています。 + +### 1. 並列処理 +ディレクトリを 1 つずつスキャンする代わりに、JEnv はワーカー goroutine のプール(通常は `runtime.NumCPU() * 2`)を生成します。 + +- **Dispatcher(ディスパッチャー)**: スキャンするディレクトリのキューを管理します。ワーカーにタスクを供給し、結果を収集します。スキャン全体の状態を維持し、完了を判断します。 +- **Worker(ワーカー)**: ディレクトリパスを取得し、フィルタリングと検証を行います。さらにスキャンが必要なサブディレクトリがある場合は、ディスパッチャーに返します。 + +### 2. スキャンシーケンス + +コンポーネント間の相互作用は、高度に並列化されたパターンに従います: + +```mermaid +sequenceDiagram + participant D as Dispatcher + participant Q as Task Queue + participant W as Workers + participant FS as File System + + D->>Q: 初期ディレクトリをプッシュ + loop タスクが残っている間 + Q->>W: タスクを割り当て + W->>W: フィルタを適用 + alt パスをスキャンすべき場合 + W->>FS: ディレクトリエントリを読み込む + FS-->>W: エントリ + W->>W: JDK 検証 (bin/javac) + alt JDK 発見 + W-->>D: 結果: JDK 情報 + else サブディレクトリ発見 + W-->>D: 結果: 新規タスク (サブディレクトリ) + D->>Q: サブディレクトリをキューにプッシュ + end + else パスがフィルタリングされた場合 + W-->>D: タスク完了 (スキップ) + end + end + D->>D: 結果を集約 +``` + +### 3. 積極的なプリフィルタリング +ディレクトリをスキャンする最速の方法は、スキャンしないことです。JEnv は、JDK が含まれていないことがわかっているディレクトリの「ブラックリスト」を組み込んでいます。 + +ワーカーがディレクトリを開く前に、その名前を以下のパターンと照合します: +- **システムフォルダ**: `Windows`, `System32`, `$Recycle.Bin`, `/proc`, `/dev` など。 +- **パッケージマネージャー**: `node_modules`, `.m2`, `gradle`, `pip`, `anaconda` など。 +- **IDE/ビルドアーティファクト**: `.git`, `.idea`, `.vscode`, `target`, `build`, `dist` など。 +- **ユーザーコンテンツ**: `Downloads`, `Documents`, `Pictures`, `Videos` など。 + +これらの巨大なディレクトリツリーをスキップすることで、JEnv は何百万もの不要な系统コールを回避します。 + +### 4. スマートな深度制限 +JDK が 20 レベルも深い場所に配置されることは稀です。JEnv はインテリジェントな深度制限戦略(通常、検索ルートから 5 レベルに制限)を使用して、スキャナーが深いアプリケーションデータフォルダで「迷子」になるのを防ぎつつ、標準的な場所にある JDK を確実に見つけます。 + +### 5. 最適化されたパス検証 +JEnv は単にファイルを探すだけではありません。JDK の構造を具体的に検証します(`bin/javac` の存在確認など)。この検証は、ディスクへのアクセスを最小限に抑えるよう高度に最適化されています。 + +## パフォーマンスベンチマーク + +| 手法 | 時間(一般的) | 向上率 | +| :--- | :--- | :--- | +| ナイーブな再帰スキャン | ~3,000ms | 基準 | +| **JEnv(並列 + フィルタリング)** | **<300ms** | **90% 高速** | + +## まとめ + +Go の強力な並列処理プリミティブと、JDK がどこに存在し(どこに存在しないか)に関するドメイン固有の知識を組み合わせることで、JEnv は Java 環境を管理するためのほぼ瞬時の体験を提供します。 + +--- + +*実装の詳細については [`src/internal/java/sdk.go`](../src/internal/java/sdk.go) をご覧ください。* diff --git a/doc/PERFORMANCE_zh.md b/doc/PERFORMANCE_zh.md new file mode 100644 index 0000000..5be51c4 --- /dev/null +++ b/doc/PERFORMANCE_zh.md @@ -0,0 +1,124 @@ +# JEnv 高性能 JDK 扫描机制 + +[English](PERFORMANCE.md) | [日本語](PERFORMANCE_jp.md) | 中文 + +JEnv 的核心亮点之一是其极速的 JDK 扫描能力。传统工具在遍历文件系统寻找 Java 安装路径时可能需要几秒钟,而 JEnv 通常在 **300 毫秒内** 即可完成——比常规方法快了 10 倍。 + +本文将详细介绍实现这一性能的技术架构和优化策略。 + +## 挑战 + +在大型磁盘(如 Windows 的 `C:\` 或 Linux 的 `/`)中扫描 JDK 是一个 IO 密集型任务。传统的递归搜索存在以下问题: +1. 访问每一个目录。 +2. 检查 `javac` 或其他 JDK 标志文件的存在。 +3. 串行操作,意味着每一步都会被磁盘延迟阻塞。 + +在拥有数十万文件的典型开发机器上,这种方式轻松耗时 3-5 秒甚至更久。 + +## 架构概览 + +JEnv 采用多层优化方案,结合并发处理与智能搜索空间缩减,以实现性能最大化。 + +```mermaid +graph TD + Start[jenv scan] --> Dispatcher[Dispatcher Goroutine] + Dispatcher --> TaskQueue[Task Queue] + + subgraph Workers[Worker Pool] + W1[Worker 1] + W2[Worker 2] + WN[Worker N] + end + + TaskQueue --> W1 + TaskQueue --> W2 + TaskQueue --> WN + + W1 --> Filter{Aggressive Filter} + Filter -- Skip --> Dispatcher + Filter -- Proceed --> Validate{Validate JDK} + + Validate -- Found --> Result[JDK Found] + Validate -- Not Found --> SubDirs[Extract Subdirs] + + Result --> Dispatcher + SubDirs --> Dispatcher + + Dispatcher --> FinalResult[Scan Result] +``` + +## 核心方案:调度中心-工人模型 (Dispatcher-Worker) + +JEnv 利用 Go 语言轻量级的 Goroutines 和 Channels 实现了精妙的 **调度中心-工人** 并发模型。 + +### 1. 并发处理 +JEnv 不会一次只扫描一个目录,而是启动一个工作协程池(通常为 `runtime.NumCPU() * 2`)。 + +- **调度中心 (Dispatcher)**:管理待扫描目录的队列,向工人分配任务并收集结果。它维护扫描状态并决定何时结束扫描。 +- **工人 (Worker)**:获取目录路径,执行过滤和验证。如果发现子目录需要进一步扫描,则将其传回调度中心。 + +这种模式让 JEnv 能够充分利用磁盘 I/O 带宽,并利用多核 CPU 并行处理目录元数据。 + +### 2. 扫描时序 + +各组件之间的交互遵循高度并行化的模式: + +```mermaid +sequenceDiagram + participant D as Dispatcher + participant Q as Task Queue + participant W as Workers + participant FS as File System + + D->>Q: 推送初始目录 + loop 当仍有任务时 + Q->>W: 分配任务 + W->>W: 应用过滤规则 + alt 路径应被扫描 + W->>FS: 读取目录条目 + FS-->>W: 条目列表 + W->>W: 验证 JDK (bin/javac) + alt 发现 JDK + W-->>D: 返回结果: JDK 信息 + else 发现子目录 + W-->>D: 返回结果: 新任务 (子目录) + D->>Q: 将子目录推入队列 + end + else 路径被过滤 + W-->>D: 任务完成 (跳过) + end + end + D->>D: 汇总结果 +``` + +### 3. 积极的预过滤 (Aggressive Pre-Filtering) +扫描目录最快的方法就是“不扫描”。JEnv 内置了一份目录黑名单,这些目录被确定永远不会包含 JDK。 + +在工人打开目录之前,会先根据以下模式检查目录名: +- **系统目录**:`Windows`, `System32`, `$Recycle.Bin`, `/proc`, `/dev`。 +- **包管理器**:`node_modules`, `.m2`, `gradle`, `pip`, `anaconda`。 +- **IDE/编译产物**:`.git`, `.idea`, `.vscode`, `target`, `build`, `dist`。 +- **个人内容**:`Downloads`, `Documents`, `Pictures`, `Videos`。 + +通过跳过这些庞大的目录树,JEnv 避免了数百万次不必要的系统调用。 + +### 4. 智能深度限制 +JDK 很少会被埋在 20 层目录之下。JEnv 采用了智能深度限制策略(通常限制在搜索根目录下的 5 层内),防止扫描器在深层的应用数据文件夹中“迷失”,同时仍能准确找到标准路径下的 JDK。 + +### 5. 优化的路径验证 +JEnv 不仅仅寻找文件,还会专门验证 JDK 的目录结构(如检查 `bin/javac`)。这一验证过程经过高度优化,旨在将磁盘访问次数降至最低。 + +## 性能基准测试 + +| 方法 | 耗时 (典型值) | 提升 | +| :--- | :--- | :--- | +| 常规递归扫描 | ~3,000ms | 基准 | +| **JEnv (并发 + 过滤)** | **<300ms** | **快 90%** | + +## 总结 + +通过将 Go 语言强大的并发原语与对 JDK 存储路径的先验知识相结合,JEnv 为管理 Java 环境提供了近乎瞬时的流畅体验。 + +--- + +*查看实现代码:[`src/internal/java/sdk.go`](../src/internal/java/sdk.go)。* diff --git a/landing-page/js/app.js b/landing-page/js/app.js index b7935c0..3f44e2f 100644 --- a/landing-page/js/app.js +++ b/landing-page/js/app.js @@ -124,6 +124,14 @@ function getPlatformName(platform, lang) { 'linux-arm64': 'Linux ARM', 'macos-x64': 'macOS (Intel)', 'macos-arm64': 'macOS (Apple Silicon)' + }, + 'jp': { + 'windows-x64': 'Windows (x64)', + 'windows-arm64': 'Windows ARM', + 'linux-x64': 'Linux (x64)', + 'linux-arm64': 'Linux ARM', + 'macos-x64': 'macOS (Intel)', + 'macos-arm64': 'macOS (Apple Silicon)' } }; const key = getPlatformKey(platform); @@ -403,6 +411,19 @@ jenv add jdk11 "C:\\path\\to\\jdk" jenv use jdk11 # 5. 验证安装 +java -version`, + 'jp': `# 1. jenv.zip を任意のディレクトリに展開します +# 2. 管理者として PowerShell/CMD を実行します + +jenv init + +# 3. ダウンロードした JDK を追加します (実際のパスに変更してください) +jenv add jdk11 "C:\\path\\to\\jdk" + +# 4. JDK 11 に切り替えます +jenv use jdk11 + +# 5. インストールを確認します java -version` }, 'linux': { @@ -439,6 +460,23 @@ tar -xzf jenv-*.zip source ~/.bashrc # 或 ~/.zshrc # 6. 验证 +java -version`, + 'jp': `# 1. jenv.zip を展開します +tar -xzf jenv-*.zip + +# 2. 初期化します (sudo が必要な場合があります) +./jenv init + +# 3. JDK を追加します +./jenv add jdk11 /path/to/jdk + +# 4. バージョンを切り替えます +./jenv use jdk11 + +# 5. シェルを再読み込みします +source ~/.bashrc # または ~/.zshrc + +# 6. 確認します java -version` }, 'macos': { @@ -475,6 +513,23 @@ tar -xzf jenv-*.zip source ~/.zshrc # 或 ~/.bashrc # 6. 验证 +java -version`, + 'jp': `# 1. jenv.zip を展開します +tar -xzf jenv-*.zip + +# 2. 初期化します (sudo が必要な場合があります) +./jenv init + +# 3. JDK を追加します +./jenv add jdk11 /path/to/jdk + +# 4. バージョンを切り替えます +./jenv use jdk11 + +# 5. シェルを再読み込みします +source ~/.zshrc # または ~/.bashrc + +# 6. 確認します java -version` } }; @@ -542,6 +597,24 @@ function getFAQItems(lang) { question: '支持哪些操作系统?', answer: '

目前支持:

' } + ], + 'jp': [ + { + question: 'JDK とは何ですか?必要ですか?', + answer: '

JDK (Java Development Kit) は、Java 用のソフトウェア開発キットです。Java プログラムを作成して実行するために必要です。

' + }, + { + question: 'どの JDK バージョンを選べばよいですか?', + answer: '' + }, + { + question: 'なぜ JEnv が必要なのですか?', + answer: '

以下のことが必要な場合:

JEnv を使えば非常に簡単になります。

' + }, + { + question: 'どの OS がサポートされていますか?', + answer: '

現在:

' + } ] }; @@ -629,8 +702,19 @@ function setupEventListeners() { * Toggle language */ function toggleLanguage() { - currentLang = currentLang === 'en' ? 'zh' : 'en'; - document.getElementById('lang-toggle').textContent = currentLang === 'en' ? '中文' : 'EN'; + if (currentLang === 'en') { + currentLang = 'zh'; + } else if (currentLang === 'zh') { + currentLang = 'jp'; + } else { + currentLang = 'en'; + } + + const langBtn = document.getElementById('lang-toggle'); + if (currentLang === 'en') langBtn.textContent = '中文'; + else if (currentLang === 'zh') langBtn.textContent = '日本語'; + else if (currentLang === 'jp') langBtn.textContent = 'EN'; + document.documentElement.lang = currentLang; // Re-translate page @@ -675,6 +759,11 @@ async function init() { currentLang = getLanguage(); document.documentElement.lang = currentLang; + const langBtn = document.getElementById('lang-toggle'); + if (currentLang === 'en') langBtn.textContent = '中文'; + else if (currentLang === 'zh') langBtn.textContent = '日本語'; + else if (currentLang === 'jp') langBtn.textContent = 'EN'; + // Load data appData = await loadData(); diff --git a/landing-page/js/i18n.js b/landing-page/js/i18n.js index be9a628..8446e04 100644 --- a/landing-page/js/i18n.js +++ b/landing-page/js/i18n.js @@ -147,6 +147,79 @@ const translations = { // Mobile mobileTitle: '请使用桌面浏览器访问', mobileMessage: '为了获得最佳体验,请在桌面电脑上打开此页面' + }, + + jp: { + // Meta + title: 'JEnv - Java バージョン管理ツール', + description: '高速で簡単な Java バージョン管理ツール', + + // Hero + detected: '検出', + tagline: '3ステップでJDKをインストール、手動のパス設定は不要', + + // Typing effect messages + typingMessages: [ + '300ms で JDK バージョンを切り替え', + '手動の環境変数設定は不要', + 'Windows、macOS、Linux で動作' + ], + + // Quick Start + quickStart: '🚀 クイックスタート', + downloadJenv: 'JEnv をダウンロード', + downloadJdk: 'JDK をダウンロード', + install: 'インストールと使用', + version: 'バージョン', + downloading: '読み込み中...', + download: 'ダウンロード', + notAvailable: 'お使いのプラットフォームでは利用できません', + + // JDK Selection + selectDistribution: 'ディストリビューションを選択', + selectDistributions: 'ディストリビューションを選択', + selectVersion: 'バージョン', + selectVersions: 'バージョンを選択', + yourPlatform: 'プラットフォーム', + autoDetected: '自動検出', + jdkHint: '💡 迷っていますか?JDK 11 はほとんどの初心者に最適です', + distHint: '💡 1つ以上の JDK ディストリビューションを選択してください', + versionHint: '💡 推奨: JDK 11 または 17', + selected: '選択済み', + packages: 'パッケージ', + downloadSelected: '選択したものをダウンロード', + + // Features + whyJenv: 'なぜ JEnv なのか?', + feature1Title: '高速切り替え', + feature1Desc: 'シンボリックリンクベースで、300ms で JDK を切り替え', + feature2Title: 'Windows 最適化', + feature2Desc: 'Windows 10/11 に最適化、権限を自動処理', + feature3Title: 'モダンな体験', + feature3Desc: 'カラフルな CLI、ライト/ダークテーマをサポート', + + // FAQ + faqTitle: 'よくある質問', + + // Footer + footerText: 'JEnv - Java バージョン管理を簡単に', + license: 'ライセンス', + lastUpdated: '最終更新日', + + // Actions + copy: 'コピー', + copied: 'クリップボードにコピーされました', + copyFailed: 'コピーに失敗しました。手動でコピーしてください', + downloadStarted: 'ダウンロードを開始しました...', + + // Errors + loading: '読み込み中...', + errorLoading: 'データの読み込みに失敗しました。ページを更新してください', + initError: '初期化に失敗しました。ページを更新してください', + + // Mobile + mobileTitle: 'デスクトップブラウザを使用してください', + mobileMessage: '最適な体験のために、デスクトップコンピュータでこのページを開いてください' } }; @@ -162,7 +235,9 @@ function t(key, lang = 'en') { */ function getLanguage() { const browserLang = navigator.language || navigator.userLanguage; - return browserLang.toLowerCase().includes('zh') ? 'zh' : 'en'; + if (browserLang.toLowerCase().includes('zh')) return 'zh'; + if (browserLang.toLowerCase().includes('ja')) return 'jp'; + return 'en'; } // Export for use in other scripts