[ 
https://issues.apache.org/jira/browse/OPENNLP-1954?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18115824#comment-18115824
 ] 

Kristian Rickert commented on OPENNLP-1954:
-------------------------------------------

I created a PR already that this needs to depend on: 

https://github.com/apache/opennlp/pull/1290

OPENNLP-1937

> Make OpenNLP jars native-image friendly (reachability metadata, reflection 
> fixes, docs, CI smoke test)
> ------------------------------------------------------------------------------------------------------
>
>                 Key: OPENNLP-1954
>                 URL: https://issues.apache.org/jira/browse/OPENNLP-1954
>             Project: OpenNLP
>          Issue Type: Improvement
>          Components: Build, Packaging and Test, Documentation
>            Reporter: Richard Zowalla
>            Priority: Major
>              Labels: graalvm, native-image
>
> h2. Description
> OpenNLP is a library, so we don't compile it to native code ourselves. 
> Applications that use OpenNLP do that, through the GraalVM 
> native-maven-plugin, Quarkus, Spring AOT and similar tools. The goal of this 
> ticket is that such an application builds a working image with no extra 
> OpenNLP-specific configuration, as long as it only uses built-in components 
> and loads models from files or streams.
> Background: dev@ thread "GraalVM native compilation" (Sep 2026): [dev@ 
> discussion|https://lists.apache.org/thread/5bp2zb15y34wcwo58x6w1ttz7qsnbfts]
> *In scope:* opennlp-api, opennlp-runtime, opennlp-ml-* (without DL), 
> opennlp-model-resolver, opennlp-formats.
> *Out of scope (separate proposals if there's demand):*
> * Publishing native binaries of any kind (CLI, gRPC server). These would need 
> a LEGAL review first.
> * A native shared library / C API ({{native-image --shared}}, 
> {{@CEntryPoint}}).
> * Native support for opennlp-dl / ONNX Runtime (JNI). We only document its 
> current status.
> * Performance work. Native image improves startup time and memory footprint, 
> not peak throughput.
> h2. Known problem areas on main
> # *Loading factories and extensions by class name.* {{ExtensionLoader}}, 
> {{BaseToolFactory}}, {{TrainerFactory}} and {{DataIndexerFactory}} load 
> classes by name. Factory class names also come from model manifests 
> ({{BaseModel}}) and from XML feature generator descriptors 
> ({{GeneratorFactory}}). Every built-in {{*Factory}}, trainer and 
> {{AbstractXmlFeatureGeneratorFactory}} implementation needs to be registered.
> # *Reflective constructors*
> #* {{GenericModelReader}} / {{GenericModelWriter}}: reader and writer class 
> looked up by model type
> #* {{ClassPathModelLoader}}: {{modelType.getConstructor(InputStream.class)}}
> #* {{DownloadUtil}}: {{type.getConstructor(Path.class)}}
> #* {{ParallelNegLogLikelihood}}: {{taskClass.getConstructor(...)}}
> #* Where it's cheap, replace these with explicit factories or lambdas (e.g. 
> an {{EnumMap}} or {{Function<InputStream, T>}}) instead of adding metadata.
> # *Java serialization.* {{BaseModel}} ({{readObject}}) and {{SvmDoccatModel}} 
> ({{ObjectInputStream}}) need serialization metadata, or we document them as 
> unsupported.
> # *Snowball stemmers.* {{Among}} uses {{MethodHandles.findVirtual}} on the 
> stemmer classes, so we either register those methods or change the generated 
> code.
> # *Bundled resources* need a resource config:
> #* stopword lists
> #* {{uax29/*.txt}}
> #* normalizer tables (CaseFolding, confusables, emoji-*)
> #* {{ner-default-features.xml}}, {{pos-default-features.xml}}
> #* {{opennlp.version}}
> # *{{SimpleClassPathModelFinder}}* reads {{jdk.internal.loader.*}} and scans 
> the classpath. That can't work in a native image. It should fail fast with a 
> clear message: check the {{org.graalvm.nativeimage.imagecode}} system 
> property, which avoids a dependency on the Graal SDK. The docs should point 
> to file-based model loading instead.
> # *CLI {{ArgumentParser}}* uses {{Proxy.newProxyInstance}}. This is low 
> priority because the CLI isn't a target, but proxy metadata for the 
> {{*Params}} interfaces is cheap to add.
> h2. Proposed sub-tasks
> # *Reachability metadata.* Add 
> {{META-INF/native-image/org.apache.opennlp/<artifactId>/reachability-metadata.json}}
>  to each affected module. Generate a baseline with the native-image-agent 
> while running the test suite, then trim it by hand to what's actually needed.
> # *Reduce reflection.* Replace reflective constructors in internal code paths 
> with explicit factories (item 2 above). Reflection stays only where the class 
> name comes from outside, i.e. manifests and descriptors.
> # *Classpath model finder.* Make {{SimpleClassPathModelFinder}} detect 
> native-image runtime and fail fast (item 6).
> # *Guard test (JVM).* Add a unit test that fails when a new built-in factory, 
> trainer or feature generator is added without a metadata entry, so the 
> metadata doesn't silently go stale.
> # *Native smoke test in CI*
> #* Add a {{native}} Maven profile and a non-deployed IT module built with 
> {{native-maven-plugin}}.
> #* The test covers sentence detection, tokenization, POS tagging and NER, 
> with models loaded from files.
> #* Add a GitHub Actions job on {{graalvm/setup-graalvm}} (CE). It can start 
> as non-blocking.
> # *User documentation.* Add a "Using OpenNLP in a native image" section to 
> opennlp-docs covering:
> #* what works out of the box
> #* loading models from files or streams instead of classpath scanning
> #* registering custom factories, extensions and feature generators
> #* Java serialization limits
> #* opennlp-dl / ONNX Runtime status
> #* sample {{native-maven-plugin}} config
> #* CE caveats (startup and footprint improve, peak throughput does not)
> h2. Acceptance criteria
> * A sample app using only OpenNLP jars from Maven Central builds with 
> {{native-maven-plugin}} and no user-supplied OpenNLP config. The native 
> binary correctly runs sentence detection, tokenization, POS tagging and NER 
> on models loaded from files.
> * The native smoke test runs in CI.
> * Unsupported paths (classpath model finder, DL module) fail with a clear 
> error message and are documented.
> * The documentation is published with the release.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to