Hello.
From time to time from Java developers who learned about the existence of Scala, the questions “How to start using Scala in an existing Java project? Is it difficult to move from one to another? How long will it take? How to convince the authorities? ”In our project, just such a transition took place, today almost the entire project is already on Scala, so I decided to share recipes and impressions.
How it all began, it is “Why do I need it at all?”:
- I wanted to learn something new and useful in production;
- I was tired of writing a lot of letters in Java, but I didn’t want to rewrite everything radically, say in Python;
Given these desires, the choice fell on a review of alternative JVM-based languages.
After the review, we stopped at Scala. I liked the compact syntax, strong typing, the ability to write in OO-style and the declared good interaction with the Java-code in both directions. The fact that Scala is already actively used by such large companies as Twitter, LinkedIn, Foursquare, and so on, inspired some confidence in the future of the language.
We already had a project on Maven with unit tests on JUnit, so it was important to easily enable Scala without significant costs for adapting the infrastructure.
So, in order.
How long will it take?
The general impression for those who doubt whether it is worth starting this process is to switch to Scala and study it
gradually absolutely real . Before the first practical application of time will be short, I would say a day or two, because at first it may even be just "Java with val and without semicolons." Time will pass, and gradually you will suddenly find a bunch of bonus methods (hello implicit) from where it came from, begin to use functions, closures, case classes, pattern matching, collections and so on ... Honestly, straight gradually, without interrupting everyday work.
How to start using Scala in an existing Java project?
First we add Scala support in the parent pom.xml:
<project> ... <properties> <version-scala>2.10.3</version-scala> </properties> <dependencies> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> <version>${version-scala}</version> </dependency> </dependencies> <build> <pluginManagement> <plugins> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>3.1.6</version> <configuration> <scalaVersion>${version-scala}</scalaVersion> <args> <arg>-deprecation</arg> <arg>-explaintypes</arg> <arg>-feature</arg> <arg>-optimise</arg> <arg>-unchecked</arg> </args> </configuration> <executions> <execution> <id>scala-compile</id> <phase>process-resources</phase> <goals> <goal>add-source</goal> <goal>compile</goal> </goals> </execution> <execution> <id>scala-compile-tests</id> <phase>process-test-resources</phase> <goals> <goal>testCompile</goal> </goals> </execution> </executions> </plugin> </plugins> </pluginManagement> <plugins> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Further ... and although not, that is all.
Now
mvn compile
will compile all .scala sources located in src / main / scala (however, those located in src / main / java will also be collected). You can also write JUnit tests on Scala and run
mvn test
. Important note to this plugin:
mvn test
will collect and execute only those .scala tests that are in src / test / scala,
otherwise they will be ignored altogether . Therefore, immediately put your .scala in src / (main | test) / scala /. As for Gradle, as far as I know, there are no problems with Scala support either.
')
Generally speaking, recently the SBT (Simple Build Tool, in fact, like Gradle, only in Scala) has become the de facto standard for Scala projects. The transition to SBT in my opinion will make sense when you need for example ScalaTest, ScalaCheck, Specs and so on, since SBT integrates natively with them, but no one imposes them on you. We have not switched to SBT, its advantages have not yet outweighed the need to shake up the structure of projects and their configuration.
As for IDE, we are working in IntelliJ IDEA, and it’s enough to enable Scala support in the settings (File → Settings → Plugins → check Scala). After rebooting for all modules, a Scala-facet configured from the pom will be added, and it will be possible to build the IDEA itself without Maven. Plus, if you want to rewrite some class from Java to Scala, then IDEA has the ability to convert, select “Convert to Scala” in the menu for .java files, or simply open .java and press Ctrl-Shift-G (. The java source will remain in place, which is useful as a reference for comparing and doping the converted code, then it needs to be deleted). As for Eclipse, there is a
corresponding plugin .
Is it difficult to move from one to another?
For us, the answer was “no”, but where it’s completely without complications:
- since there was no
for(;;)
and break
we had to thoroughly recycle some complex cycles. However, this only benefited, since the code became cleaner and clearer. break
can be temporarily compensated using scala.util.control.Breaks
; - sometimes it was still difficult to use Scala from Java in view of the richer type-system in Scala, or lack of Java analogues of Scala traits with implementation, or lack of checked exceptions (in Scala code, the compiler will be silent as a partisan, but let's say to force Java code see checked, Scala has the
@throws[SomeException]
annotation, which tells the compiler to generate the byte code with throws); - not quite difficult, try with resources is missing (for those who have Java 7), which, however, is easily replaced by loan pattern, that is, a function of the form ...
after which you can use it in code
package ru.habrahabr.hello ... val maybeSomeResult = using (Files.newBufferedReader(…)) { reader =>
How to convince the authorities?
I'm not going to sing Scala, I’ll just describe the real dividends that we received:
- It became much less letters. Specifically, in our project, even a simple conversion of sources with small quick modifications gave a decrease in the number of lines by an average of 25%, and in total about 9 thousand lines out of 37 thousand disappeared. These are exactly the lines, the letters themselves are even smaller. Obviously, fewer letters means faster solving problems and easier to find errors. The ability to write classes in one line generally tears down the roof at first;
- the richest library of collections with a bunch of methods saved a lot of routine work with cycles. All of these map filter find forall exists min par etc. etc. just hints at returning to java (one only par is worth it). All this wealth complements the immutable-collections, which are so lacking in the JDK (in which
Iterable
does not have size, the Collection
already has an add, Collections.unmodifiable…
only adds fool protection but does not protect against misuse). In my opinion, even just for the sake of this library, it is worth exploring Scala (however, the JDK has a wide choice of productive concurrent collections); - the expressivity of the code has increased, especially we often use
Option[T]
which in the simplest case solves the problem of checks for null (read, associated bugs); - The higher order functions and the other functional component of Scala again make it possible to write shorter, expressive and reusable code (in Java 8 some lambdas will certainly be a little consolation, but they still have to wait);
- implicit conversions in moderation allowed us to avoid code littering with all sorts of wrapping classes;
==
in Scala it is like Objects.equals(o1, o2)
in Java, goodbye random link Objects.equals(o1, o2)
however, if that’s what you need, there is eq
and neq
);- good interaction with Java lies in the fundamentals of Scala design, so the integration of all Java frameworks (Spring, Hibernate, etc.) is quite painless. For example, there is a bunch of annotations like
@BeanProperty
, which tells the compiler to generate getters and setters for the field in the style of JavaBeans.
Learning Scala is likely to be the whole team at the same time, so if suddenly one of the developers decides to leave the team, the team will still have enough experience to quickly teach new developers.
So, if we briefly describe the result, then “less letters — fewer bugs — more productivity”.
Since the transition to Scala, the new Java code has not been written anymore, this was the point of no return.
I would like to repeat again, it is not at all necessary to allocate a lot of time for training (as an option for the authorities, “it is not necessary to allocate a lot of money”).
PS: there is an opinion that Scala is complex and does not suit most Java developers (see the translation on Habré here
habrahabr.ru/post/134897 ), but in my opinion the Scala’s input threshold is small, the language doesn’t force to throw into the pool and thoroughly to study it before practical application, but it can bring benefits quickly enough.
Useful resources: