#Classloader
Gradle Under the Hood: ClassLoader Harvesting vs. Network CI Crashes
In the first article of our _Gradle Under the Hood_ series, we explored how we decoupled incremental build tracking from volatile compiler outputs to achieve bulletproof caching. Today, we dive into a critical continuous integration (CI) dilemma that almost every plugin author faces: **How do you execute complex, isolated task workloads on headless CI nodes without crashing due to missing network dependencies or restricted local caches?** Let’s unpack how we engineered the **JPersist Suite** verification engines to harvest their own running binary classpaths on-the-fly, how that architectural assumptions shattered across older Gradle versions, and how we leveraged native classpath streaming to achieve bulletproof reliability in our latest `v1.8.1` patch. ### The Headless CI Dilemma To protect the Gradle build daemon from memory leaks and classpath contamination, advanced automation tasks must run inside a sandbox. Gradle provides the magnificent **Worker API** , allowing you to execute tasks via isolated classloaders (`classLoaderIsolation`): workerExecutor.classLoaderIsolation { workerSpec -> workerSpec.classpath.from(toolsetFiles) }.submit(MyValidationWorker) { params -> ... } **Where it breaks on CI runners:** To populate `toolsetFiles`, a plugin typically declares an internal detached configuration and injects remote text coordinates (GAV format): project.dependencies.add(detachedConfigName, "io.github.jpersist.tools:persistence-tools-api:3.0.0") When running in a standard developer workspace, this works fine. But in a highly isolated, enterprise continuous integration runner (or mono-repository workspaces where individual component segments are built independently), this text-based lookup introduces massive fragility: 1. If the required companion library artifacts have not been officially merged and pushed to Maven Central yet, the resolution crashes with a `ModuleNotFoundException`. 2. If your CI pipelines restrict or completely disable access to `mavenLocal()`, sibling projects cannot share local intermediate build caches. 3. Forcing remote dependency resolution loops over internal libraries during a task execution step slows down your CI velocity. ### The First Iteration: ClassLoader Harvesting (v1.8.0) While building **JPersist v1.8.0** , we asked ourselves: _Why are we forcing Gradle to perform a slow, network-bound dependency lookup against Maven Central for library classes that the plugin itself is already running on?_ Since your primary plugin (e.g., `hibernate-persistence-gradle-plugin`) already declares a dependency on the core tools API module to compile, those physical classes **are already loaded into memory by the Plugin’s ClassLoader**. Instead of using text coordinates, we introduced **ClassLoader Harvesting**. The plugin programmatically queried its own running runtime environment to discover the exact physical `.jar` file path on disk hosting the core contracts, and fed those file handles straight to the isolated Worker via protection domain lookups: // Our initial v1.8.0 lookups implementation Class<?> providerClass = Class.forName(markerClassName, false, classLoader) def codeSourceLocation = providerClass.protectionDomain.codeSource?.location This successfully generated a clean local file collection array, completely insulating the task action from network overhead. ### The Plot Twist: Cross-Version Version Alignment We rolled out this design, and our local test suites under modern Gradle 9.x were glowing green. However, real-world integration testing against older long-term support (LTS) streams—specifically **Gradle 7.6.6 and Gradle 8.7** —unveiled subtle API signature and dependency lifecycle discrepancies that we hadn't anticipated. 1. **Lazy vs. Eager Extensions:** Under Gradle 9.x, the `Configuration.extendsFrom()` method natively unwraps lazy `NamedDomainObjectProvider` targets. In Gradle 8.x, passing a provider directly threw a `MissingMethodExecutionFailed` exception because the legacy eager API strictly expected a realized `Configuration` instance. 2. **The Transitive Sandbox Leak:** In mixed multi-project environments (where one project sub-module runs a legacy Hibernate 5 stack and another runs a modern Hibernate 6 stack), Gradle 7.x's older configuration engine aggressively elevated the dependency graph inside detached file scopes. Hibernate 6 classes accidentally leaked into our Hibernate 5 worker sandbox, stripping away legacy methods and breaking tasks with a critical `NoSuchMethodError`. ### The v1.8.1 Evolution: Native Classpath Streaming To guarantee 100% universal stability across Gradle 7.6.6, 8.7, and 9.x without hardcoding user-space definitions, we evolved our **ClassLoader Harvesting** implementation into a more robust two-tier pattern. First, we isolated the version lookup itself. Instead of scraping runtime class paths on the fly, the plugin now references a lean `persistence-plugin-info.properties` file generated incrementally at build time. This reads the exact published coordinate version out of a detached configuration, resolving smoothly without leaking transitive scopes: static ConfigurableFileCollection resolvePersistenceToolsFiles(Project project, Provider<String> jpaVersionProvider) { def version = jpaVersionProvider.get() boolean isLegacy = isLegacyJpaVersion(version) String providerArtifact = isLegacy ? "persistence-tools-legacy" : "persistence-tools-jakarta" String toolsVersion = "3.0.0" // Baseline safe fallback def props = new Properties() def resourceStream = JakartaPersistencePlugin.class.classLoader.getResourceAsStream("persistence-plugin-info.properties") if (resourceStream != null) { resourceStream.withCloseable { props.load(it) } toolsVersion = props.getProperty("persistence-tools.version").trim() } def detachedConfig = project.configurations.detachedConfiguration( project.dependencies.create("io.github.jpersist.tools:providerArtifact:{toolsVersion}") ) return project.files(detachedConfig) } Second, we paired this with **Native Classpath Streaming**. We bypassed raw, unchecked file collections entirely and mapped the task's execution graph straight to the project's native compilation classpath provider. By feeding `sourceSet.compileClasspath` directly into the task's configuration container, Gradle's native resolution engine handles conflicts, dependency trees, and caching boundaries naturally at execution time while remaining completely backward compatible: // Inside HibernateEnhancementPlugin.groovy (v1.8.1) def enhanceConfigName = sourceSet.name == 'main' ? "hibernateEnhanceClasspath" : "\${sourceSet.name}HibernateEnhanceClasspath" def enhanceConfigProvider = project.configurations.register(enhanceConfigName) { config -> config.canBeConsumed = false config.canBeResolved = true // Eagerly unpack via .get() for Gradle 8.x signature compatibility config.extendsFrom(project.configurations.named(sourceSet.compileClasspathConfigurationName).get()) } // Wire the lazy file collections straight into the task configuration graph enhanceTask.enhanceClasspath.from(enhanceConfigProvider) enhanceTask.enhanceClasspath.from(JakartaPersistencePlugin.resolvePersistenceToolsFiles(project, activeVersionProvider)) ### The Engineering Win By combining localized classloader resource harvesting with native compilation classpath streaming, we secured three major structural improvements for our users: 1. **100% Offline Independence:** The isolated worker tasks (`validatePersistenceSchema`, `lintNamedQueries`, and `hibernateEnhance`) can run completely offline on headless CI nodes. They don't care about `mavenLocal()` locks or staging delays on remote repositories. 2. **Absolute Lifecycle Parity:** Whether your enterprise application is running on Gradle 7.6.6, Gradle 8.7, or cutting-edge Gradle 9.x matrices, the configuration-time signatures match perfectly without crashing. 3. **Pristine Daemon State:** Tool binaries are contained strictly within the worker's parent context, keeping the global Gradle daemon's main classpath clean and unpolluted. In **Part 3** of our _Gradle Under the Hood_ series, we will look at **Thin Archives** and discuss why narrowing dynamic dependency propagation to exclusive `compileOnly` scopes is crucial to prevent runtime classpath pollution in enterprise Jakarta EE application servers. _What are your experiences dealing with classloader leakage or configuration API breaks between different Gradle lifecycles? Let's discuss in the comments below!_ 🔗 Check out the JPersist open-source architecture: https://github.com/jpersist/persistence
dev.to
November 5, 2026 at 8:34 AM
You can totally do that. It does take a little bit of work to spawn the Jni connection, add the libs to the classloader, etc

