How to use R scripts with Quarkus | Quarkify

Dmytro Chaban
Apr 23, 2020 · 4 min read
Image for post
Image for post

There’s a time when you need to call some R script from Quarkus. One option is to create microservice, but what if it’s something really small and you just want to call it in a single place without overwhelming project architecture. This is where GraalVM comes in. With GraalVm you can execute R scripts directly from Java without any conversion, microservices, or endpoints. We already have seen an example in Python, let’s see how to do it in R.

For better copy-paste experience please open this article on quarkify website

Setting up the environment

We’ll think that you already installed GraalVM, if not, follow this link. We’ll need to install GraalVM R interpreter:

Beside’s this command, we’ll need to install some local dependencies. For Ubuntu 18.04 it’s:

For Ubuntu 19.10 it’s:

Running R code in Quarkus

Now you’re ready to use the R language. Since our Cohen’s D example in Python can be done with one line in R, we gonna use something more interesting in our case, let’s build logistic regression that will identify when we need to enable CPU cooling. In our case, we have the next simple dataset

Image for post
Image for post
Some entries omitted, please have a look R script to see full dataset

If you look at dataset, you can see that we “manually” enabled cooling when CPU was above 60 grad. Let’s build a service that will predict for us when we need to enable it. We gonna start with next R code:

This super-simple piece of R code will train logistic regression and after that predict if the CPU should be cooled at 40 grad.

Create Quarkus project

If you’re lazy to write code, clone our project from github Let’s create simple Quarkus app and connect it with our R code.

Once it’s created, put our R code into file at src/main/resources/cpu_cooling.R that was provided above.

Now, let’s modify our resource, open src/main/java/tech/donau/quarkify/CpuCoolingResource.java and put next code provided in a gist.

What we just did is that we created polyglot Context, and executed our cpu_cooling.R. Since our R code outputs prediction as the last output, we can use return Value. Value is a universal wrapper for any output, with which you can specify what type you want to get, since our R code outputs double, we called Value::asDouble. If the value is more then 0.8(or 80%) we say that we. Just imagine how many lines of code you saved for keeping logistic regression in R code. Let's start our service.

Start and test

Now, let’s call our endpoint by using curl (or browser)

As you can see, in our R code we specified that we want to predict whether we want to enable cooling for 40 grads. Because our network trained on dataset that returns true close to 60 grads, 40 is out of range.

Executing R functions from Java

In previous example, we only used simple script without any input and output. Let’s slightly modify our cpu_cooling.R script so that we'll have a function that we can execute if needed. If you use cloned repo, execute git checkout feature/input

Now, we can use needs_cooling function from Java. Let's rewrite CpuCoolingResource.java a little bit.

In new version, we moved execution of our R code into startup event listener onStart. This will fix our long waiting time to execute first call. We also got R function directly from context and executed it. You can see how easy it is, even if we'll compare with Java's reflection API, it looks a lot better. Let's play around with our new code. If you stopped quarkus server, re-run it again with ./mvnw quarkus:dev.

curl http://localhost:8080/cooling?grads=64
# Enable cooling

As you can see, our trained model in R outputs correct results, and, for data provided, it starts to say that we need to enable cooling starting from 51 grads. You can also see how fast it is.

In conclusion

If for Python you have a limited amount of supported libraries, R can be used almost with no limits. This provides production-grade integration between Quarkus and R. Example that was provided in this lecture was specifically designed to show understandable example, you’re not limited to simple functions and computations.

Note, however, that our example is not ready for production, and there’s more stuff to do, which is a topic of the second article 😉

Have you ever integrated any two languages between each other without using rest or socket communication? How hard was it? I would love to exchange some experience on this topic 🙂

Originally published at https://quarkify.net on April 23, 2020.

Quarkify

Latest Quarkus Articles, Tutorials and News

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store