-
Notifications
You must be signed in to change notification settings - Fork 0
Usage Guide
As explained in Limitations,
the tool cannot always generate Java code which compiles and/or is 100% logically correct.
However you can improve the quality of the output by doing some modifications to the Scala code in advance.
Here are some suggestions:
Since some advanced Scala features cannot be handled by the tool, you can remove all usages of them in advance.
There are many of these and it can be time-consuming. I recommend to focus on:
-
implicit
-s - self-types
-
import
-s inside classes and code blocks - Named parameters and method arguments
Scala has so-called "syntactic sugar" which allows one to write more concise code while omitting certain keywords and language elements, which are mandatory in Java. Although the tool is able to handle some of them, in other cases it has to "guess" and might fail to correctly determine the missing elements.
You can help it by "de-sugaring" the syntax into the more verbose and complete syntax.
Examples of this:
- Explcitly specify variable and method types
- Add missing
return
keywords - Add empty parentheses to method invocations with no arguments
- Add explicit
new
keyword to case-class instantiations - Add explicit
apply
method invocations
NOTE: If you work in IntelliJ, the Scala plugin has support for automatic desugaring by right-clicking in the editor (or Ctrl+Alt+D). However, be careful with this - there are lots of configurable options, and sometimes the code produced is not so readable and would actually make things more difficult for the tool. You may want to try an iterative approach where you run the tool several times and use the desugaring to help fix its mistakes.
Scala has more extensive support for functional programming than Java, and some of the relevant types and methods cannot be easily translated into Java. In order to avoid extra complexity, Scala2Java will translate some of these into the equivalents from the JOOL (Jooq Lambda) and VAVR frameworks.
If your project doesn't already have these dependencies, you must add them before running the tool.
Some of the types that Scala2Java will translate into are:
- From JOOL:
- Tuple
- Function#
- From VAVR:
- Either
- Try
Scala2Java is published to Maven Central at these coordinates (also given in the README):
Group: io.github.effiban
Artifact: scala2java-core_2.13
The tool receives one or more Scala source files and translates them one by one to Java.
The output can either be printed to the console or save to a given directory.
In the second case, each Scala file will be translated into a corresponding file with the same name and a .java suffix
There are currently two options for running the tool: With a CLI and as an SDK. In the future, I plan to add an IntelliJ plugin as well.
Important: The tool must be executed with the runtime classpath of your project. This will allow the tool to accurately determine imports and perform translations of terms and types from Scala to Java.
- Download the executable jar - which is the one with the -all suffix
- To generate output to the console run the following command:
java -cp scala2java-core_2.13-<version>-all.jar:<project_classpath> io.github.effiban.scala2java.core.Scala2JavaRunner MyClass1.scala MyClass2.scala
- To generate output to a directory:
java -cp scala2java-core_2.13-<version>-all.jar:<project_classpath> io.github.effiban.scala2java.core.Scala2JavaRunner --outDir=myDir MyClass.scala MyClass2.scala
-
Add the scala2java-core dependency to your project
-
To generate output to the console (Scala example)
import io.github.effiban.scala2java.Scala2JavaTranslator.translate import java.nio.file.Path class Translator { def doTranslate(): Unit = { val scalaPath = Path.of("myRootDir", "mypackage", "MyClass.scala") translate(scalaPath) } }
-
To generate output to a directory (Scala example)
import io.github.effiban.scala2java.Scala2JavaTranslator.translate import java.nio.file.Path class Translator { def doTranslate(): Unit = { val scalaPath = Path.of("myScalaRoot", "mypackage", "MyClass.scala") val javaOutputDir = Path.of("myJavaRoot", "mypackage") translate(scalaPath, Some(javaOuptutDir)) } }