IDE advice needed

I am new to Scala, having found that my Java project (about 60K lines over about 100 classes) would be improved by rewriting it using compositionality. Scala 3’s intersection types are just what I need. I use IntelliJ IDEA, but run into problems because it flags errors where there are none, mainly around enums and not recognising some object names after an object has been defined. I can compile and run a file using scala on the command line (MacOS Terminal), but the same file won’t compile on IntelliJ despite having an up to date configuration. I realise there are issues with the IntelliJ plugin. This is a problem for me, because as someone early on the learning curve, I don’t always know if an error is an issue with the IDE or my mistake with syntax. Is there another IDE that works for Scala 3?

1 Like

That is a good question!

First of all, it’s always good to report any issues to the Scala plugin team to make sure they are aware of the problems. Also make sure that you are on the latest version as they are continuously improving.

An alternative to Intellij is metals, of which I am a maintainer. It uses the real compiler for most of it’s features, so it should always be up to date with new language features. This is a language server, which can be connected to any editor that supports the language server protocol. There are also existing plugins for a lot of editors that set everything up for you.

The most supported one is the plugin for Visual Studio Code, but users have successfully setup Neovim, Emacs, Zed, Helix and probably more. If you have any questions or problems do let me know I usually answer them as quickly as possible.

3 Likes

Thank you. Just to make progress, I am using sbt on the command line and Coteditor (which does some simple syntax colouring for Scala). It is like going back to 1978! I have been able to compile and run some Scala code that uses JavaFX, but I don’t use ScalaFX because I want to stay with the Java idiom (for FX only). I will try VSCode+Metals.

1 Like

I have installed VSCode with Metals and sbt, and can run simple programs. However, I want to access JavaFX. I have got to system to recognise imports, but I also need to set some jvm options. I have tried changing the launch.json configuration, and also created a .jvmopts file with the appropriate settings, but nothing seems to work: I still get the “needs java runtimes” error message. Is there an official way to provide vm options? I know which options to provide if I knew where they go. Also, maybe it is a cacheing thing, so is there a way to restart a build from scratch? Thanks.

For running you should be able to use jvmOptions in launch.json like:

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "scala",
      "request": "launch",
      "name": "Untitled",
      "mainClass": "MyMain",
      "args": [],
      "jvmOptions": ["-Dhello=123"],
      "env": {}
    }
  ]
}

though I haven’t tested it with JavaFX. Do you have a sample project somewhere maybe? What kind of options does it need? Does it need to be a specific Java FX compatible JDK?

1 Like

Thank you. I tried that, but the console error message is still:
Error: JavaFX runtime components are missing, and are required to run this application.
The command to run Java needs to include
–module-path /Users/william/Projects/javafx-sdk-21.0.5/lib --add-modules javafx.controls,javafx.fxml,javafx.media
but the console shows that these options are still not included in the command.
There seem to be several ways of supplying jvm options, but none seem to show up in the java command that is issued.

Intellij-idea looks in build.sbt. Maybe you can try to add javafx to that file.

Yes, did that too! Still no luck. Console still says:

Executing task: /“Users”/“william”/“Library”/“Java”/“JavaVirtualMachines”/“openjdk-21.0.1”/“Contents”/“Home”/“bin”/“java” -classpath “/Users/william/Projects/ScalaSBT/hello-world/.metals/.tmp/classpath_171F027B1590EAA2C44C8E3768821534.jar” Main

Error: JavaFX runtime components are missing, and are required to run this application

I know exactly what to provide as jvm options, but nothing persuades VSCode to include them in the command. Normally I use Intellij, but the Scala Plugin doesn’t yet provide the functionality I need.

Is this how you run it?

{
            "type": "scala",
            "request": "launch",
            "name": "Main222",
            "mainClass": "Main222",
            "args": [],
            "jvmOptions": ["–module-path /Users/william/Projects/javafx-sdk-21.0.5/lib", "--add-modules javafx.controls,javafx.fxml,javafx.media"],
            "env": {}
        }

that shows up in the run command without an issue. You can make sure that you are running the correct configuration by clicking debug in the run/debug view.

I didn’t split the jvmOptions into two strings, but I tried that now, and it still does not work, in either run or debug mode (gets Error: JavaFX runtime components are missing, and are required to run this application). Do I need to do anything special to re-import the edited launch.json?
Ah. Now I started the debug from the Run command (not the in-source grey label) and the debugger says
Unrecognized option: --module-path /Users/william/Projects/javafx-sdk-21.0.5/lib
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

This is progress. However, this option really should be recognised, as it is a run option.

Just for fun, I put the jvm options into the “args” object in launch.json instead of “jvmOptions”, and the error message showed the module path! Of course it was in the args to Main instead of java, but at least we know the launch.json did something. So, my conclusion is that the “jvmOptions” key in launch.json is being ignored. Maybe another key would work?

As far as I checked jvmOptions are not ignored from launch.json, but the code lenses (the gray icons) doesn’t take anything into account and are not related to the launch.json. It’s provided by the server whenever a main class is detected in the code. There is no sensible way to correlate the two, since one is created by the server and the launch.json is done by the client.

The only option here is to always use the configuration from launch.json and launch that.

As for unrecognized option it looks like maybe a wrong java is being used? You should specify the metals.javaHome option to the correct one and reimport the build. That should make metals pick that up.

If you’re able to create a small reproduction project I can take a look at the potential problems.

openjdk-21.0.1”/“

Does this JDK have JavaFX baked into it? It might help to install / use a JDK that has JavaFX built-in. Coursier can do that (as I recall, “Liberica” had JavaFX built-in).

Getting the javafx jdk isn’t the problem. That part works. The issue is figuring out where to specify the jvm options so they appear on the command line. I’ll try the latest suggestion (metals config) but can’t until tomorrow.