Generate Java code from Scala

1,352 views
Skip to first unread message

trylks

unread,
Apr 21, 2015, 1:46:34 PM4/21/15
to scala...@googlegroups.com
Paradoxically, I have found lots of discussions on the Internet about this, too many, starting with a thread in the old Scala forum. I have also noticed a trend of people asking for this and then giving up and using some workaround, mostly 5 to 3 years ago.

AFAIK, there is no standard or direct way to generate Java code from Scala code. However, Scala code can be compiled into Java bytecode (quite standard process), and Java bytecode can be decompiled into Java code again, thus generating Java code. 

As far as I could see, there are quite a few tools for this, and I guess they may work with varying degrees of success. I would like to know the current state of the art in this, if possible. Systematically testing all possibilities, with different Scala programs, checking the results, etc. would take very long. I hope the community knows enough to guide that search, ideally enough to avoid that search, or perhaps someone has already done that and can pinpoint a solution.

In particular, I am interested in:
  • Generating Java code that works, readability is always good but secondary in this case.
  • Using a good (free at least as beer, if possible as speech) tool that generates good Java code, there are quite a few. A nice feature would be a command line mode, but the previous point is the most relevant aspect.
  • Setting the best flags in scalac to make the decompiler job easier (so here we have a combinatorial explosion with the previous point). One flag may be -g:notailcalls, the target Java version may also be relevant.
  • I don't mind restricting myself from using some Scala expressions that may cause trouble.
I think this is a recurrent question, so maybe we can put together the knowledge that each one has extracted so far, any contribution, no matter how small, is welcome. In the end there may be several solutions that may be better or worse suited for different tasks, and having that information would be quite useful IMHO, as there isn't much usable information on the Internet, but mostly people discussing that it's very hard, maybe impossible, but the point is: what can be done, how far can we get, what is the current state of the art. Apparently something can be done, but that's as much as I know.

Thank you, and sorry if there's anything wrong with my post, this seems to be a bit of a taboo lately.

Oliver Ruebenacker

