---
schema_version: "1"
id: 7e84f25a6d4de475ad5fa4d56d8227a9cb4315ce9954e52988b9a2f11dddf4b6
title: Argument Transformation
collection: mulesoft
version: current
locale: en-us
portal_url: https://docs.salesforce.com/mulesoft/current/en-us/java-module/latest/java-argument-transformation.md
canonical_url: https://docs.mulesoft.com/java-module/latest/java-argument-transformation
source_site: docs.mulesoft.com
content_type: documentation
content_hash: f6910a6ee621f07ada02f128bba449fe79945ec0e41fdc3f3d95e41510b5f1fb
description: MuleSoft Documentation Site
release: "2.0"
latest: true
---
---
product: Java Module
version: 2.0
is-latest-version: true
---

# Argument Transformation

> For the full documentation index, see: https://docs.mulesoft.com/llms.txt

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:

```xml
<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

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:

    ```java
    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:

    ```java
    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:

    ```xml
    <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.

> [!IMPORTANT] 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:

```java
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:

```xml
<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:

```java
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:

```xml
<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:

```Dataweave
%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:

```xml
<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](https://docs.mulesoft.com/java-module/latest/java-module-examples)
