# Classpath Loading of OpenNLP Models

## Background

Since version 2.4.0, OpenNLP supports the ability to load pre-trained OpenNLP models from the classpath. It relies on either a simple implementation using the application's classpath or on the classgraph library to locate OpenNLP model JAR files. Our pre-trained models are bundled from the OpenNLP Models repository. This chapter describes

- how to load and use a pre-trained OpenNLP model available in the classpath.

- how to bundle a custom OpenNLP model to be loadable as a JAR file from the classpath.

## Loading a pre-trained model

First, you need to add the following dependency to your classpath:

    <dependency>
      <groupId>org.apache.opennlp</groupId>
      <artifactId>opennlp-model-resolver</artifactId>
      <version>CURRENT_OPENNLP_VERSION</version>
    </dependency>

by using our pre-trained models or by building custom models as described later in this section. If you need advanced classpath scanning capabilities, you can also add the classgraph library to your classpath.

    <dependency>
        <groupId>io.github.classgraph</groupId>
        <artifactId>classgraph</artifactId>
        <version>CURRENT_CLASSGRAPH_VERSION</version>
    </dependency>

Make sure you replace the placeholders with the appropriate version values. Next, you can search for such a model and load it from the classpath:

    final ClassgraphModelFinder finder = new ClassgraphModelFinder(); // or use: new SimpleClassPathModelFinder()
    final ClassPathModelLoader loader = new ClassPathModelLoader();
    final Set<ClassPathModelEntry> models = finder.findModels(false);
    for(ClassPathModelEntry entry : models) {

         final ClassPathModel model = loader.load(entry);
         if(model != null) {
              System.out.println(model.getModelName());
              System.out.println(model.getModelSHA256());
              System.out.println(model.getModelVersion());
              System.out.println(model.getModelLanguage());
              // do something with the model by consuming the byte array
         }
    }

Moreover, certain OpenNLP models can be obtained via a ClassPathModelProvider, such as OpenNLP's built-in DefaultClassPathModelProvider class. It allows direct use of models available under a certain locale, given that those are present in the classpath and can be loaded.

    final ClassPathModelProvider provider = new DefaultClassPathModelProvider(finder, loader);
    // Here: SentenceModel, other model types accordingly
    final SentenceModel sm = provider.load("en", opennlp.tools.models.ModelType.SENTENCE_DETECTOR, SentenceModel.class);
    if(sm != null) {
        // do something with the (sentence) model
    }

In this example, the finder and loader objects can be created or re-used as shown in the previous code example.

When running on Java 21+ (the minimum supported version since OpenNLP 3.0.0), the JVM argument

    --add-opens java.base/jdk.internal.loader=ALL-UNNAMED

may be required. Without this parameter, OpenNLP uses the JVM bootstrap classpath to locate models rather than the UCP class loader. For more advanced or non-standard class loading scenarios, using ClassGraph and implementing a custom provider may cover additional cases beyond the default UCP class loader or JVM bootstrap class path behavior.

## Bundling a self-trained model

If you intend to provide your own custom trained OpenNLP models as JAR files for classpath discovery, we recommend that you have a look at our setup in the OpenNLP Models repository. We recommend to bundle one model per JAR file. Make sure you add a model.properties file with the following content:

    model.name=${model.name}
    model.version=${model.version}
    model.sha256=${model.sha256}
    model.language=${model.language}

Make sure to replace the values accordingly and configure your build tool to include the binary model and the model.properties in the resulting JAR file. To load such a custom model, you may need to adjust the pattern for classpath scanning. For example, if you name the model "custom-opennlp-model", you need the following code to successfully find and load it:

    final ClassgraphModelFinder finder = new ClassgraphModelFinder("custom-opennlp-model.jar"); // or use: new SimpleClassPathModelFinder("custom-opennlp-model.jar")
    final ClassPathModelLoader loader = new ClassPathModelLoader();
    final Set<ClassPathModelEntry> models = finder.findModels(false);
    for(ClassPathModelEntry entry : models) {
        final ClassPathModel model = loader.load(entry);
        if(model != null) {
          System.out.println(model.getModelName());
          System.out.println(model.getModelSHA256());
          System.out.println(model.getModelVersion());
          System.out.println(model.getModelLanguage());
          // do something with the model by consuming the byte array
        }
    }