Integrating Scala into an existing project in Java

17,840

Solution 1

I work on a mixed Java/Scala project right now (previously a Java-only project). Remember, there is no difference as far as the JVM is concerned between a .class file generated from javac vs. one generated from scalac.

For example: I implement Java interfaces and extend Java classes in Scala with no problems. I also instantiate Java beans and 'Scala' spring beans together in the same definition file (with scala beans having dependencies on java beans and vice-versa), and I have both Java and Scala beans coexisting together in a spring integration messaging pipeline.

The two languages inter-operate quite well, though where collections are concerned, you'll probably want to take a look at Scala's JavaConversions and JavaConverters objects.

For building, we use Ant (I'd personally prefer SBT for a new project, but if you're dealing with a pre-existing java project that uses ant, it's likely to be more trouble than it's worth to change build systems). To configure ant to compile scala files, have a look at this question.

Solution 2

I see that no one has mentioned David Bernard's scala-maven-plugin, formerly the maven-scala-plugin, mentioned in @richard-close's answer. I don't have extensive experience with it, but I have had immediate success with two Java projects (one fairly large, one small), so I figured it was worth posting this here — even though the question is somewhat dated now — as I arrived at this question via Google.

The Mixed Java/Scala Projects page should be able to get you going, though there are other interesting documentation pages as well. Just add the relevant sections shown here and try to compile your project. Don't make the mistake I did and try to use other configurations documented elsewhere with this one first: just follow these minimal config changes in your top-level pom.xml (or whatever makes sense if Scala will have limited scope in your project). Go here for an easier to copy & paste text (no '+'s showing additions).

<dependencies>
+       <dependency>
+        <groupId>org.scala-lang</groupId>
+        <artifactId>scala-library</artifactId>
+        <version>2.11.7</version>
+      </dependency>
</dependencies>
<build>
 <pluginManagement>
  <plugins>
+        <plugin>
+          <groupId>net.alchim31.maven</groupId>
+          <artifactId>scala-maven-plugin</artifactId>
+          <version>3.2.1</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <version>2.0.2</version>
+        </plugin>
  </plugins>
 </pluginManagement>
 <plugins>
+       <plugin>
+        <groupId>net.alchim31.maven</groupId>
+        <artifactId>scala-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>scala-compile-first</id>
+            <phase>process-resources</phase>
+            <goals>
+              <goal>add-source</goal>
+              <goal>compile</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>scala-test-compile</id>
+            <phase>process-test-resources</phase>
+            <goals>
+              <goal>testCompile</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>compile</phase>
+            <goals>
+              <goal>compile</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
 </plugins>
</build>

Be sure to use an updated version of Scala above if you are using Java 8 (i.e. Scala 2.11.x); some of the official docs may be slightly oudated.

One thing I noticed that the docs say you need to do but apparently don't need to do: you don't need to have your Scala sources in a separate directory, and can possibly leave them under the existing java directory of your project. This is convenient, and seems to work, but I do not know if there are side effects.

IntelliJ notes

If you happen to be using IntelliJ, don't forget to right-click on the maven module in your project view and 'Add Framework Support ...' to add the Scala Framework to the project. You will probably need to add the framework to each submodule you intend to use Scala in if you are using a multi-module project, not just the top-level module. Then, you should be able to autoconvert Java files to Scala files, accessible through the Refactor menu (though you will need to expect some manual fixes). This can give you a quick way to test the config, especially if there is some little Java class you can try first.

Caveats

@james-adam's comments about JavaConversions are also very important to be aware of. One issue I've realized when trying to integrate Scala with another JVM language (Kotlin) in a single project, is that things may not be that smooth due to how each language handles collections: they are both designed to work well with Java, but not necessarily with each other. I don't know the details, but this is a bit tangential to the question anyway.

Solution 3

This: http://scala-tools.org/mvnsites/maven-scala-plugin looks like a good way to integrate your Scala code into your Maven build, though I haven't tried it. (I use SBT, which does Scala/Java integration nicely, as well as IDE project creation (Idea & Eclipse) via plugins. You wouldn't want to change your whole build process, though).

Solution 4

Yes, you can have mutual dependencies between Java and Scala without problems.

Share:
17,840

Related videos on Youtube

SPIRiT_1984
Author by

SPIRiT_1984

The senior developer of ARRIAH

Updated on July 12, 2022

Comments

  • SPIRiT_1984
    SPIRiT_1984 almost 2 years

    we have a project written in Java. It is a maven project, that has jsp pages and a lot of java code:

    • servlets for handling user requests and dealing out responses.
    • classes of logic used by servlets in order to process the required logic.
    • classes of SQL generators used to connect to database and perform the specific queries required by the logic.

    Well, we are looking towards Scala. For example, we use mappers in order to get a collection of entities from the database and after that transform this collection, filter it and return to the servlet. That seems like a good thing to do in Java. The question is - how can I integrate that into an existing project? Can I use in my logic files written in Java some Scala classes that again use the mapper files written in Java?

  • David Leppik
    David Leppik over 8 years
    For what it's worth, Scala and Kotlin both analyze Java source code to resolve dependencies before compiling. That's how they can be mixed with Java so freely. Since neither Scala nor Kotlin can read the other's source code, it won't be possible to mix them willy-nilly within a project.
  • kennyg
    kennyg over 7 years
    Hey I know this is quite an old post but you mentioned Java 8 in conjunction with the scala-maven-plugin. I seem to be having issues getting this to work. "Failed to execute goal net.alchim31.maven:scala-maven-plugin:3.1.6:compile" I think its a compatibility issue with Java 8. Were you able to successfully get this to run?
  • kennyg
    kennyg over 7 years
    ah, nevermind. I needed to upgrade my scala dependency as well.
  • bartektartanus
    bartektartanus over 7 years
  • supriyo_basak
    supriyo_basak about 4 years
    Hi @kennyg, I am facing the same problem. Could you please tell what Scala dependency you used? I am using 2.11 and still getting the same problem.