Scala macros: Generate factory or ctor for Java Pojo

110 views Asked by At

I'm currently working with reasonably large code base where new code is written in scala, but where a lot of old Java code remains. In particular there are a lot of java APIs we have to talk to. The old code uses simple Java Pojos with public non-final fields, without any methods or constructors, e.g:

public class MyJavaPojo {
    public String myField1;
    public MyOtheJavaPojo myField2;
}

Note that we dont have the option of adding helper methods or constructors to these types. These are currently created like old c-structs (pre-named parameters) like this:

val myPojo = new MyJavaPojo
myPojo.myField1 = ...
myPojo.myField2 = ...

Because of this, it's very easy to forget about assigning one of the fields, especially when we suddenly add new fields to the MyJavaPojo class, the compiler wont complain that I've left one field to null.

NOTE: We don't have the option of modifying the java types/adding constructors the normal way. We also don't want to start creating lots and lots of manually created helper functions for object creation - We would really like to find a solution based on scala macros instead of possible!

What I would like to do would be to create a macro that generates either a constructor-like method for my Pojos or a macro that creates a factory, allowing for named parameters. (Basically letting a macro do the work instead of creating a gazillion manually written helper methods in scala).

Do you know of any way to do this with scala macros? (I'm certain it's possible, but I've never written a scala macro in my life)

Desired API alternative 1:

val myPojo = someMacro[MyJavaPojo](myField1 = ..., myField2 = ...)

Desired API alternative 2

val factory = someMacro[MyJavaPojo]
val myPojo = factory.apply(myField1 = ..., myField2 = ...)

NOTE/Important: Named parameters!

I'm looking for either a ready-to-use solution or hints as to where I can read up on making one.

All ideas and input appreciated!

1

There are 1 answers

1
Paul Draper On BEST ANSWER

Take a look at scala-beanutils.

@beanCompanion[MyJavaPojo] object MyScalaPojo

MyScalaPojo(...)

It probably won't work directly, as you classes are not beans and it's only been made for Scala 2.10, but the source code is < 200 lines and should give you an idea of where to start.