NPE Initializing PluginsService in ES8

I am trying to create a Node, which was working in ES7 and now am trying to do the same thing in ES v8.11.3. The simple code is

final Settings settings = Settings.builder()
        .put(ACTION_AUTO_CREATE_INDEX, false)
        .put(THREAD_POOL_WRITE_QUEUE_SIZE, 500)
        .put(CLIENT_TRANSPORT_PING_TIMEOUT, "20s")
        .put(TRANSPORT_TYPE, NETTY_TRANSPORT_NAME)
        .put(INDEX_STORE_TYPE, IndexModule.Type.FS.getSettingsKey())
        .put(PATH_HOME, new File(dir).getAbsolutePath())
        .put(PATH_DATA, new File(dir, "data").getAbsolutePath())
        .put(PATH_LOGS, new File(dir, "logs").getAbsolutePath())
        .put(CLUSTER_NAME, name)
        .put(NODE_NAME, name)
        .build();

Path configDir = Path.of(dir, "config");
return new Node(InternalSettingsPreparer.prepareEnvironment(settings, Collections.emptyMap(), configDir, null);

When this code runs, it gets to PluginsService#addServerExportersService line elasticsearch/server/src/main/java/org/elasticsearch/plugins/PluginsService.java at v8.11.3 · elastic/elasticsearch · GitHub PluginsService.class.getModule(); which returns an unnamed module (my understanding is this is valid) but the descriptor is null (see screenshot)

and then gets an NPE when later calling .exports() on the null descriptor (see elasticsearch/libs/core/src/main/java/org/elasticsearch/jdk/ModuleQualifiedExportsService.java at v8.11.3 · elastic/elasticsearch · GitHub)

Here is the call stack

I don't think my setup code is even relevant here, because PluginsService.class.getModule() is hardcoded in ES code and the module has a null descriptor. What module is expected here and what ought the descriptor be?

If the issue is somehow my setup, might someone have an example for me to create a node correctly?

I think I can't edit the above code anymore, but here's more complete code.

LogConfigurator.configureESLogging();
final Settings settings = Settings.builder()
    .put("path.home", "/Users/my_user")
    .build();

Path configDir = Path.of("/tmp", "config");
Node n = new Node(InternalSettingsPreparer.prepareEnvironment(settings, Collections.emptyMap(), configDir, () -> "nodename"));

and build.gradle has

    implementation "org.elasticsearch:elasticsearch:8.11.3"
    implementation "org.elasticsearch:elasticsearch-logging:8.11.3"
    implementation "org.apache.logging.log4j:log4j-core:2.17.1"
    implementation "org.apache.logging.log4j:log4j-api:2.17.1"

@rjernst sorry to ping you directly but I'm getting quite desperate - might you know about this issue? I see your name on this ModuleQualifiedExportsService code

This is a community forum manned by volunteers so it is considered rude to ping people not already involved in the thread. You also gave very little time before pinging, especially given that it was a weekend. As it is a community forum there are no SLAs or even guarantees of getting a response, so you should wait at least a few days before bumping your thread.

It may also help if you provided some additional contect around what you are doing as others might be able to chime in. Are you building a plugin? Are you trying to embed Elasticsearch into an application?

I don't think we'd expect this to work - it looks like you're trying to run Elasticsearch in "embedded" mode but this hasn't been a valid approach for ~8 years. I'm somewhat surprised that this worked for you even in 7.x.

The correct way to create a node is to run Elasticsearch in its own process.

1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.