Skip to content

nvim client compatibility fails with null/empty config data #548

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
awilkins opened this issue Feb 10, 2025 · 1 comment · Fixed by #550
Closed

nvim client compatibility fails with null/empty config data #548

awilkins opened this issue Feb 10, 2025 · 1 comment · Fixed by #550

Comments

@awilkins
Copy link
Contributor

Started a basic nvim-lspconfig config (please ignore all my horrible assumptions)

local fs = require('vim.fs')

return {
  default_config = {
    cmd = { 'java', '-jar', fs.abspath('~/vscode/natls/libs/natls/build/libs/natls.jar') },
    filetypes = { 'natural' },
    root_dir = function(dir)
      return fs.root(dir, '.natural')
    end,
  },
  docs = {
    description = [[
https://github.com/MarkusAmshove/vscode-natural

Natural Language Server
]],
  },
}

Sadly on connection it stops on this error

Error executing vim.schedule lua callback: /usr/local/share/nvim/runtime/lua/vim/lsp/client.lua:548: RPC[Error] code_name = InternalError, message = "Internal error." data = 'java.util.concurrent.CompletionException: java.lang.NullPointerException: Cannot invoke "org.amshove.natls.config.InitializationConfiguration.isAsync()" because the return value of "org.amshove.natls.config.LSConfiguration.getInitialization()" is null\n\tat java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:315)\n\tat java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:320)\n\tat java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1770)\n\tat java.base/java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1760)\n\tat java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)\n\tat java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)\n\tat java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)\n\tat java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)\n\tat java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)\nCaused by: java.lang.NullPointerException: Cannot invoke "org.amshove.natls.config.InitializationConfiguration.isAsync()" because the return value of "org.amshove.natls.config.LSConfiguration.getInitialization()" is null\n\tat org.amshove.natls.languageserver.NaturalLanguageService.indexProject(NaturalLanguageService.java:115)\n\tat org.amshove.natls.languageserver.NaturalLanguageServer.lambda$initialize$1(NaturalLanguageServer.java:136)\n\tat java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1768)\n\t... 6 more\n'
stack traceback:
	[C]: in function 'assert'
	/usr/local/share/nvim/runtime/lua/vim/lsp/client.lua:548: in function ''
	vim/_editor.lua: in function <vim/_editor.lua:0>

Not sure which path it's taking to initialize the config. I tried a couple of configs passing a struct to init_options but couldn't manage to set the async property.

A small patch to NaturalLanguageService on line 115 ...

		if (getConfig().getInitialization() != null && !getConfig().getInitialization().isAsync())

... and nvim works (not had a proper play with it yet).

Image

It seems to be generally agreed that starting a server without initialization options should "just work", but I'm not sure this is what's happening ; wondering if nvim's LSP client is supplying an empty string value here.

@MarkusAmshove
Copy link
Owner

MarkusAmshove commented Feb 11, 2025

Good find. VSCode sends default configuration and I've had my lsp-config send configuration since the server supported configuration.
I'll leave my configuration here, in case you're wondering how to pass the configuration.
But nonetheless, we should do the null check, because crashing is always bad.

local function register_natural()
  local root_files = { { '.natural', '_naturalBuild' } }

  local my_util = require'dotfiles.util'
  local user_home = my_util.get_user_home()
  local server_path = user_home .. '/dev/natls/libs/natls/build/libs/natls.jar'

  local lspconfig = require 'lspconfig'
  local configs = require 'lspconfig.configs'
  local lsp_util = require 'lspconfig.util'

  local java_path = "/usr/lib64/jvm/jdk-21.0.2+13/bin/java"
  local debugargs =  '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000'
  -- local debugargs = ""

  if not configs.natls then
    configs.natls = {
      default_config = {
        cmd = {java_path, debugargs, '-jar', server_path },
        filetypes = { 'natural' },
        root_dir = function (fname)
          for _, patterns in ipairs(root_files) do
            local root = lsp_util.root_pattern(unpack(patterns))(fname)
            if root then
              return root
            end
          end
        end,
        single_file_mode = false,
        init_options = {
          completion = {
            qualify = true
          },
        },
      }
    }
  end

  lspconfig.natls.setup {
    on_attach = after_attach
  }
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants