Last Updated on 03/05/2021 by Patryk Bandurski
I have already presented how to call Java code using event processors with the newest Java Module for Mule 4. For earlier mule’s version Entry Point Resolvers were used to invoke custom Java code. However for scenarios when we would like to use custom code in DataWeave, for transformations, another approach is needed. The approach presented in this article will be more concise comparing to using Java Module. It is highly extended comparing to the possibilities of the Mule 3 version. Mule 3 allowed to invoke static methods. In contrast, Mule 4 not only allows to call static methods but also instantiates classes and access its instance attributes.
Invoke a method
Below I have attached the DataWeave code responsible for converting an array into a list. To perform conversion I will use the already existing asList static method in the Arrays class.
%dw 2.0
import asList from java!java::util::Arrays
output application/java
---
asList(["Santa Clarita Diet", "Grimm", "Harry Potter", "Under the dome", "Penny Dreadful"])
To perform call on any class first we need to import it. In order to do this import keyword is used.
As you can see we need import from java! statement. After that, we provide a full path to the class that we are importing. In contrast to the java way, as a separator two colons are used. The last part must be the class name. We are not able to perform import of the whole package. Only class is permitted.
In our example, I have imported the Arrays class from java.util package. During import, I was more specific and I chose only the asList method to import. If I would not specify anything between import and from keywords all methods would be available.
asList method accepts an array of any type. As you can see, DataWeave nicely converted it to a java array. Some of you may be aware that asList also accepts a list of parameters that are treated as an array – varargs. However, this feature is not supported.
Below I have imported all methods from Collections class.
%dw 2.0
import java!com::ambassadorpatryk::utils::Collections
output application/java
---
Collections::intersection(vars.firstList, vars.secondList)
At line 5 you can see that in order to use static interasection() method I added before class name and separated it with double colons.
Create an instance
Creating an instance is a very simple process, that is similar to invoking a method. I have prepared an Item class with two constructors. Notice that we have one private attribute called value and one public method toUpper().
package com.ambassadorpatryk.utils;
import java.nio.charset.Charset;
import java.util.Random;
public class Item {
private String value;
public Item() {
byte[] array = new byte[7]; // length is bounded by 7
new Random().nextBytes(array);
String generatedString = new String(array, Charset.forName("UTF-8"));
this.value = generatedString;
}
public Item(String value) {
this.value = value;
}
public void toUpper() {
this.value = value.toUpperCase();
}
}
In order to instantiate it and get value variable in Java I would code something like
new Item("How I met your mother").value
Below as you can see I used a class name Item and called the constructor using ::new
construct. After that value is returned. Please notice that in order to get attributes I used dot instead of double colons.
%dw 2.0
import java!com::profitonilne::utils::Item
output application/json
---
payload ++ [Item::new("How I met your mother").value]
You need to be aware of the fact that we are able to instantiate a class and get its attribute but we are not able to call any non-static method at all. We would not be able to do something like that:
Item::new("How I met your mother")::toUpper()
Summary
Importing and using Java code within DataWeave is straightforward. You can import all methods or only interesting ones using the import keywords in the header section. DataWeave behind the scene performs all conversions to java constructs that are required by the method’s parameters. In comparison to using Java Module, it may be even simplified while you do not need to add your class manually to the mule-artifact.json file. I found it very interesting that the DataWeave engine was able to enter private variable without any setters and getters and return it. It is a pity that we are not able to chain calls of methods and instance methods. However, I rate this feature high 🙂 as it simplifies java calls in DataWeave.