david-streamlio opened a new pull request, #25883: URL: https://github.com/apache/pulsar/pull/25883
Main Issue: https://github.com/quarkusio/quarkus/issues/48776 ### Motivation Applications using `pulsar-client-original` in GraalVM native-image builds currently fail unless the consuming framework (Quarkus, Micronaut, Spring Native, etc.) provides its own reflection and class initialization metadata for Pulsar client internals. This forces every framework to independently reverse-engineer and maintain configuration that tracks Pulsar's internal class layout — and when it drifts, native builds break silently. A concrete example: Quarkus's Pulsar extension registered `org.apache.pulsar.client.util.WithSNISslEngineFactory` for runtime initialization, but that class was removed in Pulsar 4.x. Because the configuration lived downstream instead of in the client itself, the breakage went unnoticed for a year (https://github.com/quarkusio/quarkus/issues/48776). Embedding the configuration directly in `pulsar-client-original` following the [GraalVM embedded configuration convention](https://www.graalvm.org/latest/reference-manual/native-image/overview/BuildConfiguration/#embed-a-configuration-file) means the `native-image` tool picks it up automatically from the classpath, keeping the config in sync with the code that owns the classes. ### Modifications Added three GraalVM native-image configuration files under `pulsar-client/src/main/resources/META-INF/native-image/org.apache.pulsar/pulsar-client-original/`: - **reflect-config.json** — Registers 20 classes for reflective access: the three `ConfigurationData` classes (deserialized by Jackson), all six `Authentication` implementations (instantiated by name via `AuthenticationUtil.create()`), the OAuth2 protocol model classes, schema internals (`ProtoBufParsingInfo`, `ProtobufNativeSchemaData`, `KeyValue`), `DataURLStreamHandler`, and `SecretsSerializer`. - **native-image.properties** — Marks eight classes for runtime initialization that would otherwise fail during native-image build due to eager static initialization of Netty allocators, thread pools, or HTTP clients: `PulsarByteBufAllocator`, `Commands`, `Backoff`, `TokenClient`, `GenericProtobufNativeSchema`, `ConnectionPool`, `ControlledClusterFailover`, and `HttpClient`. - **resource-config.json** — Includes the async-http-client default properties files that are loaded via classloader at runtime. Added `NativeImageConfigTest` that validates: - All classes referenced in `reflect-config.json` exist on the classpath - All classes referenced in `native-image.properties` exist on the classpath - All `Authentication` implementations shipped with the client are registered - Both JSON config files are well-formed This test catches configuration drift early — if a class is renamed, removed, or a new `Authentication` plugin is added without updating the config, the test fails with a descriptive message. Note: the shaded `pulsar-client` JAR intentionally strips `META-INF/native-image/**` in its shade plugin filters, which is correct since shading relocates packages and invalidates the original class names. Users building native images should depend on `pulsar-client-original`. ### Verifying this change This change added tests and can be verified as follows: - Added `NativeImageConfigTest` that validates all 20 reflection entries and 8 runtime-initialized classes resolve on the classpath, and that all `Authentication` implementations are registered. - Every class in the configuration was verified against the Pulsar 4.2.1 source tree. - The equivalent configuration (derived from Quarkus's `SmallRyeReactiveMessagingPulsarProcessor`) was validated by successfully compiling six native-image integration tests in the Quarkus `integration-tests/reactive-messaging-pulsar` module against Pulsar 4.2.1. ### Does this pull request potentially affect one of the following parts: - [ ] Dependencies (add or upgrade a dependency) - [ ] The public API - [ ] The schema - [ ] The default values of configurations - [ ] The threading model - [ ] The binary protocol - [ ] The REST endpoints - [ ] The admin CLI options - [ ] The metrics - [ ] Anything that affects deployment ### Documentation - [x] `doc-not-needed` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
