diff --git a/src/programming/java/工具箱/Maven.md b/src/programming/java/工具箱/Maven.md new file mode 100644 index 0000000..bb6de41 --- /dev/null +++ b/src/programming/java/工具箱/Maven.md @@ -0,0 +1,37 @@ +--- +icon: bi:arrows-expand +date: 2025-05-08 +category: + - 实用工具 + - JAVA +tag: + - maven +title: maven常用配置 +--- + + +maven常用配置 + + +# 阿里云镜像 + +```xml + + aliyunmaven + central + 阿里云公共仓库 + https://maven.aliyun.com/repository/public + +``` + +# 配置代理 +```xml + + http-proxy + true + http + 10.6.212.9 + 7897 + localhost|127.0.0.1|*.local + +``` diff --git a/src/programming/java/工具箱/MobaXterm.md b/src/programming/java/工具箱/MobaXterm.md new file mode 100644 index 0000000..160b41a --- /dev/null +++ b/src/programming/java/工具箱/MobaXterm.md @@ -0,0 +1,18 @@ +--- +icon: bi:arrows-expand +date: 2025-05-08 +category: + - 实用工具 +tag: + - MobaXterm +title: MobaXterm +--- + +MobaXterm工具实用教程 + + +1. 去官网安装正版软件,比如23.6版本的:[MobaXterm free Xserver and tabbed SSH client for Windows](https://mobaxterm.mobatek.net/) +2. 打开这个网站,输入信息:[MobaXterm Keygen](https://inused.github.io/pages/file/tool/MobaXtermKeygen.html) +3. 将自动下载的Custom.mxtpro文件放入到[mobaxterm]的目录下 +4. [重启软件]即已完成注册 + diff --git a/src/programming/java/工具箱/Scoop.md b/src/programming/java/工具箱/Scoop.md new file mode 100644 index 0000000..3898ad1 --- /dev/null +++ b/src/programming/java/工具箱/Scoop.md @@ -0,0 +1,288 @@ +--- +icon: bi:arrows-expand +date: 2025-05-09 +category: + - 实用工具 +tag: + - Scoop +title: Scoop +--- + +# Scoop + +欢迎体验 **Scoop** —— Windows 的命令行包管理神器!本文将带你全面了解 Scoop 的功能、安装方法、使用技巧以及常见问题解决方法。如果你厌倦了繁琐的软件安装流程,Scoop 绝对是你的最佳选择!🚀 + +------ + +## 什么是 Scoop? + +[Scoop](https://github.com/ScoopInstaller/Scoop?tab=readme-ov-file#installatio) 是一个专为 Windows 设计的命令行包管理工具,旨在简化软件的安装与管理。无论是开发者还是普通用户,Scoop 都能让你通过几行命令快速安装和管理应用程序,省去繁琐的图形界面操作。 + +> **Scoop 核心优势**:轻量、快速、无需管理员权限、环境整洁! + +------ + +## Scoop 的核心功能 + +Scoop 的设计理念是简化和自动化,以下是它的主要功能: + +- **消除 UAC 提示**:无需频繁点击“允许”弹窗。 +- **隐藏 GUI 安装向导**:告别繁琐的下一步、下一步。 +- **保持 PATH 环境整洁**:避免 PATH 变量被杂乱无章的路径污染。 +- **无副作用安装/卸载**:安装和删除软件时不会影响系统其他部分。 +- **自动解析依赖**:自动安装软件所需的依赖项。 +- **一键配置环境**:通过脚本快速配置开发环境,例如: + +------ + +## 安装 Scoop + +### 1. 安装PowerShell并配置权限 + +确保你的系统满足以下要求: + +- **PowerShell**:安装最新版本的 [PowerShell](https://aka.ms/powershell) 或 [Windows PowerShell 5.1](https://aka.ms/wmf5download)。然后执行以下指令: + +```powershell +Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser +``` + +这是一条用于配置 PowerShell 执行策略的命令。具体含义如下: + +- `Set-ExecutionPolicy`:这是 PowerShell 的一个 cmdlet,用于设置执行策略,控制脚本的运行方式。 +- `ExecutionPolicy RemoteSigned`:将执行策略设置为 `RemoteSigned` 模式。在这种模式下,允许本地创建的脚本无限制运行,但任何从互联网下载的脚本都必须具有受信任的签名才能执行。 +- `Scope CurrentUser`:指定此执行策略的更改仅适用于当前用户,而不会影响系统中的其他用户或其他范围(如整个计算机)。 + +### 2. 安装 + +以**非管理员身份**运行以下命令,Scoop 将默认安装到 `C:\Users\\scoop`: + +```powershell +# 查看 PowerShell 版本 +Get-Host | Select-Object Version +# 标准安装 +irm get.scoop.sh | iex +# 使用代理安装(若无法访问 GitHub) +irm https://get.scoop.sh -Proxy '127.0.0.1:7890' | iex +``` + +------ + +## 加速下载:Aria2 配置 + +Scoop 支持 [aria2](https://github.com/aria2/aria2) 来实现多连接下载,提升下载速度。只需安装 aria2 即可: + +```powershell +scoop install aria2 +scoop config aria2-warning-enabled false +``` + +### Aria2 配置项 + +通过 `scoop config` 调整 aria2 设置: + +1. **aria2-enabled**(默认:true):启用/禁用 aria2。 +2. **aria2-warning-enabled**(默认:true):显示/隐藏 aria2 警告。 +3. **aria2-retry-wait**(默认:2):重试等待时间(秒)。 +4. **aria2-split**(默认:5):文件分段数。 +5. **aria2-max-connection-per-server**(默认:5):单服务器最大连接数。 +6. **aria2-min-split-size**(默认:5M):最小分段大小。 +7. **aria2-options**:自定义 aria2 参数。 + +示例: + +```powershell +scoop config aria2-split 10 +scoop config aria2-max-connection-per-server 8 +``` + +------ + +## 软件仓库推荐 + +Scoop 的软件来源于“桶(bucket)”,分为官方和第三方仓库。 + +### 官方仓库 + +- **[Main](https://github.com/ScoopInstaller/Main)**:常用非 GUI 应用。 +- **[Extras](https://github.com/ScoopInstaller/Extras)**:不符合 Main 标准的应用。 +- **[Games](https://github.com/Calinou/scoop-games)**:开源/免费游戏及工具。 +- **[Nerd-fonts](https://github.com/matthewjberger/scoop-nerd-fonts)**:Nerd 字体。 +- **[Nirsoft](https://github.com/ScoopInstaller/Nirsoft)**:Nirsoft 工具集。 +- **[Sysinternals](https://github.com/niheaven/scoop-sysinternals)**:Sysinternals 套件。 +- **[Java](https://github.com/ScoopInstaller/Java)**:JDK/JRE 相关。 +- **[Nonportable](https://github.com/ScoopInstaller/Nonportable)**:不可移植应用。 +- **[PHP](https://github.com/ScoopInstaller/PHP)**:PHP 安装包。 +- **[Versions](https://github.com/ScoopInstaller/Versions)**:应用的替代版本。 + +### 第三方仓库 + +- **[scoopcn](https://github.com/scoopcn/scoopcn)**:国内应用为主。 +- **[dorado](https://github.com/chawyehsu/dorado)**:优质应用集合。 +- **[Cluttered-bucket](https://github.com/Paxxs/Cluttered-bucket)**:绿色软件及独立开发者应用。 +- **[scoopet](https://github.com/ivaquero/scoopet)**:学术研究相关工具。 +- **[scoop-zapps](https://github.com/kkzzhizhou/scoop-zapps)**:自动化更新仓库。 +- **[aki-apps](https://github.com/akirco/aki-apps)**:个人维护的 bucket。 +- **[siku](https://github.com/amorphobia/siku)**:个性化应用集合。 +- **[scoop-bear](https://github.com/AStupidBear/scoop-bear)**:包含 Navicat 等。 +- **[echo-scoop](https://github.com/echoiron/echo-scoop)**:包含 IDM 等。 +- **[abgo_bucket](https://github.com/abgox/abgo_bucket)**:包含 123pan 等。 +- **[diklios-scoop-bucket](https://github.com/diklios5768/diklios-scoop-bucket)**:包含 CooDesker 等。 + +添加第三方仓库示例: + +```powershell +scoop bucket add scoopcn https://github.com/scoopcn/scoopcn +``` + +------ + +## 常用命令速查 + +### 1. 获取帮助 + +```powershell +scoop help +scoop help install +``` + +### 2. 安装应用 + +- **当前用户安装**: + +```powershell +scoop install nano +``` + +- **全局安装(需管理员权限)**: + +```powershell +scoop install nano -g +``` + +- **高级选项**: + +```powershell +scoop install git -g --no-cache --skip +``` + +### 3. 卸载应用 + +- **卸载程序**: + +```powershell +scoop uninstall nano +``` + +- **卸载并移除配置文件**: + +```powershell +scoop uninstall nano -p +``` + +- **卸载全局程序**: + +```powershell +scoop uninstall nano -g +``` + +### 4. 更新操作 + +- **更新 Scoop 和 bucket**: + +```powershell +scoop update +``` + +- **更新指定应用**: + +```powershell +scoop update nano +``` + +- **更新所有**: + +```powershell +scoop update * +``` + +### 5. 其他实用命令 + +- **查看已安装应用**: + +```powershell +scoop list +``` + +- **检查可更新应用**: + +```powershell +scoop status +``` + +- **打开应用主页**: + +```powershell +scoop home nano +``` + +- **管理 bucket**: + +```powershell +scoop bucket known +scoop bucket add extras +scoop bucket list +scoop bucket rm extras +``` + +- **清理旧版本和缓存**: + +```powershell +scoop cleanup * +scoop cache rm * +``` + +- 配置代理 + +```powershell +# 配置代理 +scoop config proxy '127.0.0.1:7890' +# 移除代理 +scoop config rm proxy +``` + +------ + +## 常见问题及解决 + +### 问题:Inno Setup 错误 + +错误信息: + +``` +Signature detected: Inno Setup Setup Data (6.3.0) +This is not directly supported, but i'll try to unpack it as version 5602; Version detected: 6300 +Critical error: The setup files are corrupted. Please obtain a new copy of the program. +``` + +**解决方法**: + +安装 `innounp-unicode` 版本: + +```powershell +scoop uninstall innounp +scoop bucket add versions +scoop install versions/innounp-unicode +``` + +------ + +## 进阶学习 + +想深入了解 Scoop?查看 [官方文档](https://github.com/ScoopInstaller/Scoop/wiki) 获取更多高级用法和技巧! + +------ + +## 总结 + +Scoop 是一个强大而优雅的工具,让 Windows 软件管理变得轻松高效。无论是快速安装开发工具,还是管理日常应用,Scoop 都能让你事半功倍。快来试试吧,打造属于你的高效环境!💻 \ No newline at end of file diff --git a/src/programming/java/工具箱/SpringBoot打包体积优化.md b/src/programming/java/工具箱/SpringBoot打包体积优化.md new file mode 100644 index 0000000..4f21359 --- /dev/null +++ b/src/programming/java/工具箱/SpringBoot打包体积优化.md @@ -0,0 +1,616 @@ +--- +icon: bi:arrows-expand +date: 2025-05-13 +category: + - 实用工具 + - JAVA + - SpringBoot + - JAR +tag: + - JAR包瘦身 +title: SpringBoot打包体积优化.md +--- + +SpringBoot打包体积优化 + + +# Spring Boot JAR 瘦身与加密:构建安全高效的部署方案 + +在 Spring Boot 应用程序部署过程中,我们常常面临两个主要挑战: + +1. **JAR 包体积过大**:Spring Boot 应用打包时会将所有依赖一起打包,导致最终 JAR 文件臃肿 +2. **代码安全性问题**:部署到客户环境或公开场合的 JAR 包可能被反编译,造成核心业务逻辑泄露 + +为了解决这些问题,本文将介绍一套完整的解决方案,包括 JAR 包瘦身和 JAR 包加密两部分,以及配套的自定义类加载器,实现高效安全的 +Spring Boot 应用部署。 + +## 整体方案设计 + +该方案由两个主要项目组成: + +1. **spring-boot-jar-slim-encrypt**:用于将 Spring Boot 应用 JAR 包瘦身和加密 +2. **spring-boot-custom-classloader**:用于加载瘦身和加密后的 JAR 包 + +### 工作流程 + +``` +┌────────────────────┐ +│ 原始Spring Boot │ +│ JAR包 │ +└──────────┬─────────┘ + │ + ▼ +┌────────────────────┐ ┌────────────────────┐ +│ spring-boot-jar- │ │ │ +│ slim-encrypt工具 ├───►│ 提取依赖到libs目录 │ +└──────────┬─────────┘ └────────────────────┘ + │ + ▼ +┌────────────────────┐ +│ 瘦身后的JAR包 │ +└──────────┬─────────┘ + │ + ▼ +┌────────────────────┐ +│ XJar加密处理 │ +└──────────┬─────────┘ + │ + ▼ +┌────────────────────┐ +│ 加密后的JAR包 │ +│ (.xjar) │ +└──────────┬─────────┘ + │ + │ 部署 + ▼ +┌─────────────────────────────────────────┐ +│ 运行时环境 │ +│ ┌─────────────────┐ ┌───────────────┐ │ +│ │ 加密JAR (.xjar) │ │ 提取的依赖库 │ │ +│ └────────┬────────┘ └───────┬───────┘ │ +│ │ │ │ +│ │ │ │ +│ ▼ ▼ │ +│ ┌─────────────────────────────────┐ │ +│ │ PlainTextClassLoader │ │ +│ │ (自定义类加载器) │ │ +│ └─────────────┬─────────────┬─────┘ │ +│ │ │ │ +│ ▼ ▼ │ +│ ┌─────────────────┐ ┌───────────────┐ │ +│ │ 解密JAR内容 │ │ 加载外部依赖 │ │ +│ └─────────────────┘ └───────────────┘ │ +│ │ +└─────────────────────────────────────────┘ +``` + +1. 使用 spring-boot-jar-slim-encrypt 工具提取原始 JAR 包中的依赖 +2. 将依赖库单独存储在 libs 目录 +3. 对精简后的 JAR 包进行加密 +4. 使用自定义类加载器加载外部依赖和解密 JAR 包 + +## 项目一:spring-boot-custom-classloader + +这是一个自定义类加载器项目,它实现了两种类加载器: + +### 1. JarClassLoader 接口 + +```java +package com.mangmang; + +import java.io.File; + +public interface JarClassLoader { + String JAR_EXTENSION = ".jar"; + + /** + * 从指定目录加载所有JAR文件 + * + * @param jarDir 包含要加载的JAR文件的目录路径 + * @throws IllegalArgumentException 如果jarDir为null或不存在 + */ + default void loadJar(String jarDir) { + if (jarDir == null || jarDir.trim().isEmpty()) { + throw new IllegalArgumentException("JAR目录路径不能为空"); + } + + File directory = new File(jarDir); + if (!directory.exists() || !directory.isDirectory()) { + throw new IllegalArgumentException("指定路径不是有效目录: " + jarDir); + } + + File[] jarFiles = directory.listFiles(this::isJarFile); + if (jarFiles == null) { + return; + } + + for (File jarFile : jarFiles) { + System.out.println("加载 》" + jarFile.getName()); + scanJarFile(jarFile); + } + } + + /** + * 递归扫描文件或目录以查找JAR文件 + * + * @param file 要扫描的文件或目录 + * @throws IllegalArgumentException 如果file为null + */ + default void scanJarFile(File file) { + if (file == null) { + throw new IllegalArgumentException("文件不能为null"); + } + + if (!file.exists()) { + return; + } + + if (isJarFile(file)) { + addJARFile(file); + } else if (file.isDirectory()) { + File[] files = file.listFiles(); + if (files != null) { + for (File f : files) { + scanJarFile(f); + } + } + } + } + + /** + * 检查文件是否为JAR文件 + */ + default boolean isJarFile(File file) { + return file.isFile() && file.getName().endsWith(JAR_EXTENSION); + } + + /** + * 将JAR文件添加到类加载器 + * + * @param jar 要添加的JAR文件 + * @throws IllegalArgumentException 如果jar为null或不是有效的JAR文件 + */ + void addJARFile(File jar); +} + +``` + +这是一个接口,定义了 JAR 文件加载的核心方法: + +- `loadJar(String jarDir)`: 从指定目录加载所有 JAR 文件 +- `scanJarFile(File file)`: 递归扫描文件或目录查找 JAR 文件 +- `isJarFile(File file)`: 检查文件是否为 JAR 文件 +- `addJARFile(File jar)`: 将 JAR 文件添加到类加载器 + +### 2. PlainTextClassLoader 实现 + +```java +package com.mangmang; + +import org.springframework.boot.context.event.ApplicationStartingEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.lang.NonNull; + +import java.io.File; +import java.lang.management.ManagementFactory; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * 明文类加载器 + *

