Mixing Scala and Java — Invoking currying functions from Java
So…. you want to start trying out Scala. But you are stuck with legacy Java code. You can rewrite your code one class at a time or one flow at a time. But, if you don’t have the time to do so you can just invoke new Scala classes functions from old Java classes. Scala and Java are interoperable, however, the interoperability is not always straight forward. One example is when you want to invoke currying function from Java code.
What is currying function?
It’s not related to Indian food or an NBA superstar, if that’s what you think.
I won’t get into details about currying or higher order functions but a definition and good examples can be found in Alexey Zvolinsky’s article:
Example time:
Let’s say I have old legacy service that does something:
public String doSomething(UUID userGuid) {
log.info(“Yeah, you did it” + userGuid.toString());
return “Great success”;
}
Now, there is a cool service which you wrote that checks authorization for a certain user. The new authorization service is written in Scala and takes advantage of currying function to implement the following logic:
If the user is authorized invoke a function of your choosing — in our case doSomething. If not authorized throw an exception.
The authorization service might look something like this:
trait AuthorizationService {
def authorizedFor[T](
userGuid: UUID,
permissionToBeChecked: String)
(doSomething: AuthenticatedUserInfo => T): T}
The code that does the actual authorization might look something like so:
def authorizedFor(userGuid: UUID,
permissionToBeChecked: String]):
AuthroizedUserInfo = { if(“WRITE_PERMISSION” == permissionToBeChecked &&
userGuid ==
UUID.fromString("00000000-0000-0000-0000-000000000000"
) {
AuthrizedUserInfo(“howdy@doodie.com”)
} else {
throw UnauthorizedException(
s“””$userGuid not authorised for $permissionToBeChecked “””)
}}
Note, that your authorization service returns data about the authorized user AuthroizedUserInfo. If you wish, you can to use that information in your original method doSomething.
So how can I invoke it from my old java code?
Java 8 reintroduced the concept of SAM interfaces as Functional interfaces. Scala has extended the interface as a bunch of abstract classes: AbstractFunction0, AbstractFunction1, AbstractFunction2.. AbstractFunction22. Basically, each class represents a function with a set of input parameters:
AbstractFunction0 — zero input parameters
AbstractFunction1 — one input parameter
...
AbstractFunction 22 — 22 input parameters
Putting it all together
public String doSomething(UUID userGuid) {
Object result = authorizationService.authorizedFor(
userGuid,
“WRITE_PERMISSION”,
new AbstractFunction1 <AuthenticatedUserInfo, Object > () {
@Override
public Object apply(AuthenticatedUserInfo authenticatedUser) {
log.info(“Yeah, you did it ” +authenticatedUser.email()
);
return
“Great success”;
}
}
);
return (String) result;
}
Enjoy!!!