emacs-lsp / lsp-java

lsp-mode :heart: java
https://emacs-lsp.github.io/lsp-java
GNU General Public License v3.0
650 stars 90 forks source link

`lsp-java-update-project-configuration` raises unfriendly errors #141

Open Alexander-Shukaev opened 5 years ago

Alexander-Shukaev commented 5 years ago

Describe the bug

If one invokes lsp-java-update-project-configuration, for example, from magit-status buffer, (buffer-file-name) is nil, hence the backtrace (see below). That is, it won't even reach a hint error (error "Update configuration could be called only from build file(pom.xml or gradle build file)" (by the way it's rather user-error).

Expected behavior

User-friendly approach would be to allow invocation of lsp-java-update-project-configuration from any (sub)directory or file of the project. All you need is a reusable function to locate dominating files that you are looking for to satisfy condition, e.g.:

(defun lsp-java--dominating-file (name &optional file)
  "Use `locate-dominating-file'."
  (and (setq file (locate-dominating-file
                   (file-name-directory (or file
                                            (buffer-file-name)
                                            default-directory))
                   name))
       (expand-file-name file)))

And now:

(defun lsp-java-update-project-configuration ()
  "Update project configuration."
  (interactive)
  (let ((default-directory (or (lsp-java--dominating-file "pom.xml")
                               (lsp-java--dominating-file #'(lambda (directory)
                                                              (directory-files directory nil "\\.gradle\\'"))))))
    (if default-directory
        (lsp-java-with-jdtls
          (lsp-notify "java/projectConfigurationUpdate"
                      (lsp--text-document-identifier)))
      (user-error "Update configuration should be called only from project tree containing build file (pom.xml or gradle)"))))

Logs

Debugger entered--Lisp error: (wrong-type-argument stringp nil)
  file-name-nondirectory(nil)
  (let ((file-name (file-name-nondirectory (buffer-file-name)))) (if (or (string= file-name "pom.xml") (string-match "\\.gradle" file-name)) (let ((lsp--cur-workspace (lsp-java--current-workspace-or-lose))) (lsp-notify "java/projectConfigurationUpdate" (list :uri (lsp--buffer-uri)))) (error "Update configuration could be called only from build file(pom.xml or gradle build file)")))
  lsp-java-update-project-configuration()
  funcall-interactively(lsp-java-update-project-configuration)
  call-interactively(lsp-java-update-project-configuration)
Alexander-Shukaev commented 5 years ago

Since I am a new user, perhaps, I can ask a question indirectly related to this issue. How do I build a Maven project using lsp-java? I see two relevant functions, lsp-java-update-project-configuration and lsp-java-build-project. Both of which succeeded (if invoked properly). However, I don't see any jar files appearing. Where are the build artifacts? Sorry for these dumb questions.

yyoncho commented 5 years ago

lsp-java-update-project-configuration

This will refresh the pom.xml data but is pretty much no longer needed since latest version of lsp-java tracks automatically the pom.xml changes.

lsp-java-build-project

This will produce only ".class"(equivalent to the Build project in eclipse if you are familiar with it).

If you want to do build the project(e. g. invoke mvn clean install) I would recommend you to use projectile's projectile-compile-project. You may try also https://github.com/apg/mvn-el .