Disclaimer: This code is a bit old and hasn't been updated to a recent version of jni but it should give you a general gist of requirements: github.com/flutter/demo...
demos/native_interop_demos/jnigen_db_native_interop at main · flutter/demos
This repo is for unmaintained code that supports talks, blogs, and other experiments. - flutter/demos
github.com
October 5, 2026 at 6:48 AM
Android APK 逆向实战:从 JADX、Apktool 到 Frida、Ghidra,理解 DEX、SO、脱壳与加固
# Android APK 逆向实战:从 JADX、Apktool 到 Frida、Ghidra,理解 DEX、SO、脱壳与加固 在 Android 安全研究和 APP 开发过程中,APK 逆向是一个非常重要的技术方向。 很多人刚开始接触 APK 逆向时,通常只知道使用 JADX 打开 APK,然后查看 Java 代码。 但真正深入之后会发现,Android APK 背后涉及的内容远不止 Java 代码: * APK 文件结构 * AndroidManifest.xml * DEX * Smali * SO / ELF * JNI * ARM64 * ClassLoader * ART * Frida * DEX 脱壳 * SO 分析 * VMP * RASP * Android 版本适配 如果想真正理解 Android 加固和脱壳,仅仅会使用一个反编译工具是不够的。 本文从一个普通 APK 出发,把 **JADX、Apktool、Smali、Frida、Ghidra/IDA、DEX、SO、ART** 串起来,建立一套比较完整的 Android APK 逆向分析思路。 ## 一、APK 到底是什么? APK 本质上是一个 ZIP 格式的 Android 应用程序包。 例如: app.apk 修改扩展名或者直接使用解压工具打开,可以看到: AndroidManifest.xml classes.dex classes2.dex resources.arsc res/ assets/ lib/ META-INF/ 如果应用比较简单,可能只有一个: classes.dex 大型 Android 应用则可能存在: classes.dex classes2.dex classes3.dex classes4.dex Native 代码一般位于: lib/ ├── arm64-v8a/ │ ├── libxxx.so │ └── libyyy.so └── armeabi-v7a/ └── libxxx.so 因此可以简单理解: APK │ ├── Java / Kotlin │ ↓ │ DEX │ ├── Native │ ↓ │ SO │ ├── Resources │ └── Manifest / Signature # 二、使用 JADX 进行第一轮静态分析 JADX 是 Android APK 逆向分析中非常常见的工具。 它可以直接加载 APK,并尝试将 DEX 反编译成接近 Java 的代码。 例如: jadx app.apk 打开之后,可以看到类似: com.example.app ├── MainActivity ├── LoginActivity ├── MainApplication ├── network ├── utils └── ... 如果原始代码是: fun checkLogin(token: String): Boolean { return token.isNotEmpty() } 编译以后会进入 DEX。 JADX 做的事情实际上是: DEX ↓ 反编译 ↓ Java-like Code 所以需要注意: > JADX 显示出来的代码,并不等于原始 Java/Kotlin 源代码。 如果应用使用了: * R8 * ProGuard * 混淆 * Kotlin Coroutine * Lambda * Native * 自定义 ClassLoader * DEX 加密 * VMP 那么最终反编译出来的代码可能和原始源码存在非常大的差异。 # 三、为什么还需要 Apktool? JADX 更适合查看代码逻辑。 Apktool 则更适合分析: * APK 结构 * AndroidManifest.xml * Resources * Smali * APK 修改与重新打包 例如: apktool d app.apk -o app_out 解包之后通常可以看到: app_out/ ├── AndroidManifest.xml ├── smali/ ├── smali_classes2/ ├── res/ ├── assets/ └── unknown/ 其中非常重要的一部分就是: smali/ 这里保存的是 Smali 代码。 # 四、Smali 是什么? 理解 Android 逆向,Smali 是必须掌握的一部分。 可以简单理解成: Java / Kotlin ↓ D8 / R8 ↓ DEX ↓ Smali 表示 Smali 更接近 DEX 指令级别。 例如: .method public test()I .locals 1 const/4 v0, 0x1 return v0 .end method 逻辑非常简单: v0 = 1 return v0 实际逆向过程中: > JADX 负责帮助我们快速理解整体代码逻辑,Smali 则用于进一步确认具体实现。 例如 JADX 中看到: if (isLogin()) { startActivity(...); } 如果怀疑它存在某种校验逻辑,可以继续定位对应 Smali。 # 五、从 Java 层进入 Native 层 分析 APK 时,经常会遇到: public native boolean verify(String data); 或者: static { System.loadLibrary("xxx"); } 这说明部分核心逻辑可能已经进入 Native 层。 对应的文件通常位于: lib/arm64-v8a/libxxx.so 这时候继续使用 JADX 分析就不够了。 需要进入: Java / Kotlin ↓ JNI ↓ C / C++ ↓ SO 这个阶段通常会使用: * Ghidra * IDA * Binary Ninja 等 Native 分析工具。 # 六、使用 Ghidra / IDA 分析 SO Android 的 `.so` 文件通常属于 ELF 格式。 例如: libxxx.so 使用 Ghidra 或 IDA 加载之后,可以重点关注: ELF Header Sections Symbols Strings Imports Exports Functions 特别是 JNI 相关位置。 例如: JNI_OnLoad RegisterNatives Java_xxx_xxx 这些内容可以帮助我们建立: Java Method ↓ JNI ↓ Native Function ↓ SO 的调用关系。 # 七、JNI 是 DEX 和 SO 之间的重要桥梁 Android 应用经常存在这样的调用链: Java / Kotlin ↓ JNI ↓ C / C++ ↓ SO 例如: public native String decrypt(String data); 实际运行过程中可能变成: Java Method ↓ JNI Bridge ↓ Native Function ↓ libxxx.so 因此在分析 APK 时,如果发现大量: native System.loadLibrary() RegisterNatives() JNI_OnLoad() 就应该把分析范围扩展到 Native 层。 # 八、为什么加固 APK 很难直接用 JADX 分析? 普通 APK 的大致结构可以理解为: classes.dex ↓ ClassLoader ↓ Class ↓ ART ↓ 执行 但是经过加固之后,结构可能变成: APK │ ├── 壳代码 ├── 加密 DEX └── Native Loader ↓ Runtime ↓ DEX 解密 ↓ ClassLoader ↓ ART 因此静态分析工具拿到的: classes.dex 可能并不是真正的业务 DEX。 例如一个实际拥有大量业务功能的 APP: JADX ↓ 几十个类 但实际运行时: 几千甚至更多业务类 这就是 Android 加固经常出现的情况。 # 九、什么是 DEX 脱壳? 很多人理解的脱壳是: > 找到一个脚本,然后把 DEX 导出来。 但从技术原理来看,脱壳远不止如此。 一个典型的 DEX 加固流程可能是: 原始 DEX ↓ 加密 / 转换 / 虚拟化 ↓ 保护后的 APK 运行的时候: 保护后的 APK ↓ 壳代码 ↓ 运行时恢复 ↓ 真实 DEX / Code ↓ ClassLoader ↓ ART ↓ 执行 所以从研究角度来看,真正值得理解的是: > **代码什么时候被恢复、以什么形式存在,以及最终如何进入 ART 执行链路。** # 十、Frida 为什么重要? JADX、Apktool、Ghidra、IDA 主要属于静态分析工具。 Frida 则属于动态分析工具。 两者最大的区别可以简单理解为: 静态分析 APK ↓ DEX / SO ↓ 分析代码 动态分析: APK ↓ 实际运行 ↓ 观察函数 ↓ 观察参数 ↓ 观察返回值 ↓ 分析调用关系 例如: Java Method ↓ 参数 ↓ 执行 ↓ 返回值 动态分析能够帮助研究人员确认: * 某个函数是否真的执行 * 函数什么时候执行 * 参数是什么 * 返回值是什么 * Java 和 Native 如何交互 对于复杂的加固应用,这些运行时信息往往比单纯查看反编译代码更加重要。 # 十一、静态分析 + 动态分析 实际 APK 分析过程中,通常不会只使用一个工具。 比较常见的组合是: APK │ ┌──────────┴──────────┐ ↓ ↓ JADX Apktool │ │ Java/Kotlin Smali │ │ └──────────┬──────────┘ ↓ 定位逻辑 │ ┌──────┴──────┐ ↓ ↓ Frida Ghidra / IDA ↓ ↓ 动态分析 Native分析 │ │ └──────┬──────┘ ↓ JNI / ART ↓ 调用链 这样能够形成完整的分析闭环。 # 十二、ART 是理解 Android 加固的关键 如果只停留在 JADX 和 Smali 层面,很难真正理解现代 Android 加固。 进一步学习 Android 安全之后,就会遇到: > ART —— Android Runtime 可以简单理解为: DEX ↓ ClassLoader ↓ DexFile ↓ Class ↓ Method ↓ ART Runtime ↓ 解释执行 / JIT / AOT 这也是为什么研究 Android 加固时,经常需要阅读 AOSP 中 ART 相关源码。 重点关注的方向包括: ClassLoader DexFile ClassLinker JNI JIT AOT Method Class Loading 当一个加固方案深度介入这些运行时机制之后,就不能再简单地把它理解成: DEX 加密 而应该理解成: 代码保护 + 运行时加载 + 执行环境保护 + 完整性保护 # 十三、为什么 Android 新版本会影响加固? Android Runtime 并不是一成不变的。 随着 Android 版本升级: Framework ART Class Loading JNI Hidden API Memory Management Native Interface 都会发生不同程度的变化。 因此,如果加固方案深度依赖 ART 内部实现,就需要持续进行 Android 版本适配。 可以把 Android 应用的运行环境简单理解为: Application ↓ Java / Kotlin ↓ Android Framework ↓ ART ↓ Native ↓ Linux Kernel 越深入底层: > 加固方案能够控制的运行时细节通常越多,同时也意味着更高的版本适配成本。 这也是为什么一个加固方案在 Android 10、Android 12、Android 14、Android 15、Android 16 上的表现不能简单认为完全一致。 # 十四、DEX 加固和 SO 加固有什么区别? 这是理解 Android 加固非常重要的一点。 ## 1. DEX 加固 DEX 主要承载: Java / Kotlin 业务逻辑 算法 接口逻辑 关键字符串 常见保护思路包括: DEX Encryption DEX Packing Class Encryption VMP Runtime Loading ## 2. SO 加固 SO 主要承载: Native 算法 核心计算 JNI 接口 底层逻辑 常见保护思路包括: ELF Protection Symbol Stripping .text Protection Integrity Check Runtime Decryption Anti-Debug 因此比较完整的 Android 加固方案通常不是只保护 DEX,而是多个层面共同保护: DEX + SO + Resources + Runtime + Integrity + RASP # 十五、VMP 是什么? VMP 通常可以理解为: > Virtual Machine Protection,虚拟化保护。 普通代码执行过程可以简单理解成: Java / Kotlin ↓ DEX ↓ ART 而虚拟化保护可能变成: 原始代码 ↓ 转换成虚拟指令 ↓ Virtual Machine ↓ Interpreter ↓ 执行 例如原始逻辑: A + B 经过虚拟化后,不再直接保存成传统形式,而可能转换成一系列虚拟指令: LOAD LOAD ADD RETURN 然后由自定义解释器负责执行。 复杂的 VMP 可能包含: Virtual Instruction Dispatcher Handler Interpreter Control Flow Data Flow 因此 VMP 的分析难度通常明显高于普通的 DEX 混淆。 # 十六、Android APK 逆向的完整学习路线 如果从零开始学习 Android APK 逆向,可以按照下面的顺序进行。 ## 第一阶段:APK 基础 先理解: APK Manifest DEX Resources SO Signature 工具: JADX Apktool ## 第二阶段:Smali 重点掌握: register invoke move const if goto return new-instance iget iput 目标不是机械背诵指令,而是能够: > 看到 Smali 后快速还原程序逻辑。 ## 第三阶段:Java / Kotlin → DEX 理解: Java / Kotlin ↓ D8 / R8 ↓ DEX 进一步研究: classes.dex classes2.dex Multidex R8 ProGuard ## 第四阶段:Native 学习: C / C++ ↓ ARM64 ↓ ELF ↓ SO 工具: Ghidra IDA 重点掌握: JNI JNI_OnLoad RegisterNatives ARM64 Calling Convention ## 第五阶段:动态分析 学习: Frida 重点理解: Java Hook Native Hook 参数观察 返回值观察 调用链跟踪 ## 第六阶段:ART 最后深入: ART ClassLoader DexFile ClassLinker JNI JIT AOT 然后再研究: DEX Encryption Runtime Loading DEX Protection VMP SO Protection RASP Anti-Hook Integrity 这样学习会比一开始直接研究所谓的“脱壳脚本”更加系统。 # 十七、从逆向角度理解 Android 加固 当把整个流程串起来之后,会发现: > **Android 逆向和 Android 加固实际上是同一条技术链路上的两个方向。** 逆向研究关注: 代码在哪里? ↓ 什么时候加载? ↓ 如何解密? ↓ 谁调用? ↓ 在哪里执行? 而加固则试图提高这些问题的分析成本: 代码不能直接看到 ↓ 代码不能轻易恢复 ↓ 降低运行时暴露 ↓ 增加动态分析成本 ↓ 检测异常运行环境 因此现代 Android 加固并不是简单地: classes.dex 加密 而更接近: APK │ ┌─────────────┼─────────────┐ ↓ ↓ ↓ DEX SO Resources │ │ │ 加密/VMP ELF保护 加密 │ │ │ └─────────────┼─────────────┘ ↓ Runtime ↓ ClassLoader / ART ↓ Integrity / RASP # 十八、一套实用的 Android 逆向工具组合 如果主要用于学习和安全研究,不需要一开始安装几十个工具。 基础工具链可以使用: 分析目标 | 工具 ---|--- Java/Kotlin 代码分析 | JADX APK 解包 | Apktool Smali 分析 | Apktool DEX 分析 | JADX / DEX 工具 动态分析 | Frida Native 分析 | Ghidra / IDA ARM64 分析 | Ghidra / IDA Android Runtime | AOSP 源码 调试 | adb / LLDB 最终可以形成: APK │ ┌────────┴────────┐ ↓ ↓ JADX Apktool ↓ ↓ Java/Kotlin Smali │ │ └────────┬────────┘ ↓ 静态分析 │ ┌────────┴────────┐ ↓ ↓ Frida Ghidra / IDA ↓ ↓ 动态分析 SO / ARM64 │ │ └────────┬────────┘ ↓ JNI / ART ↓ DEX / SO 加载链 ↓ 加固与脱壳研究 # 十九、总结 Android APK 逆向真正值得学习的,并不是某一个工具或者某一个脱壳脚本,而是理解整个 Android Runtime 链路。 最核心的一条主线可以概括为: APK ↓ DEX ↓ ClassLoader ↓ ART ↓ JNI ↓ SO ↓ Native ↓ Runtime 掌握 **JADX + Apktool** ,可以完成基础静态分析; 掌握 **Smali** ,可以进一步理解 DEX 指令; 加入 **Frida** ,可以观察真实运行过程; 再结合 **Ghidra / IDA** ,就可以进入 Native 和 ARM64 层; 继续研究 **ART、DEX 加密、运行时加载、VMP、SO 加固和 RASP** ,才能真正理解现代 Android 加固的技术体系。 对于 Android 安全研究来说,最终需要建立的并不是“怎么脱壳”的单点知识,而是一套完整的认知: > **代码在哪里 → 如何加载 → 什么时候恢复 → 如何执行 → 如何保护。** 这条链路基本贯穿了 Android APK 逆向、脱壳以及加固技术的核心内容。
dev.to
September 17, 2026 at 9:40 AM
pf4j - plugin framework for Java

