Message-ID: From: "mblakley-casana (@mblakley-casana)" To: "pgjdbc/pgjdbc" Date: Wed, 13 May 2026 21:02:23 +0000 Subject: [pgjdbc/pgjdbc] issue #4068: Android/ART cannot load pgjdbc 42.2.10+ because maxResultBuffer parser references java.lang.management.ManagementFactory List-Id: X-GitHub-Author-Id: 163172869 X-GitHub-Author-Login: mblakley-casana X-GitHub-Issue: 4068 X-GitHub-Repo: pgjdbc/pgjdbc X-GitHub-State: closed X-GitHub-Type: issue X-GitHub-Url: https://github.com/pgjdbc/pgjdbc/issues/4068 Content-Type: text/plain; charset=utf-8 **I'm submitting a ...** - [x] bug report - [ ] feature request **Describe the issue** Android's ART runtime does not provide the Java SE `java.lang.management` package. Since pgjdbc 42.2.10, `org.postgresql.util.PGPropertyMaxResultBufferParser` has a verifier-visible reference to `java.lang.management.ManagementFactory`. That makes current pgjdbc releases fail to load in Android instrumentation/test APKs even when the application never configures `maxResultBuffer` and never uses the percentage form of that property. **Driver Version?** 42.2.10 and newer, including current 42.7.x releases. 42.2.8 does not have `PGPropertyMaxResultBufferParser` and is still loadable on Android for this use case. **Java Version?** Android Runtime (ART), reproduced on an Android API 34 emulator. This is not an Oracle/OpenJDK Java SE runtime issue; `java.lang.management.ManagementFactory` exists there. **OS Version?** Android API 34 emulator. The underlying issue applies to Android runtimes that omit `java.lang.management`. **PostgreSQL Version?** Not relevant to the class-loading failure. The driver fails before a query is needed. **To Reproduce** 1. Add pgjdbc version >= 42.2.10 to an Android instrumentation test APK. 2. In test code, load the driver or open a normal JDBC connection: ```java Class.forName("org.postgresql.Driver"); // or DriverManager.getConnection("jdbc:postgresql://...", user, password) ``` 3. Run the instrumentation test on Android. **Expected behaviour** The driver should load when `maxResultBuffer` is unset. **Actual behaviour** Android fails while resolving the pgjdbc class graph because `java.lang.management.ManagementFactory` is unavailable: ```text java.lang.NoClassDefFoundError: Failed resolution of: Ljava/lang/management/ManagementFactory; ``` **Logs** Representative Android failure: ```text java.lang.NoClassDefFoundError: Failed resolution of: Ljava/lang/management/ManagementFactory; ``` **Context** We use pgjdbc from Android end-to-end tests to perform direct PostgreSQL setup/teardown through a helper class. This is test-only usage, not production app database access. The Android runtime omits JMX/`java.lang.management`, so a static class reference to `ManagementFactory` prevents the driver class graph from loading. The `maxResultBuffer` percentage syntax is a JVM heap convenience feature, but the driver currently touches the class even when `maxResultBuffer` is unset. **Suggested fix** Avoid direct/verifier-visible references to `java.lang.management` from production driver classes. `PGPropertyMaxResultBufferParser` can look up `ManagementFactory`, `MemoryMXBean`, and `MemoryUsage` reflectively only when heap introspection is actually needed. If those classes are unavailable: - unset `maxResultBuffer` should continue to parse as disabled - byte values such as `100M` should remain usable, without heap-based capping - percentage values such as `10pct` should fail with a clear `PSQLException` I have a small patch prepared with tests for the missing-management-runtime path.