lsp-java
lsp-java copied to clipboard
Better explanaition of concept of workspace
I already for a long time try to understand how workspace
is defined in lsp-java
and fail.
As I can see by default a workspace will be created at ~/.emacs.d/workspace
.
Then I open 10 different maven projects and import their roots into this workspace. If I run lsp-workspace-folders-open
I can see all 10 projects there.
Now I close all java buffers expecting language server to be terminated as stated here https://github.com/emacs-lsp/lsp-java/issues/45 . But it does not happen - ps aux
shows me it is still running.
I close emacs and start it again.
I define a new workspace location with
(setq-default lsp-java-workspace-dir not-a-defaul-wp-dir)
(setq-default lsp-java-workspace-cache-dir (concat not-a-default-wp-dir ".cache"))
Then I open 11th maven project and import it expecting it will be the only one in a fresh workspace.
But I see all 11 projects loaded into workspace.
OK, I assume it is a problem with initial workspace at ~/.emacs.d/workspace
. I remove it completely, I remove the second workspace as well, start emacs again, open any java project and again witness all 11 projects are loaded into workspace.
After investigation I found out that only dropping file ~/.emacs.d/.lsp-session-v1
I can start a fresh workspace.
And finally I don't understand the concept of workspace
at all. Assuming Eclipse language server works the same way as Eclipse IDE separate workspaces should be independent.
Does maintainers of lsp-java have a clear vision how to work in multi-workspace environment?
Is it possible to start several servers/one server handling several workspaces?
What is a current working solution if I want to have one project per workspace (like in Intellij IDEA)? Is it to call lsp-workspace-folders-add
new project + lsp-workspace-folders-remove
for old project every time I switch to a new project?
How can I help to improve lsp-java in this field?
Find the answers inline:
Yauhen Lazurkin writes:
Now I close all java buffers expecting language server to be terminated as stated here #45 . But it does not happen - ps aux shows me it is still running.
This behaviouir has changed in lsp-mode - if you want to reenable it do
(setq lsp-keep-workspace-alive nil)
And finally I don't understand the concept of
workspace
at all. Assuming Eclipse language server works the same way as Eclipse IDE separate workspaces should be independent.
Workspace = eclipse workspace. This is what JDT LS is using for storing its cache. The confusion comes from the fact that this is not lsp entity but something eclipse specific and from lsp point of view it is redundant. From LSP (the protocol) the project is initialized with a set of (workspace)folders which lsp-mode stores in the session file. Thus, when you delete the workspace it does not delete the folders because it is only server internal storage.
Does maintainers of lsp-java have a clear vision how to work in multi-workspace environment?
My plan for the future is to integrate with workspaces in treemacs. So when you switch treemacs workspace it will switch the workspace for you.
Is it possible to start several servers/one server handling several workspaces?
Tehnically yes by registering multiple JDT LS clients or by changing the
lsp-java registration(removing multi-root support). The problem with
that is that there is already a code that assumes that there is only one
JDT LS instance. For example, you could globaly(not being in java
buffer) do dap-java-debug
it will look for the global jdt-ls instance
and ask it to search for main classes.
What is a current working solution if I want to have one project per workspace (like in Intellij IDEA)? Is it to call
lsp-workspace-folders-add
new project +lsp-workspace-folders-remove
for old project every time I switch to a new project?
You want to have multiple JDT LS running simultaneously in one emacs instance or you are fine with 1:1?
How can I help to improve lsp-java in this field?
It depends on what exactly you want to achieve. The only setup that will be relativelly hard to achieve is to have several jdt-ls instances running at the same time. But if you want to have multiple emacs instances each one runnin one jdt-ls with different project - this is easy.
Hi @yyoncho , thank you for explanation.
Ideal scenario for me would be
- there is any number of open workspaces with any number of projects in it
- by switching to any known project lsp understands current workspace
- by switching to any new project lsp asks to add to an existing workspace or to create a new one
- everything is backed by single JDT LS instance (I don't know if this is technically possible from server side). Latter point is less crucial.
By help I mean pull requests - either coding or documentation. But before doing anything I would like to discuss vision.
Yauhen Lazurkin writes:
Hi @yyoncho , thank you for explanation.
Ideal scenario for me would be
- there is any number of open workspaces with any number of projects in it
- by switching to any known project lsp understands current workspace
- by switching to any new project lsp asks to add to an existing workspace or to create a new one
- everything is backed by single JDT LS instance (I don't know if this is technically possible from server side). Latter point is less crucial.
By help I mean pull requests - either coding or documentation. But before doing anything I would like to discuss vision.
This is technically possible using the current lsp-mode/lsp-java API.
- Use
lsp-workspace-folders-add/remove
to add remove folder. - Use
lsp-session-folder->servers
to additionally associate the folder with the workspace. This is one thing that we do differently than vscode. In vscode, all of the workspace folders are associated with a language servers that support multuroot in one workspace. In lsp-mode the folder is associated with language server the first time you open a supported language. Maybe we should change that in core since ATM seems to be causing only troubles. - Restart the server - after you have switched the set of folder once you restart the server it will pick the new set of folders. If we fix 2 this won't be needed.
If we want to build a UI for that, as I mentioned before, IMO we could do integration with treemacs which already has a UI to manage workspaces, project roots, and so on(but we still have to address 2 in some way unless we associate a lsp-mode session with treemacs workspace).
I'm also quite confused by the concept of workspace/folders.
When I open some file in project A, lsp would ask me whether to watch all files under project A/B/C, and lsp-describe-session
would give me something like:
[-] /Code/ProjectA
`-[-] jdtls:75162
|-[-] Buffers
| |-[+] SomeFileInProjectA.java
`-[+] Capabilities
[-] /Code/ProjectB
`-[-] jdtls:75162
|-[-] Buffers
| |-[+] SomeFileInProjectA.java
`-[+] Capabilities
[-] /Code/ProjectC
`-[-] jdtls:75162
|-[-] Buffers
| |-[+] SomeFileInProjectA.java
`-[+] Capabilities
Does this means that every other projects is "opened"? How do I prevent that?
hi @blahgeek , yes, all 3 projects are opened. It means that if you will try to find a type you will use a classpath of all three projects. To prevent this when you switch project you need to remove old project from the workspace and restart server as described by @yyoncho In my opinion this is not the best approach and there should be a possibility to isolate projects without restarting server.
without restarting server.
there is no need to restart the server, lsp-workspace-folders-remove should be sufficient.
Hi, would like to clarify about the lsp-java-workspace-dir.
I am currently using lsp-treemacs-sync-mode to sync changes in my treemacs workspace so that it will reflect as a different lsp session. However, within each lsp session, my lsp-java-workspace-dir remains the same. Does lsp-java segregate the cache between lsp workspaces within the lsp-java-workspace-dir?
My lsp-java-workspace-dir also does not change when I switch treemacs workspace. Does lsp-java segregate the cache between lsp sessions within the lsp-java-workspace-dir?
What's the current status of this? I couldn't find lsp-session-folder (lsp-mode-20220901.1705). The following sequence for switching between projects works, but it's painful.
(lsp-workspace-folders-remove "C:/projects/prj1") ; automatically stops the server
(lsp-workspace-folders-add "C:/projects/prj2")
(lsp-restart-workspace)
When you switch your treemacs-workspace
, it would switch your lsp-workspace-folders
for you, if you have lsp-treemacs-symc-mode
on
ATM there is also lsp-save-vscode-workspace and lsp-load-vscode-workspace which uses vscode's json format and you can use it to manage folders from lsp-mode side
Thanks for those replies. It helped clear up some confusion. I also found this discussion on workspaces helpful. When I use sync mode, it only adds new projects, not remove old ones. This is OK for my current use case since all my projects are nearly identical branches.
However, the second project I switch to is giving the error "... is a non-project file, only syntax errors are reported". When I open a file in one branch, it shows up under buffers for both projects in lsp session. If I open the same file in the other branch, it shows up twice in each project under buffers. E.g.
C:/projects/BranchA MyJavaClass.java<branchA> MyJavaClass.java<branchB>
C:/projects/BranchB MyJavaClass.java<branchA> MyJavaClass.java<branchB>
For now, I will manually remove the workspace if I need to switch projects. I'm not sure if there is something wrong. I can open a new issue if you believe this is a bug.
So if you end up starting jdtls server for 2 versions of the same project, it won't work.
However, the second project I switch to is giving the error
how do you switch?
I'm using treemacs-project-follow-mode and lsp-treemacs-sync-mode as suggested by bboytian above. Then I just open a file in the other project which causes treemacs to update to the that project in the default workspace. This then causes lsp sync, which I can see from opening the lsp session window.
I was getting this error even before I had lsp-treemacs-sync-mode working correctly, though. I don't recall exactly how I had it set up, but I think I was just switching to a java file in the other project. That was why I had started using lsp-workspace-folders-remove; it would force the server to shut down, and then I could start fresh.