Argument Transformation | MuleSoft Documentation
# Argument Transformation
Since Java Module version 1.1, this module transforms the arguments given to a Java invocation even if they don’t exactly match the type expected by the Java method. The Java module infers how to transform a parameter to what a method expects.
## When Are Arguments Transformed?
For each specified parameter, the Java module checks whether its type matches the type expected by the method for that parameter or not. If it is not what the method expects, the Java Module transforms it to what is expected.
## Simple Example of Argument Transformation
This is a simple example where one of the arguments is transformed.
The static method `min` from the `Math` class is called, but the class expects to receive two `int` parameters. The call is made with a Number and a String:
```
<flow name="calculateMinimum">
 <java:invoke-static class="java.lang.Math" method="min(int,int)" >
  <java:args>#[{
    'arg0': 5,
    'arg1' : "3"
   }]
  </java:args>
 </java:invoke-static>
</flow>
```

In this case `arg1` would have been passed as a string, but it is transformed into an integer before calling the Java method.
## Pass a Custom POJO to a Module as a Map
In Mule 3 when working with custom POJOs, users explicitly declared in the DataWeave expression what type the data to transform. In Mule 4, the Java module automatically recognizes the expected type for an argument and tries to transform the data to the expected type. (POJO stands for plain old Java object.)
In the examples that follow, a Map parameter is transformed into a custom POJO by the Java module.
  1. Define the `Car` class of the POJO:
```
public class Car {
 private String doors;
 private String wheels;
 private String engine;
 public String getDoors() {
  return doors;
 }
 public String getWheels() {
  return wheels;
 }
 public String getEngine() {
  return engine;
 }
}
```

  2. Declare the `describeCar` static method in the class to receive an instance of the POJO:
```
public class CarUtils {
 public static String describeCar(Car car) {
  return "This car has: " + car.getEngine() + ", " + car.getWheels() + ", " + car.getDoors();
 }
}
```

  3. Invoke the static method in the Mule flow:
```
<flow name="describeCarFlow">
  <java:invoke-static class="CarUtils" method="describeCar(Car)" >
    <java:args>
      #[{
      'car': {
        'doors' : "Four doors",
        'engine' : "120 Horsepower engine",
        'wheels' : "17 Inch chromed rims"
      }
      }]
    </java:args>
  </java:invoke-static>
</flow>
```

The Mule operation receives the `car` map whose key and values are mapped to a `Car` class instance. This map is transformed into an instance before the invocation of the Java method. Without this improvement, the invocation would fail, stating that the arguments passed to the Java method did not match its signature.


## Collections and Maps
The Java module checks that every element of the collection and every entry of the map honors the Java Generic declared by the method signature. If any element fails this check, the Java module creates the whole collection or map repopulates it with the transformed elements.
The Java method is called with another instance of the collection or map if a transformation is needed (not the same as the one passed in the Mule flow). This is particularly important if the method called is expected to add or remove elements in the collection or map, and the ability to reference this collection or map after the invocation is needed.  
---  
## Transform a List Example
The `List` given to the operation is transformed and a new `List` with the transformed items is passed to the Java method.
The `IntegerUtils` Java class declares the `sumNumbers` static method:
```
public class IntegerUtils {
 public static Integer sumNumbers(List<Integer> numbers) {
  return numbers.stream().mapToInt(i -> i.intValue()).sum();
 }
}
```

This Mule flow invokes the Java class:
```
<flow name="sumListOfNumbers">
 <java:invoke-static class="IntegerUtils" method="sumNumbers(List)">
  <java:args>
   #[{
    'numbers' : [1, "5", 4, "8", 3]
   }]
  </java:args>
 </java:invoke-static>
</flow>
```

The `numbers` list in the flow has two string objects (`"5"` and `"8"`), which the module transforms into integers.
## Transform a Map Example
A map for the operation is transformed and a new map with the transformed keys and values is passed to the Java method.
This Java class declares the `sumMapValues` static method:
```
public class MapUtils {
 public static Integer sumMapValues(Map<String, Integer> map) {
  return map.keySet().stream().mapToInt(i -> i.intValue()).sum();
 }
}
```

This Mule flow invokes the `MapUtils` Java class:
```
<flow name="sumValuesOnMap">
 <java:invoke-static class="MapUtils" method="sumMapValues(Map)">
  <java:args>
   #[{
    'map' :{
     'books': "22",
     'pencils': 33,
     'pens': 12
    }
   }]
  </java:args>
 </java:invoke-static>
</flow>
```

This map contains values that do not comply with the generics imposed in the Java method. Because of this, a new instance with the transformed key and values is used to call the method.
## Pass a Java Byte Array to a Method Example
Consider a Mule app that processes image files uploaded by users. To handle these files efficiently, you want to pass the image data as a byte array to a Java method for further processing. This example demonstrates how to configure the Java Module in Anypoint Studio to pass a byte array to a Java method, ensuring that the image data is processed correctly and efficiently.
  1. In Anypoint Studio, create a new Mule project and add an **HTTP Listener** to your flow.
This serves as the entry point for incoming file upload requests.
  2. Drag the **Set Payload** operation after the **HTTP Listener**.
  3. Select the **Set Payload** operation and for **Value** set this DataWeave payload:


```
%dw 2.0
output application/octet-stream
---
payload
```

  4. Drag the **Java Module Invoke** operation after **Set Payload**.
  5. Select the **Invoke** operation and configure it to call the Java method.
Make sure that the method signature accepts a byte array as a parameter.
  6. In the **Invoke** operation configuration, set the Method property to the name of the Java method you want to invoke, for example `processImage`.
  7. Map the incoming file data to the byte array parameter of the Java method.
You can use DataWeave to transform the file data into a byte array.
  8. Continue building your Mule flow by adding the logic for handling the processed image data, such as saving it to a database or sending it to another service.


In the **Configuration XML** window, the configuration looks like this:
```
<flow name="imageProcessingFlow">
  <http:listener doc:name="HTTP Listener" config-ref="HTTP_Listener_config" path="/upload"/>
  <set-payload value="#[%dw 2.0
output application/octet-stream
---
payload]"/>
      <java:invoke-static
        class="org.mule.extensions.internal.model.ByteArrayProcessor"
        method="processByteArray(byte[])"
        target="processedResult">
        <java:args><![CDATA[#[{bytes: payload}]]]></java:args>
      </java:invoke-static>
  <!-- Add additional steps to handle the processed image data -->
</flow>
```

## See Also
  * Java Module Examples