18

I want to create a multi-module (maven) spring MVC application, with modules like:

web
persistance (hibernate)
core (general libs)
models
job-server (queue based jobs)
services (business logic)

Now to use Scala in this project, can I write scala everywhere without any problems? Or should I use scala for my services module, and java for the web module?

I know hibernate will have to be in java.

Thoughts? Advice?

Are there any issues to look out for? Is this a good idea? Will I have to hack certain parts to glue them together?

loyalflow
  • 14,275
  • 27
  • 107
  • 168

2 Answers2

17

Yes, you can use Scala for both your Spring MVC code and your Hibernate classes.

Here is an example of a Spring MVC Controller in Scala taken from one of my projects:

@Controller
class HomeController {
  val log: Logger = LoggerFactory.getLogger(this.getClass.getName)

  @RequestMapping(Array("/"))
  def home: String = {
    log.debug("HomeController::home")

    "home/home"
  }
}

And an example of a Hibernate domain class. Note the use of private Java collection classes for Hibernate adapted by public Scala collection classes for users of the class (helped by Scala's JavaConversions class).

@Entity
class Role {
  @Id @GeneratedValue
  var id: Long = _

  @Index(name="role_name")
  var name: String = _

  var created_at: Date = _
  var updated_at: Date = _  

  @ManyToMany
  private var sub_role: java.util.Set[Role] = _
  def subRoles: Set[Role] = {
    if (sub_role == null) sub_role = new java.util.HashSet[Role]
    sub_role
  }

  @ManyToMany
  private var permission: java.util.Set[Permission] = _
  def permissions: Set[Permission] = {
    if (permission == null) permission = new java.util.HashSet[Permission]
    permission
  }
}

The only thing I've found that I've had to use Java for is writing @Retention(RUNTIME) annotations (for JSR-303 validations).

I use Maven and the maven-scala-plugin with mixed Java/Scala projects.

sourcedelica
  • 23,940
  • 7
  • 66
  • 74
  • Is there a manual about how use scala and Spring? Yes we can use Spring with scala, but what about nuances? – Cherry Jun 25 '14 at 06:42
  • What the... please don't write Scala code like this. Ever. :( – Andres F. Nov 28 '15 at 18:43
  • 1
    Could you be more specific? How would you write Hibernate code in Scala? – sourcedelica Nov 29 '15 at 14:36
  • 1
    I wouldn't. Specifically, I wouldn't choose Scala if using Hibernate was a requirement; and if it wasn't a requirement, I would drop Hibernate. As for Scala: don't use `var`, don't instantiate `java.util` collections, don't use `JavaConversions` unless you have to (for example, because you're calling a Java API), don't explicitly check for `null` in Scala code, etc. What you did here is indeed "using Hibernate", but it's not "effectively" using it -- in order to use it, you dropped all that makes Scala code look like Scala! – Andres F. Nov 29 '15 at 14:47
  • 1
    My answer was addressing the case where you need to use both Scala and Hibernate together. That is a regular requirement in many places. When using Scala and Hibernate you need to use `var` and you need to use `java.util`. Have you used Scala and Hibernate together? – sourcedelica Nov 29 '15 at 19:42
  • @sourcedelica Yes, I worked with a team that tried Hibernate + Scala. In the end, it wasn't a good fit, and they decided to keep Hibernate and drop Scala. You won't find many teams using both technologies, and for good reason: in order to use Scala with Hibernate, you must turn Scala into a monstrosity it was never meant to be. You *can* do it, but you *shouldn't*. – Andres F. Nov 30 '15 at 01:40
  • Ok, in your opinion you shouldn't. But if we asked Martin Odersky about it he would say it's all good. The Hibernate code is going to be a small fraction of your overall codebase. Sure, it won't be idiomatic Scala but it will be idiomatic Hibernate. And there's advantages of not having a mixed Java/Scala codebase. I've been on a number of projects where we've used both Scala and Hibernate and it's worked great. – sourcedelica Nov 30 '15 at 04:01
  • 1
    I certainly would hate to be on a project where we had the opportunity to use Scala but some zealots decided that since the Hibernate code wouldn't be idiomatic Scala the whole project would have to be done in another language. – sourcedelica Nov 30 '15 at 04:04
  • @sourcedelica You don't know what Odersky would say because you're not a mind-reader. It's ok in some cases to make compromises, but I contend that if your compromises include using a highly invasive framework such as Hibernate, which leads you to write non-idiomatic Scala code (plenty of no-nos in your snippet), then you should really consider ditching either Hibernate or Scala. If your project is *greenfield* why on Earth are you picking Hibernate? Learn the right tool for the job! If your project is legacy, *I highly doubt* migrating the Java portions to Scala is a good idea. – Andres F. Dec 01 '15 at 19:55
  • I know what he would say because I've heard him talk on the subject plenty of times: Scala is a hybrid language - it has support for imperative, mutable code because sometimes that is what is required. In the real world you don't always have choices in the technology to use because there are company or department standards that have to be followed. Or maybe the project is greenfield but it has to integrate with legacy code. Or, more frequently, a team wants to start using Scala but wants to keep using the rest of their stack because they still need to ship product. – sourcedelica Dec 02 '15 at 16:52
  • It is a poor technical decision to take a team who has never used Scala before and force them to not only learn Scala, but also a whole stack of "idiomatic" libraries (which may or may not be stable). That's a recipe for disaster. You have to adopt a gradual approach. Re: Odersky, I'll be at ScalaDays in May, I'll ask him and report back. – sourcedelica Dec 02 '15 at 16:58
3

You can use scala & java together for whatever you think each works best for.

I know hibernate will have to be in java.

This isn't necessarily true. You can use scala classes as Hibernate ORM objects. You just have to make sure that the compiled .class files end up with the same getters, setters, and default constructor that Hibernate expects.

Even your Web App module can be written in scala. The controllers just need to abide by the contract which Spring MVC expects.

In general, almost anything written in Java can be re-written in scala. Of coarse there are exceptions but don't per-maturaly limit yourself from trying. Assuming your existing code dones't do anything to crazy (i.e. black-magic reflection), it should be fine.

The interesting question here is how to get it working with Maven...

There is an existing SO question which describes using the maven-scala-plugin to get this kind of project working (multi-module with mixed scala and java resources). The only extra comment I will add to this solution is that, in my experience, we could only get it working with scala modules being dependent on java sources, not the other way around. This was because our maven config used the java compiler and scala compiler seprarately. In theory, the scala compiler can compile Java files too so if you configured it to just use one compiler for everything, you wouldn't encounter this limitation.

EDIT:

Blankman commented:
@Jesse so you have done this also then? not sure I understood the maven issue.

Yes, I have worked on a couple projects which have used mixed java and scala sources. We didn't use Scala for the Hibernate layer but we did for everything else.

The maven issue I am describing was a consequence of our maven-scala-plugin configuration. You have to configure it to know how to compile your scala files. Our configuration (probably not correct) was setup to compile java files first, using javac, and then compile scala files, using scalac. This meant that we weren't allowed to write java code which referenced scala classes because they wouldn't not be available at compile time. With the proper configuration, it should be possible to use the scalac compiler to compile all your sources together which will remove this awkward restriction. The SO question I linked to above has example configuration as well as some discussion about the compile time issues I am talking about. If you need more reference for setting up the plugin, check out the plugin's website (also linked to above) for the official doc.

Community
  • 1
  • 1
Jesse Webb
  • 43,135
  • 27
  • 106
  • 143
  • 2
    When using Scala with Hibernate, you have to keep in mind that you need to use the `java.util` collection classes instead of the Scala collections. – Madoc Jun 26 '12 at 20:57
  • 1
    @Madoc thanks, it's little things like that I was hopping to learn from thanks! – Blankman Jun 26 '12 at 22:51
  • @Jesse so you have done this also then? not sure I understood the maven issue. – Blankman Jun 26 '12 at 22:51
  • @Jesse - You don't necessarily have to provide getters and setters - JPA can go against fields directly. Also the Scala compiler can't actually compile .java to .class files, but it does know how to parse Java as needed so it can understand the structure of Java source classes. – sourcedelica Jun 27 '12 at 02:00
  • 1
    @sourcedelica - Yes, you are correct. The javac compiler would most likely still need to be run after, but at least the scalac compiler will not blow up with your scala files reference uncompiled java classes. We (unknowingly) did the opposite: compile java first. For more info on using scalac in this regard, even with a section on describing getting it working in maven... http://www.codecommit.com/blog/scala/joint-compilation-of-scala-and-java-sources – Jesse Webb Jun 27 '12 at 15:00
  • Would the down-voter care to comment to help me improve my answer? – Jesse Webb Jun 27 '12 at 16:32