+ * 该类实现了自定义类加载器接口和Spring应用启动事件监听器接口。 + * 主要功能是在应用启动时,从JVM启动参数中查找指定路径的JAR文件并加载。 + * 通过反射机制将JAR文件动态添加到当前线程的类加载器中,实现运行时加载额外的类库。 + *

+ *

+ * 使用方法: + * 1. 在JVM启动参数中添加 -Dexternal.jars.path=你的JAR文件目录路径 + * 2. 系统将自动加载该目录下所有的JAR文件 + *

+ *

+ * 示例: + * java -Dexternal.jars.path.path=/path/to/jars -jar your-application.jar + *

+ */ +public class PlainTextClassLoader implements JarClassLoader, ApplicationListener { + + private final String findPath = "external.jars.path"; // 查找路径的键名 + private final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // 获取当前线程的类加载器 + private final List jarFiles = new ArrayList<>(); // 存储已加载的JAR文件列表 + + /** + * 构造函数 + *

+ * 在初始化时执行以下操作: + * 1. 设置当前线程的类加载器 + * 2. 输出启动日志信息 + * 3. 从JVM启动参数中检索包含"external.jars.path.path"的参数 + * 4. 提取路径值并调用loadJar方法加载指定目录下的JAR文件 + *

+ */ + public PlainTextClassLoader() { + // 设置当前线程的类加载器 + Thread.currentThread().setContextClassLoader(classLoader); + + // 打印启动信息 + System.out.println("启动自定义明文类加载器"); + + // 查找并加载外部JAR文件 + loadExternalJarsFromSystemProperties(); + } + + /** + * 从系统属性中查找并加载外部JAR文件 + */ + private void loadExternalJarsFromSystemProperties() { + List inputArguments = ManagementFactory.getRuntimeMXBean().getInputArguments(); + + // 查找包含指定路径参数的启动参数 + inputArguments.stream() + .filter(arg -> arg.contains(findPath)) + .map(this::extractPathFromArgument) + .filter(Objects::nonNull) + .forEach(this::loadJar); + } + + /** + * 从JVM参数中提取路径值 + * + * @param argument JVM启动参数 + * @return 提取的路径值,如果提取失败则返回null + */ + private String extractPathFromArgument(String argument) { + String prefix = "-D" + findPath + "="; + if (argument.startsWith(prefix)) { + String path = argument.replace(prefix, ""); + if (!path.isEmpty()) { + return path; + } + } + return null; + } + + /** + * 处理应用程序启动事件 + *

+ * 当Spring应用启动时会触发此方法。 + * 目前该方法为空实现,可以在此添加应用启动时需要执行的代码。 + *

+ * + * @param event Spring应用启动事件对象 + */ + + @Override + public void onApplicationEvent(@NonNull ApplicationStartingEvent event) { + // 应用程序启动事件的处理方法,目前为空 + } + + /** + * 将JAR文件添加到类加载器 + *

+ * 通过反射机制调用URLClassLoader的addURL方法,将指定的JAR文件URL添加到当前类加载器。 + * 添加成功后,JAR文件中的类可以被当前JVM加载和使用。 + * 同时将已加载的JAR文件记录到jarFiles列表中。 + *

+ * + * @param jar 要添加到类加载器的JAR文件对象 + * @throws RuntimeException 如果添加过程中发生任何异常,将抛出RuntimeException + */ + @Override + public void addJARFile(File jar) { + if (jar == null) { + throw new IllegalArgumentException("JAR文件不能为null"); + } + + try { + addUrlToClassLoader(jar); + jarFiles.add(jar); + System.out.println(jarFiles); + } catch (Exception e) { + throw new RuntimeException("添加JAR文件到类加载器失败: " + jar.getName(), e); + } + } + + /** + * 通过反射将JAR文件URL添加到类加载器 + * + * @param jar 要添加的JAR文件 + * @throws Exception 如果反射操作失败 + */ + private void addUrlToClassLoader(File jar) throws Exception { + Method addUrlMethod = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); + if (!addUrlMethod.isAccessible()) { + addUrlMethod.setAccessible(true); + } + URL jarUrl = jar.toURI().toURL(); + addUrlMethod.invoke(classLoader, jarUrl); + } +``` + +这是一个明文类加载器,实现了 `JarClassLoader` 接口和 Spring 的 `ApplicationListener` 接口,用于在 +Spring Boot 应用启动时加载外部 JAR 文件: + +主要特点: + +- 在 Spring Boot 应用启动时自动执行 +- 通过 JVM 参数 `-Dexternal.jars.path=你的JAR文件目录路径` 指定外部 JAR 文件目录 +- 使用反射机制将 JAR 文件 URL 添加到当前线程的类加载器中 + +使用示例: + +```bash +java -Dexternal.jars.path=/path/to/jars -jar your-application.jar +``` + +## 项目二:spring-boot-jar-slim-encrypt + +这个工具用于压缩和加密 Spring Boot JAR 文件,主要包含以下两个核心类: + +### 1. JarUtil 工具类 + +```java +// 路径:spring-boot-jar-slim-encrypt/src/main/java/com/mangmang/JarUtil.java +package com.sunri; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.io.FileUtil; +import io.xjar.XCryptos; +import io.xjar.XEncryption; +import org.apache.commons.compress.utils.IOUtils; +import org.apache.commons.compress.utils.Sets; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; + +public class JarUtil { + /** + * 表示UTF-8字符编码的常量。 + * 该变量用于在各种文件操作中强制使用UTF-8编码, + * 确保在整个应用程序中一致地处理文本数据。 + */ + private static final String UTF_8 = "UTF-8"; + /** + * 常量BOOT_INF_LIB表示JAR文件中通常存储依赖库的默认目录路径。 + * 该路径主要用于在压缩或排除等操作中识别和处理库文件。 + */ + private static final String BOOT_INF_LIB = "BOOT-INF/lib"; + /** + * 用于标识JAR(Java归档)文件的文件扩展名。 + * 该常量表示JAR文件的标准扩展名,通常用于 + * 文件过滤、命名或在目录或归档中识别JAR文件的操作。 + */ + private static final String JAR_EXTENSION = ".jar"; + /** + * 定义在管理JAR过程中生成的需求文件的后缀, + * 特别是在处理依赖项或排除项时使用。 + * 该字符串用作特定的文件名模式,用于保存与特定服务 + * 相关的排除依赖项或其他需求的列表。 + * 默认值为"-requirements.txt"。 + */ + private static final String REQUIREMENTS_SUFFIX = "-requirements.txt"; + /** + * 预定义的、不可修改的特定jar文件名集合,被视为 + * "安全"或"始终包含"的文件。这些jar文件通常在 + * 处理或压缩操作中免于排除过滤。 + * 该集合包含以下jar标识符: + * - "spring" + * - "logback-core" + * - "tomcat" + * 该变量用于根据jar文件名决定是否包含特定jar文件的操作中。 + * 它作为应用程序关键或必要jar的白名单。 + */ + private static final Set WHITE_LIST_JARS = Sets.newHashSet("spring", "logback-core", "tomcat"); + + /** + * 通过排除和包含指定的条目来压缩给定的源JAR文件,并将结果写入目标JAR文件。 + * 它处理源JAR的条目,应用排除和包含规则,还可以将某些条目提取到指定的目录中。 + * 在此过程中创建一个临时文件,成功完成后将其重命名为目标JAR文件。 + * + * @param serviceName 正在处理的服务名称,主要用于日志记录和创建其他相关文件。 + * @param sourceJar 要压缩的源JAR文件。 + * @param includes 指定应保留哪些条目的包含模式集合。可能会自动添加额外的默认包含项。 + * @param exclusions 指定应排除哪些条目的排除模式集合。 + * @param targetJar 将写入压缩JAR的文件。 + * @param libDir 某些被排除的条目可能被提取到的目录(如适用)。 + */ + public static void compress(String serviceName, File sourceJar, Set includes, Set exclusions, File targetJar, String libDir) { + includes.addAll(WHITE_LIST_JARS); + File tempJar = new File(targetJar.getAbsolutePath() + ".tmp"); + Set excludedJars = new HashSet<>(); + + if (processJarEntries(sourceJar, tempJar, includes, exclusions, libDir, excludedJars)) { + finalizeCompression(serviceName, targetJar, tempJar, excludedJars, libDir); + } else { + boolean delete = tempJar.delete(); + System.out.println("删除临时文件:{" + delete + "}"); + } + } + + /** + * 处理源JAR文件中的条目以生成临时JAR文件, + * 同时根据包含和排除规则过滤条目。如果需要, + * 还会将指定的JAR条目提取到库目录中。 + * + * @param sourceJar 要处理的源JAR文件 + * @param tempJar +``` + +这个工具类提供了两个主要功能: + +#### JAR 包压缩功能 + +`compress` 方法实现了 JAR 瘦身功能: + +- 根据包含列表和排除列表过滤 JAR 中的依赖 +- 将被排除的依赖提取到指定的库目录 +- 生成一个记录排除依赖的需求文件 +- 创建一个只包含必要依赖的精简 JAR 文件 + +#### JAR 包加密功能 + +`encrypt` 方法利用 XJar 库实现了 JAR 加密: + +- 支持指定加密密码 +- 通过包含和排除模式选择性地加密 JAR 中的内容 +- 生成加密后的 XJar 文件 + +### 2. SpringBootJarSlimEncryptApplication 主应用 + +```java +// 路径:spring-boot-jar-slim-encrypt/src/main/java/com/mangmang/SpringBootJarSlimEncryptApplication.java +``` + +这是工具的主应用类,提供了完整的命令行接口来处理 JAR 文件的压缩和加密: + +主要功能: + +- 通过配置常量定义输入/输出目录、加密设置等 +- 支持从 XML 配置文件加载要包含和排除的依赖项 +- 批量处理多个 JAR 文件 +- 支持通过系统属性覆盖默认配置 + +主要配置参数: + +- `xml.dir`: 依赖项 XML 文件目录(默认: `./config/xml/`) +- `raw.dir`: 原始 JAR 文件目录(默认: `./config/rawJars/`) +- `compress.dir`: 压缩后 JAR 文件目录(默认: `./config/compressJars/`) +- `libs.dir`: 提取的库文件目录(默认: `./config/libs/`) +- `xjar.dir`: 加密后的 XJar 文件目录(默认: `./config/xJars/`) +- `compress.enable`: 是否启用压缩功能(默认: `true`) + +## 使用步骤 + +### 步骤 1: 集成自定义类加载器 + +在你的 Spring Boot 项目中添加自定义类加载器依赖: + +```xml + + + com.mangmang + spring-boot-custom-classloader + 1.0.0 + +``` + +### 步骤 2: 构建 Spring Boot 应用 + +正常构建你的 Spring Boot 应用: + +```bash +mvn clean package +``` + +### 步骤 3: 配置依赖排除和包含规则 + +创建两个 XML 文件以定义要排除和包含的依赖项: + +**exclusions.xml**(要排除的依赖): + +```xml + + + + spring-boot-starter-web + 2.7.0 + + + +``` + +**includes.xml**(要保留的依赖): + +```xml + + + + spring-boot-custom-classloader + + + +``` + +### 步骤 4: 执行 JAR 瘦身和加密工具 + +将你的 Spring Boot JAR 文件放入 `./config/rawJars/` 目录,然后运行瘦身加密工具: + +```bash +java -jar spring-boot-jar-slim-encrypt.jar +``` + +你可以通过系统属性覆盖默认配置: + +```bash +java -Dcompress.enable=true -Dlibs.dir=/custom/libs/path -jar spring-boot-jar-slim-encrypt.jar +``` + +### 步骤 5: 部署和运行 + +部署加密后的 JAR 文件和提取的库文件: + +```bash +java -Dexternal.jars.path=/path/to/libs -jar your-application.xjar +``` + +## 技术原理解析 + +### JAR 瘦身原理 + +1. 扫描 Spring Boot JAR 中的 `BOOT-INF/lib` 目录 +2. 根据配置的排除和包含规则过滤依赖 +3. 将被排除的依赖提取到外部目录 +4. 创建一个不包含被排除依赖的新 JAR 文件 + +### JAR 加密原理 + +1. 使用 XJar 库实现 JAR 文件内容的加密 +2. 只加密指定的文件模式(如 Java 类文件、配置文件等) +3. 避免加密某些需要保持明文的资源 + +### 自定义类加载器原理 + +1. 在 Spring Boot 应用启动时初始化自定义类加载器 +2. 扫描指定目录下的 JAR 文件 +3. 使用反射机制将 JAR 文件 URL 添加到当前类加载器 + +## 方案优势 + +1. **减小 JAR 体积**:将大型依赖库外置,显著减小主 JAR 文件体积 +2. **提高安全性**:通过加密保护核心业务逻辑和敏感配置 +3. **灵活配置**:支持通过 XML 配置和系统属性灵活控制瘦身和加密过程 +4. **无缝集成**:与 Spring Boot 应用无缝集成,无需修改应用代码 + +## 注意事项 + +1. 确保加密密码安全保存,丢失密码将导致无法运行加密的 JAR +2. 测试瘦身后的应用,确保所有需要的依赖都能正确加载 +3. 部署时必须将提取的依赖库和加密后的 JAR 一起部署 +4. 启动应用时必须指定外部库路径参数 + +## 结论 + +通过结合 JAR 瘦身、JAR 加密和自定义类加载器,我们成功构建了一套完整的 Spring Boot 应用优化和保护方案。这不仅有效减小了部署包的体积,还提高了应用的安全性,为企业级 +Spring Boot 应用的部署提供了一种实用的解决方案。 + +在实际应用中,可以根据具体需求调整配置参数,以达到最佳的平衡点。例如,可以根据应用规模和安全需求调整要排除的依赖和加密的文件模式。 + +这套工具实现了将原本臃肿的 Spring Boot 应用拆分为核心加密 JAR 和外部依赖库的方案,使得应用部署更加灵活,也为应用分发和更新提供了更多可能性。 + +------ + +*注:本方案适用于需要保护核心业务逻辑或减小部署包体积的 Spring Boot +应用。对于简单应用或开源项目,可能不必使用这么复杂的方案。* \ No newline at end of file diff --git a/src/programming/java/工具箱/WebSocket和HTTP关系.md b/src/programming/java/工具箱/WebSocket和HTTP关系.md index 3f7c3e0..5de9ca1 100644 --- a/src/programming/java/工具箱/WebSocket和HTTP关系.md +++ b/src/programming/java/工具箱/WebSocket和HTTP关系.md @@ -7,6 +7,7 @@ category: tag: - websocket - http +title: WebSocket和HTTP关系 --- # WebSocket和HTTP关系 @@ -14,7 +15,7 @@ tag: ## 1. WebSocket简介 WebSocket 是 HTML5 提供的一种在单个 TCP 连接上进行全双工通讯的协议。它使客户端和服务器之间的数据交换变得更加简单高效,并允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需完成一次握手,便可创建持久性的连接,实现双向数据传输。 - + ## 2. WebSocket与HTTP的关系 ### 2.1 协议转换过程 diff --git a/src/programming/java/工具箱/XJar.md b/src/programming/java/工具箱/XJar.md new file mode 100644 index 0000000..7ec0a63 --- /dev/null +++ b/src/programming/java/工具箱/XJar.md @@ -0,0 +1,230 @@ +--- +icon: bi:arrows-expand +date: 2025-05-13 +category: + - JAVA + - 加密 +tag: + - xjar +title: XJar +--- + +XJar:保护您的Java应用程序免受反编译和源码泄露 + +# XJar:保护您的Java应用程序免受反编译和源码泄露 + +介绍一个强大且实用的工具——**XJar**。它专为Spring Boot JAR和原生JAR提供安全加密运行支持,能够有效防止源码泄露和反编译的风险。无论你是想保护个人项目还是企业级应用,XJar都能为你提供一个简单而高效的解决方案。 + +GitHub: https://github.com/core-lib/xjar + +## 什么是XJar? + +XJar是一个开源工具,通过对JAR包内的资源进行加密,并结合扩展的ClassLoader,构建了一套程序加密启动和动态解密运行的机制。它特别适合Spring Boot项目,同时也支持原生JAR,旨在帮助开发者保护Java应用程序的安全性。 + +## 功能特性 + +XJar提供了以下核心功能,让它在加密工具中脱颖而出: + +- **无代码侵入**:无需修改源代码,只需对编译好的JAR包进行加密即可。 +- **完全内存解密**:资源在运行时动态解密,减少源码或字节码泄露的风险。 +- **支持所有JDK内置加解密算法**:灵活选择适合你的加密算法。 +- **资源加密灵活性**:支持选择需要加密的字节码或其他资源文件。 +- **Maven插件支持**:集成到构建流程,加密更便捷。 +- **Go启动器**:动态生成Go语言启动器,保护密码不泄露。 + +## 环境依赖 + +- **JDK版本**:1.7及以上 + +## 使用步骤 + +下面我将详细介绍如何使用XJar加密你的JAR包,步骤清晰易懂。 + +### 1. 添加依赖 + +首先,在你的Maven项目中添加XJar依赖,并配置jitpack.io仓库: + +```xml + + + + + jitpack.io + https://jitpack.io + + + + + + com.github.core-lib + xjar + 4.0.2 + + + +``` + +> **小贴士**:如果只是用JUnit测试加密过程,可以将``设置为`test`。 + +### 2. 加密源码 + +使用XJar提供的`XCryptos.encryption()`方法对JAR包进行加密: + +```java +XCryptos.encryption() + .from("/path/to/read/plaintext.jar") // 待加密JAR包路径 + .use("io.xjar") // 加密密码 + .include("/io/xjar/**/*.class") // 需要加密的字节码 + .include("/mapper/**/*Mapper.xml") // 需要加密的资源文件 + .exclude("/static/**/*") // 排除静态文件 + .exclude("/conf/*") // 排除配置文件 + .to("/path/to/save/encrypted.jar"); // 输出加密后的JAR包 +``` + +- `include`和`exclude`支持ANT表达式或正则表达式,灵活控制加密范围。 +- 当两者同时使用时,加密范围为`include`内排除`exclude`后的资源。 + +### 3. 编译脚本 + +加密完成后,XJar会在输出目录生成一个`xjar.go`文件。这是Go语言编写的启动器源码,需要编译为可执行文件: + +- **Windows**:编译后生成`xjar.exe` +- **Linux**:编译后生成`xjar` + +编译需要Go环境,但运行时无需Go支持。注意:启动器带有防篡改校验,无法通用。 + +### 4. 启动运行 + +使用编译好的启动器运行加密后的JAR包: + +```shell +./xjar java -Xms256m -Xmx1024m -jar /path/to/encrypted.jar +``` + +- 启动器需放在Java命令之前。 +- 仅支持`-jar`方式启动,不支持`-cp`或`-classpath`。 +- 使用`nohup`时,需写为:`nohup ./xjar java -jar /path/to/encrypted.jar`。 + +## 注意事项 + +在使用XJar时,以下问题可能影响你的体验,我整理了解决方案供参考: + +### 1. Spring Boot Maven插件兼容性 + +XJar不支持`spring-boot-maven-plugin`的`executable = true`和`embeddedLaunchScript`配置,需删除: + +```xml + + org.springframework.boot + spring-boot-maven-plugin + + + +``` + +### 2. Spring Boot + JPA(Hibernate)报错 + +若使用Hibernate,启动可能报错。解决方法: + +1. 克隆[XJar-Agent-Hibernate](https://github.com/core-lib/xjar-agent-hibernate),编译生成`xjar-agent-hibernate-${version}.jar`。 + +2. 启动命令添加代理: + + ```shell + ./xjar java -javaagent:xjar-agent-hibernate-${version}.jar -jar your-app.jar + ``` + +### 3. 静态文件加载问题 + +加密静态文件可能导致浏览器加载失败,建议排除加密: + +```java +.exclude("/static/**/*") +.exclude("/META-INF/resources/**/*") +``` + +### 4. JDK 9+模块化问题 + +在JDK 9及以上版本,需添加参数: + +```shell +./xjar java --add-opens java.base/jdk.internal.loader=ALL-UNNAMED -jar /path/to/encrypted.jar +``` + +### 5. 阿里云Maven镜像问题 + +使用阿里云镜像时,需在`mirrorOf`中排除jitpack.io: + +```xml + + alimaven + central,!jitpack.io + http://maven.aliyun.com/nexus/content/repositories/central/ + +``` + +## 插件集成 + +XJar提供了[xjar-maven-plugin](https://github.com/core-lib/xjar-maven-plugin),可自动完成加密过程。 + +### 配置示例 + +```xml + + + + jitpack.io + https://jitpack.io + + + + + + com.github.core-lib + xjar-maven-plugin + 4.0.2 + + + + build + + package + + io.xjar + + + + + + + +``` + +### 执行方式 + +- **自动构建**:`mvn clean package -Dxjar.password=io.xjar` +- **手动执行**:`mvn xjar:build -Dxjar.password=io.xjar` + +> **强烈建议**:不要在`pom.xml`中写死密码,通过命令行传递更安全! + +## 参数说明 + +以下是`xjar-maven-plugin`的主要参数: + +| 参数名称 | 命令参数 | 参数说明 | 参数类型 | 缺省值 | +| --------- | ---------------- | ------------ | -------- | -------------------------- | +| password | -Dxjar.password | 密码字符串 | String | 必须 | +| algorithm | -Dxjar.algorithm | 加密算法名称 | String | AES/CBC/PKCS5Padding | +| keySize | -Dxjar.keySize | 密钥长度 | int | 128 | +| ivSize | -Dxjar.ivSize | 密钥向量长度 | int | 128 | +| sourceDir | -Dxjar.sourceDir | 源JAR目录 | File | ${project.build.directory} | +| targetDir | -Dxjar.targetDir | 目标JAR目录 | File | ${project.build.directory} | + +更多详情见:[xjar-maven-plugin](https://github.com/core-lib/xjar-maven-plugin)。 + +## 结尾 + +XJar以其无侵入性、灵活性和高效性,成为保护Java应用的绝佳选择。无论是个人项目还是商业产品,它都能帮你轻松加密JAR包,确保代码安全。赶快试试吧! \ No newline at end of file