Scala: sbt issues

Report of the bug that prevents sbt from executing correctly in the Bifrost IDE

Overview of the Issue

When using the sbt tool (used to compile/package Scala, and start the Metals server for Scala), an issue appears:

sbt thinks that server is already booting because of this exception:
sbt.internal.ServerAlreadyBootingException: java.io.IOException

After this exception is raised, the user is presented with this option:

Create a new server? y/n (default y)

After pressing Y, sbt continues with its normal execution. However, there are some cases in which the Metals server will execute sbt commands without any user interaction, and they will fail (since the user is not able to press Y when the sbt commands asks if it is necessary to create a new server).

This issue prevents the Metals server from working correctly.

The issue is documented in the following links:

Some solutions were offered but the issue can still be replicated in the Bifrost IDE environment. The #6777 issue

Cause

In the case of the Bifrost IDE, this happens only when the project is created on a folder within /home/BlackDiamond/workspace. This workspace directory is a network directory, mounted on a Azure storage account. When sbt is run, sbt tries to create a socket on a child folder of the project folder (which is on the workspace directory). This fails because of the nature of the directories in workspace (they are network directories).

Patch/Temporary Solution

The temporary solution is to use a custom sbt version (an alpha/snapshot), which creates the socket in another location (which is unique for any project). The only file that was modified in the sbt source code was this (BootServerSocket.java), which looks like this after the change:

Only the socketLocation method was modified:

Changes in the socketLocation method

To use this custom sbt version, the Scala project must use the sbt version 1.6.3-SNAPSHOT. This can be configured in the project/build.properties file in the project directory. In order to make sure that this is always the case, the Metals version that is used is the 0.11.3-SNAPSHOT version (this is configured globally by the BlackDiamond extension). This Metals version always sets the sbt version to 1.6.3-SNAPSHOT, whenever a new project is created with Metals.

Final Solution

The final solution is explained here. To summarize the explanation: there will be an sbt configuration that handles whether an alternative socket location must be used and which will it be (both of these configurations are hard-coded in the temporary solution, at the start of the socketLocation method). By default, the normal socket location will be used.

For all practical purposes, the temporary solution and the final solution behave in the exact same way, with only one exception: the temporary solution relies on an SNAPSHOT version of sbt and metals. It is much better to rely on a stable version of both. In order to do so, it is necessary to merge the necessary changes into the sbt repository, so that the issue is fixed on an official version of sbt.

Last updated