2
votes

Working on some scala software in IDEA IntelliJ. (It also features Android if it is essential). Suppose I have two projects:

P1, written in scala, uses sbt as the build tool

P2, written in java, uses gradle as the build tool

I want to call some code from P2, having its full source. So I import P2 as a module in my IntelliJ scala project. But when I compile my sbt project using sbt-shell, it tells me an error that it cannot find any definitions of classes and packages declared in P2. I guess I need to create a proper reference in my build.sbt file so it could understand where the definitions come from. I've found one solution which suggests adding unmanaged java source paths to build.sbt like so:

unmanagedSourceDirectories in Compile += file("mydependency")

but thing is that dependency has dependencies itself. When I try to compile that, sbt tells me that it cannot find definitions of that dependency. So I need a way to reference full java project in build.sbt so that I could then compille whole thing via sbt shell (in fact, I forced to use the very sbt shell).

Any suggestions?

4
It seems like an easy problem to solve with Maven: Package the Java project as a JAR and make it a Scala dependency. It's a two step process, but it'll work. - duffymo

4 Answers

3
votes

Per my understanding, better (but different) solution would be to publish jar in your local repository (e.g. publishLocal), and depend on it.

2
votes

When I try to compile that, sbt tells me that it cannot find definitions of that dependency.

Two possible solutions I see: add those dependencies in your build.sbt project or as suggested build the gradle project separately, publish it to your local repository (or local folder) and reference it from sbt project.

1
votes

Possibility three - define a multi module SBT project for both of your projects, and manage the java project also within sbt. This is a tedious solution, however, as you have to maintain two different build files, so this is only useful if you intend to switch whole hog to SBT.

Otherwise the "publishLocal" solution is probably the least painful.

1
votes
  • P2/Java: put it under Maven, install it into your local maven repository
  • P1/Scala: in build.sbt add an Library Depdendency to P2/Java, e.g. libraryDependencies += "xyz" % "xyz" % "xyz". Now all dependencies of P2 are also accessible in P1
  • As an option for "more convenience": IntelliJ allows you to add an Project Structure (F4) Module Dependency to an separate Java module. If you combine the both things above, you can change P2, and those changes are reflected instantly in P1. Otherwise you would have an binary maven/jar reference, and any change in P2 would need a maven publish, which is not convenient if you own both source bases P1 and P2 and change a lot both of them. Side note: Any refresh on build.sbt would remove this explicity added IntellIJ-project-struture-module-dependency to P2. So I propose to turn sbt auto-import off in Intellij and the dependency is kept any time you restart IntelliJ