Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Java Support for Lithe

> **Viva 预览版 Java 支持(1.1.2)**:清单已迁到当前契约 0,后端使用 Core
> **Viva 预览版 Java 支持(1.1.3)**:清单已迁到当前契约 0,后端使用 Core
> `65cf82343c5e315aae2e335b2e8f0217b703e89a` 中的 Rust SDK 0.4.0(尚无对应发布标签)。
> 本轮验证含第三方 JAR 依赖的普通 Maven 工程:JDT 补全、Maven 编译、main 运行和断点调试,包含变量读取、继续和退出。
> 需要同时包含 Lithe 客户端的动作注册解码、动作刷新与首次调试加载修复;未修改这些行为的旧 preview 不能直接使用本包。
Expand All @@ -24,7 +24,7 @@
> SDK. Maven and Gradle import settings come from the Maven and Gradle plugins through a function interface that
> Lithe Core relays between plugins.

1.1.2 面向包含主仓库 [#1884](https://github.com/1lck/Lithe-IDEA/pull/1884) 的配套 Viva preview(客户端修订 `607f00967d70a7017d49805183d0d2e6ffdf1c0d` 或更新版本)。API / 能力与传输版本以 `plugin.json`、`sdk.lock.json`
1.1.3 面向包含主仓库 [#1884](https://github.com/1lck/Lithe-IDEA/pull/1884) 的配套 Viva preview(客户端修订 `607f00967d70a7017d49805183d0d2e6ffdf1c0d` 或更新版本)。API / 能力与传输版本以 `plugin.json`、`sdk.lock.json`
和固定 Core 中的[插件资料](https://github.com/Lithe-IDEA/Lithe-core-rust/tree/65cf82343c5e315aae2e335b2e8f0217b703e89a/shared/plugins)为准。
`MIGRATION.md` 保留迁移历史,不能用其中旧宿主、旧 API 数字推断当前兼容性。

Expand Down
54 changes: 53 additions & 1 deletion backend/src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ use lithe_plugin_sdk::{
WorkspaceContext,
};
use serde_json::{json, Map};
use std::collections::{HashMap, HashSet};
use std::collections::{HashMap, HashSet, VecDeque};
use std::io::{BufRead, BufReader, Cursor, Write};
use std::net::TcpListener;
use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -223,6 +223,9 @@ pub struct RunSession {

const MAX_ACTION_QUERY_REFRESHES: u8 = 3;
const MAX_ACTION_PROGRESS_JOBS: usize = 128;
/// Remember recent terminal job IDs because SDK notification workers may run
/// out of wire order. This per-server history has the same bound as live jobs.
const MAX_COMPLETED_ACTION_PROGRESS_JOBS: usize = 128;

#[derive(Default)]
struct ActionQueryRetry {
Expand All @@ -233,6 +236,7 @@ struct ActionQueryRetry {
degraded: bool,
exhausted_reported: bool,
active_work: HashSet<String>,
completed_jobs: VecDeque<String>,
progress_limit: bool,
}

Expand All @@ -254,8 +258,17 @@ impl ActionQueryRetry {
}

fn progress(&mut self, id: &str, complete: bool) -> bool {
// Completion is terminal for a JDT job ID. A delayed worker must not
// resurrect it, nor may a duplicate end consume another retry budget.
if self.completed_jobs.iter().any(|completed| completed == id) {
return false;
}
if complete {
self.active_work.remove(id);
if self.completed_jobs.len() == MAX_COMPLETED_ACTION_PROGRESS_JOBS {
self.completed_jobs.pop_front();
}
self.completed_jobs.push_back(id.to_owned());
if self.active_work.is_empty() && !self.progress_limit {
return self.work_completed();
}
Expand Down Expand Up @@ -1520,6 +1533,45 @@ mod tests {
);
}

#[test]
fn completed_progress_cannot_be_resurrected_by_a_late_worker() {
let mut retry = ActionQueryRetry::default();
// SDK notification workers can acquire the lock in a different order
// from the wire: an earlier running update may follow completion.
assert!(!retry.progress("build", true));
assert!(!retry.progress("build", false));
assert!(!retry.progress("index", false));
assert_eq!(retry.defer(retry.completed_work), (true, false));
assert!(
retry.progress("index", true),
"late build update must not block recovery"
);
let completed = retry.completed_work;
assert!(!retry.progress("index", true));
assert_eq!(
retry.completed_work, completed,
"duplicate completion is not new work"
);
}

#[test]
fn terminal_progress_history_is_bounded_and_keeps_recent_jobs() {
let mut retry = ActionQueryRetry::default();
for id in 0..MAX_COMPLETED_ACTION_PROGRESS_JOBS * 2 {
retry.progress(&id.to_string(), true);
}
assert_eq!(
retry.completed_jobs.len(),
MAX_COMPLETED_ACTION_PROGRESS_JOBS
);
let recent = (MAX_COMPLETED_ACTION_PROGRESS_JOBS * 2 - 1).to_string();
let completed = retry.completed_work;
retry.progress(&recent, false);
retry.progress(&recent, true);
assert!(retry.active_work.is_empty());
assert_eq!(retry.completed_work, completed);
}

#[test]
fn progress_bookkeeping_is_bounded_and_malformed_events_do_not_recover() {
let mut retry = ActionQueryRetry::default();
Expand Down
66 changes: 66 additions & 0 deletions docs/releases/v1.1.3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
## 中文

Java Support 1.1.3 为配套 Viva 预览版提供 Java 项目支持。本版本是预发布,插件包不带发布者签名。

### 下载与安装

下载本页对应系统的 ZIP:macOS Apple Silicon(`darwin-arm64`)、macOS Intel(`darwin-x64`)或 Windows x64(`windows-x64`)。在兼容 Viva 客户端的插件设置中选择从文件安装 ZIP。

需要包含 [Lithe #1884](https://github.com/1lck/Lithe-IDEA/pull/1884) 的客户端(修订 `607f00967d70a7017d49805183d0d2e6ffdf1c0d` 或更新版本)及 Core #29。旧版 macOS Lithe 和未包含这些修复的 Viva preview 不受支持。插件使用契约/API/能力版本 0;语言服务器使用随包 Temurin 21,项目运行仍使用用户选择的 JDK。

Maven 项目配合 Maven 0.0.1;Gradle 项目配合 Gradle 1.0.0。构建工具由用户安装或由项目 Wrapper 提供。

### 更新

- 修复并发处理索引进度时,晚到的旧更新重新激活已完成任务、导致运行动作不恢复的问题;终态历史有界且不增加后台轮询。
- 补齐自身 LICENSE/NOTICE 与 Rust 构建依赖的许可和哈希清单,缺失时阻止打包。

- 跑通普通 Maven、Gradle 和普通 Java 目录的补全、编译、运行及断点调试,Java 8 项目保留正确的编译目标。
- Windows 后端静态链接编译器运行库,发布检查拒绝额外的 VC++/MinGW 运行库依赖。
- 修复 Windows 可执行路径、中文/UNC 文件 URI、Lombok 加载及过长 classpath;退出后清理临时 classpath JAR。
- 冷索引暂时无法返回运行动作时,在索引任务完成后有界恢复,不增加后台轮询。
- 已在 macOS 与 Windows 无头验证断点变量、继续/停止、编译错误阻止运行旧 class、暂停时关闭及插件安装目录只读。

### 兼容性与已知限制

- 二进制依赖类跳转尚未接通:语言服务器能返回 `jdt:` 目标,但插件未注册对应内容提供者,Viva 无法打开类内容;不保证反编译视图或类间继续跳转。
- `.jsp` 当前按 HTML 打开,没有 Java 语言服务接管,JSP 内的 Java 补全与跳转不受支持。

尚未完整验收原生窗口、全部日志/取消路径、JUnit/TestNG 行内运行器和 Spring/MyBatis。JSP HTTP/Servlet 调试通过不代表 JSP 源码补全或 JSP 断点;Ant 源码布局不代表执行 Ant target。Java 5/7 源码级别、长 module-path、JavaCC 生成模型、多版本 JAR 和部分旧泛型项目仍有限制,详见 README 与主仓库 #1881–1883。

实测 JDT 内存与补全延迟没有显著改善,本版本不宣称整体性能提升。Windows 的真实工作流在 ARM Windows 上使用 x64 工具验证,其耗时不代表原生 AMD64 性能。

---

## English

Java Support 1.1.3 targets the matching Viva preview. This is a prerelease with unsigned plugin archives.

### Download and installation

Choose the ZIP for macOS Apple Silicon (`darwin-arm64`), macOS Intel (`darwin-x64`), or Windows x64 (`windows-x64`), then install it from a file in the compatible Viva client's plugin settings.

The client must include [Lithe #1884](https://github.com/1lck/Lithe-IDEA/pull/1884), revision `607f00967d70a7017d49805183d0d2e6ffdf1c0d` or newer, and Core #29. Legacy macOS Lithe and earlier Viva previews are unsupported. Contract, API and capability versions are 0. Bundled Temurin 21 runs the language server; project execution uses the selected project JDK.

Use Maven 0.0.1 for Maven projects and Gradle 1.0.0 for Gradle projects. Supply the build tool yourself or through the project's wrapper.

### Changes

- Prevent late progress updates from resurrecting completed indexing jobs and blocking run-action recovery; terminal history is bounded without polling.
- Include project and Rust dependency notices with a hash manifest; missing notices stop packaging.

- Validated completion, compilation, execution and breakpoint debugging for ordinary Maven, Gradle and plain Java projects, preserving Java 8 compilation targets.
- The Windows backend statically links compiler runtimes; release checks reject extra VC++/MinGW runtime DLL dependencies.
- Fixed Windows executable paths, Unicode/UNC file URIs, Lombok loading and long classpaths; temporary classpath JARs are removed after execution.
- Recover run actions after cold-index jobs finish, with bounded retries and no background polling.
- Headless macOS and Windows workflows cover breakpoint locals, continue/stop, refusal to run stale classes after compilation errors, closing paused sessions and read-only installed packages.

### Compatibility and known limitations

- Navigation into binary dependency classes is not wired up: the language server returns `jdt:` targets, but no matching content provider is registered, so Viva cannot open them. Decompiled views and further navigation between classes are not supported.
- `.jsp` files currently open as HTML without a Java language service; Java completion and navigation inside JSP are unsupported.

Native windows, all logging/cancellation paths, inline JUnit/TestNG and Spring/MyBatis have not been fully accepted. JSP HTTP/Servlet debugging does not cover JSP-source completion or JSP breakpoints; Ant source layouts do not cover Ant targets. Java 5/7 source levels, long module-paths, JavaCC models, multi-release JARs and some older generic code remain limited; see README and Lithe #1881–1883.

Measurements found no significant JDT memory or completion-latency improvement. Windows workflows used x64 tools on ARM Windows, so their timings do not represent native AMD64 performance.

2 changes: 1 addition & 1 deletion io.github.lithe-idea.java-support/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"schemaVersion": 0,
"id": "io.github.lithe-idea.java-support",
"displayName": "Java Support",
"version": "1.1.2",
"version": "1.1.3",
"pluginAPIVersion": 0,
"requires": {"backend": 0, "debugAdapters": 0, "languages": 0, "languageServers": 0, "pluginFunctions": 0, "settings": 0, "projectGenerators": 0, "toolDefinitions": 0},
"requiresTools": ["java"],
Expand Down
Loading