lsp-java icon indicating copy to clipboard operation
lsp-java copied to clipboard

Cannot evaluate, please specify projectName in launch.json

Open iocanel opened this issue 6 years ago • 8 comments

Describe the bug

I am debugging a unit test and try to evaluate region or thing at point. Evaluation fails with the following error message:

error in process filter: Cannot evalution expression because of 
java.lang.IllegalStateException: Cannot evaluate, please specify projectName in 
launch.json.. [4 times]

iocanel avatar Apr 03 '19 15:04 iocanel

See https://github.com/emacs-lsp/dap-mode/issues/46 . This is a limitation related to the fact that we are using eclipse che methods to resolve the test name and it does not provide the project name. At the same time, the VScode debug adapter requires the project name. One of the possible solutions is to drop the che methods and use the methods from the vscode test extension but it has some limitations(e. g. it requires junit 4.8) I am still evaluating the options.

yyoncho avatar Apr 03 '19 17:04 yyoncho

Is it possible to work around it? Maybe, create a launch.json and add it somewhere?

iocanel avatar Apr 03 '19 17:04 iocanel

Doing that:

(defun dap-java--run-unit-test-command (runner run-method?)
  "Run debug test with the following arguments.
RUNNER is the test executor. RUN-METHOD? when t it will try to
run the surrounding method. Otherwise it will run the surronding
test."
  (-let* ((to-run (->> (list :cursorOffset (point)
                             :sourceUri (lsp--path-to-uri (buffer-file-name)))
                       (lsp-send-execute-command "che.jdt.ls.extension.findTestByCursor")
                       cl-first))
          (test-class-name (cl-first (s-split "#" to-run)))
          (class-path (->> (vector test-class-name nil)
                           (lsp-send-execute-command "vscode.java.resolveClasspath")
                           cl-second
                           (s-join dap-java--classpath-separator))))
    (message "CLASSPATH: %s " class-path)
    (list :program-to-start (s-join " "
                                    (cl-list* runner "-jar" dap-java-test-runner
                                              "-cp" (format dap-java--var-format "JUNIT_CLASS_PATH")
                                              (if (and (s-contains? "#" to-run) run-method?) "-m" "-c")
                                              (if run-method? to-run test-class-name)
                                              dap-java-test-additional-args))
          :environment-variables `(("JUNIT_CLASS_PATH" . ,class-path))
          :projectName dap-java-project-name
          :cwd (lsp-java--get-root))))

and then defining dap-java-project-name to be the name of the maven project can act as a workaround for the issue. With this API I cannot

yyoncho avatar Apr 03 '19 18:04 yyoncho

I am considering switching from jdt eclipse che to jdt-ls + vscode extension bundles which will solve that issue. Also, eclipse-che-ls does not update the jdt-ls regularly which is a bit irritating since there are a lot of new features in current jdt-ls version.

yyoncho avatar Apr 03 '19 18:04 yyoncho

I have custom functions for retrieving the project name (Gradle or Maven based only). I rely on them with emacs-lsp and eglot. For Maven, I extract the artifactId from the pom.xml file and for Gradle, I parse the settings.gradle script.

For my particular use-cases, a project is often a multi-module Maven or Gradle project, so I wouldn't expect a generic folder name or the "root" name based on random assumptions (git folder base name or anything like that).

I think that it would be great if the LSP server itself would return the project "known real name" for a given "connection". The server should already know if it's a Maven or Gradle or plain Java project and then use it as extra metadata, after all the server likely already parsed the "external project model" prior importing it.

yveszoundi avatar Apr 09 '19 23:04 yveszoundi

@yveszoundi

I think that it would be great if the LSP server itself would return the project "known real name" for a given "connection". The server should already know if it's a Maven or Gradle or plain Java project and then use it as extra metadata, after all the server likely already parsed the "external project model" prior importing it.

There are such methods in vscode test extension and in vscode dependency extension. I am starting a rework to switch from che to jdt.ls + bundles and meanwhile I will expose all of the most of the new functionality that has been implemented in jdt.ls. We are now in pretty good shape at lsp-mode side so it will be fine to spend some time on lsp-java.

yyoncho avatar Apr 10 '19 04:04 yyoncho

FWIW, for maven projects, I read the artifactId and use that as a project name. Then I call dap like: https://github.com/iocanel/idee/blob/master/idee-maven.el#L218

iocanel avatar May 22 '19 14:05 iocanel

@iocanel It was reported that even a project root uri will do(I haven't tested that).

yyoncho avatar May 22 '19 15:05 yyoncho