unread,
Apr 21, 2015, 2:39:55 PM4/21/15
to trylks, scala-user

     Hello,

  Decompiling Java byte code to Java source code is often unsatisfactory and sometimes impossible (bytecode can do some things that Java can't).

  A more viable approach may be using Scala compiler to parse Scala source into a syntax tree, then type it, and then convert to Java. Looks straight-forward, but is a lot of work.

  Either way, you would still be using the Scala standard library - none of the above approaches gets rid of it.

  You may also consider whether it is worth translating code such as:

  case class Person(first:String, last:String)
  Seq(1, 2, 3).map(2*_)
  val (x, y) = if(true) (1, 2) else (3,4) 
  val y = a*x*x + b*x + c  // Let's assume these are matrices, not primitives

  Why would we want to convert Scala source to Java source? In most cases, you can treat Scala source as if it was already Java source. Java can call Scala methods and Java programmers can very quickly learn most of the Scala syntax.

     Best, Oliver

  


--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Oliver Ruebenacker
Solutions Architect at Altisource Labs
Be always grateful, but never satisfied.

trylks

unread,
Apr 23, 2015, 12:12:58 PM4/23/15
to scala...@googlegroups.com
Well, nothing of this is technical in any aspect, so I preferred not to mention anything about it, but the discussion diverts again to avoiding the Scala translation into Java (e.g. embrace Scala, forget about Java), and I don't think that is going to be really useful for me, so I'll clarify everything (after all, that's why I'm very deliberately using a pseudonym).
 
Why would we want to convert Scala source to Java source?

For plenty of reasons. In my case, the situation is:
  • I'm working in a big project.
  • We all commit to the same SVN. I'd prefer to have separate repos for the current configuration, but there's nothing I can do about that.
  • Nobody messes with someone's else code. I don't think anyone reads or even cares about someone's else code, as long as it doesn't cause trouble to theirs.
  • Scala dependencies are already there, because some other library needed them. Guava and Groovy are also there.
  • Committing source code is fine as long as it can be compiled and everyone else can keep working smoothly with their Eclipse configuration and such.
  • Adding jar dependencies is feasible but annoying, and should be avoided if possible at all. Not all partners can do this, only one, and in principle it should be done once for each library, which should be stable, not the stuff we are developing.
  • Committing source code in anything but Java is not permitted, as people are using Eclipse without support for Groovy, Scala, Clojure...
Therefore, if I could put the stuff into Java then nobody would be annoyed and everybody would be able to work without problems or inconveniences caused. Then, for convenience reasons, the releases could use jars instead, instead of ugly Java code, which is anyway not meant to be read. The Scala code would be accessible for people in the project, but as far as I know, nobody cares. I actually asked to people responsible for this, nobody I asked cares about the code, just having something that works, in fact, the point is producing something that seems to work (it doesn't even need to really work). Some partners may appreciate it just as much as any other code they may read, and they would probably prefer not to read it, because life is short.

In short, I think decompiling Scala jars is the best solution, definitively much better than using Java, and also fairly better than using Xtend, which I am considering as well and may have better results in the end.

I know there are some situations in which Java bytecode cannot be translated into Java, but most probably I still prefer a crippled Scala to Xtend and Java, depending on the features that I should avoid not to generate such a code. Maybe it's @tailrec (the magic there is suspicious), or maybe something else, I don't know, but that would definitively be interesting if someone has taken a look at it and made a list (which I couldn't find so far).

Java programmers can very quickly learn most of the Scala syntax.

Only a few of us are interested on that, precisely the ones that are trying to escape the project and get a new job. I would qualify this as a toxic environment, but please don't get me started on that. In my personal case, the sooner I finish a bunch of work, the sooner I will be able to escape, with everyone happy, recommendation letters, etc. (hopefully the cake is not a lie), and Scala could be a great help to get everything done ASAP. Otherwise, I think I'll use Xtend, the problem is: I've to learn Xtend (and be proficient in it), and (more importantly) there are many things in Scala that are not-so-convenient in Xtend-Java land, e.g. implicit definitions and parser combinators.

Finally, about converting the Scala AST to Java code, that's way beyond what I can do, definitively not an option for me.

Thank you.

Oliver Ruebenacker

unread,
Apr 23, 2015, 1:14:51 PM4/23/15
to trylks, scala-user

     Hello,

  Why don't you do this:

  - Create an API for others to use in Java, commit the source code.
  - Package the API as a JAR.
  - Add API JAR to separate project, implement the API using Scala, compile and package implementation as JAR files.
  - Add the implementation JAR file to the common project and commit it.
  - Add Java code to common project that calls the implementation (e.g. a factory method), commit that Java code.

     Best, Oliver

trylks

unread,
Apr 27, 2015, 1:49:09 PM4/27/15
to scala...@googlegroups.com, try...@gmail.com
That would be cool, and it's feasible but not that easy. Due to this step:

 - Add the implementation JAR file to the common project and commit it.

For this reason:
  • Adding jar dependencies is feasible but annoying, and should be avoided if possible at all. Not all partners can do this, only one, and in principle it should be done once for each library, which should be stable, not the stuff we are developing.
This implies that updating a jar may take a few days instead of a few minutes, depending on the attention that the person receiving the e-mail is paying to this (or whether he is on vacations).

I have thought of all these workarounds, but I don't think that any will work for me, and it's really sad because using jars and Java interfaces completely solves the problem from a technical point of view, but I'm afraid this is not that much of a technical problem but an organizational problem (a disaster, I'd say).

Thanks a lot in any case.

Oliver Ruebenacker

unread,
Apr 27, 2015, 2:02:03 PM4/27/15
to trylks, scala-user

     Hello,

  In most cases, projects are set up in such a way that if one party adds a JAR and SVN commits it, the others need just SVN update and then they have it, too. 

  This is accomplished by either committing Eclipse project configurations (including classpath), or by committing build definitions (e.g. SBT config files) from which Eclipse project configurations can be generated automatically.

  If neither of these is done in your place, that is unfortunate, of course.

     Best, Oliver

Ryan Tanner

unread,
Apr 27, 2015, 5:59:36 PM4/27/15
to scala...@googlegroups.com
I apologize that this is harsh, but I think there are only two realistic options:

1. Write Java (that's what the higher-ups want anyways)
2. Quit

Any in-between seems unfair to the rest of the organization, since presumably someone, someday, will have to maintain whatever you write, right?  While the organization you've described certainly sounds dysfunctional and I can understand why you may not be too interested in their future, people have long memories and it's most likely in your best interest not to burn bridges by delivering something others can't understand or that doesn't meet the requirements (assuming "use Java" was a requirement).

I know this isn't the answer you want, but ultimately this isn't a technical question, it's a political one, so I say crack open your copy of Effective Java, use what you can from Guava and Groovy and just bite the bullet so you can get out of there.
Reply all
Reply to author
Forward
0 new messages