Allows to add plug-in capabilities to your Java app. Uses a new classloader for every plugin. Has been around for a long time but I never stumbled over it

pf4j.org
PF4J
PF4J site repository
pf4j.org
September 1, 2026 at 12:56 PM
Test failure: Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03/CircularCctorThreeThreads03.cmd (113053) https://github.com/dotnet/runtime/issues/113053
Test failure: Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03/CircularCctorThreeThreads03.cmd · Issue #113053 · dotnet/runtime
Failed in: runtime-coreclr gcstress-extra 20250302.1 Failed tests: coreclr linux arm Checked gcstress0xc_disabler2r_jitstress2 @ (Debian.12.Arm32.Open)Ubuntu.2204.ArmArch.Open@mcr.microsoft.com/dot...
github.com
March 3, 2025 at 2:28 AM
Looking at the spring boot hello world, it's like "oh yeah, this one annotation is doing what used to take 100s of lines of xml".

The magic of spring is that public classes are "discoverable". You can get the classloader object and look around the system.
April 18, 2026 at 10:24 PM
Be sure to include a lengthy section that uses the classloader API to make your library load first.
August 18, 2024 at 2:20 PM
From the #Gradle community 👉 👉 👉

Martin Bonnin shares his thoughts on the separation of concerns for your Gradle plugins!

https://mbonnin.net/2025-08-24_isolation_101/
Classloader isolation 101
Separation of concerns for your Gradle plugins
mbonnin.net
October 2, 2025 at 7:07 PM
🚀 Datasource Micrometer v1.4.1 & v2.2.1 have been released.

Highlights
• GraalVM hints for SPRING_PROXY
• Fix ClassLoader for SpringJdbcProxyFactory

Release Notes
• github.com/jdbc-observa...
• github.com/jdbc-observa...

#springboot #micrometer #observability #jdbc
Release Release v1.4.1 · jdbc-observations/datasource-micrometer
Add runtime hints for SpringJdbcProxyFactory (#107) Extract connection info retrieval from DataSourceObservationListener (#108) Specify fixed classloader in SpringJdbcProxyFactory (#109) Changelog...
github.com
April 8, 2026 at 4:00 AM
One constant between two such "official" plugins (by the vendors of the tools they bind to) is that they directly depend on the tools, rather than using a dedicated configuration and the Worker API for classloader isolation.
June 28, 2025 at 4:27 PM
I disagree about properties and plugins. There's a classloader inheritance, true, but plugins aren't inherited other than just being in the build classloader (some plugins auto-apply themselves to subprojects but that's bad practice, and not how Gradle itself works)
December 14, 2024 at 11:13 AM
Classloader issues make my brain hurt. #java
March 12, 2025 at 4:37 AM
fabricmc's classloader is also called Knot and it was the most normal thing until it wasn't
July 27, 2025 at 2:34 AM
Genau das Richtige für den 5. Montag... jackson und snakeyaml Classloader Probleme.
March 7, 2025 at 10:57 AM
🌻 released sbt 2.0.5, featuring
- in-process test ClassLoader that closes by default
- `update` task performance improvements
- common settings bug fix
eed3si9n.com/sbt-2.0.5 #Scala
sbt 2.0.5 · eed3si9n
eed3si9n.com
August 3, 2026 at 11:42 PM
The dev for the earlier usb 13.50 kernel exploit needs testers.
To qualify you need:
- A PS4 on 13.50
- a Blu-ray burner (NOT DVD burner you find in laptops)

Post a comment on the original tweet if you have these things.
twitter-thread.com/t/2068716414...
looking for someone with an owned ps4 on 1350 and a bluray burner with bd re disc to run a clean bd j logging test n the iso only prints bdj probe logs to confirm sunjce classloader codesource and al...
looking for someone with an owned ps4 on 1350 and a bluray burner with bd re disc to run a clean bd j logging test n the iso only prints bdj probe logs to confirm sunjce classloader codesource and al...
twitter-thread.com
June 21, 2026 at 4:01 PM
Yes but the plugins _will_ run in the same classloader as the one that runs build scripts, so they have to be compatible. It's the same for Java, if you run Gradle with Java 17, plugins compiled with 21 will break (badly).
July 1, 2025 at 6:56 AM
1. Class Loader Subsystem has 3 parts:

Bootstrap ClassLoader: Loads essential classes like String and Math.

Extension ClassLoader: Loads classes like JDBC drivers for DB connections.

System ClassLoader: Loads custom classes defining logic, e.g., DB connections or math.
December 29, 2024 at 1:49 PM
What does « class defined by a thread » means ? That a classloader loaded the class in that thread?
September 26, 2025 at 6:02 AM
This number is irrelevant of the classloader as it can change in a thread. So basically it tells you how many classes were loaded by that thread.
September 26, 2025 at 7:25 AM
Leyden EA:

Unified CDS archive supporting multiple types of optim. artifacts
Loaded Classes in CDS archive
Classloader lookup cache
Archived Method Profiles
AOT compilation of Java methods
AOT resolution of constant pool entries
AOT generation of Dynamic Proxies & reflection data

#JDK #leyden
github.com
June 21, 2024 at 10:44 AM